Anti-Patterns¶
Common mistakes when implementing prerequisite checks.
Recognize These Mistakes
Each anti-pattern here has caused production incidents. Learn to spot them before they cause problems.
1. Scattered Prerequisites¶
Checking prerequisites throughout the code instead of upfront.
// Bad: prerequisites scattered
func Deploy(config Config) error {
if config.Namespace == "" {
return errors.New("namespace required")
}
client, err := NewClient()
if err != nil {
return err
}
if config.Image == "" {
return errors.New("image required") // Too late!
}
// ...
}
// Good: consolidated prerequisites
func Deploy(config Config) error {
if err := config.Validate(); err != nil {
return err
}
// All prerequisites passed, proceed
client, err := NewClient()
// ...
}
2. Silent Prerequisites¶
Not reporting which prerequisite failed.
# Bad: which check failed?
check_prerequisites() {
command -v kubectl >/dev/null && \
command -v helm >/dev/null && \
kubectl auth can-i create deployments
}
# Good: report specific failure
check_prerequisites() {
command -v kubectl >/dev/null || { echo "kubectl not found"; return 1; }
command -v helm >/dev/null || { echo "helm not found"; return 1; }
kubectl auth can-i create deployments || { echo "No deploy permission"; return 1; }
}
3. Incomplete Prerequisites¶
Missing critical checks.
# Bad: doesn't check if image exists
- name: Deploy
run: kubectl set image deployment/app app=$IMAGE
# Good: verify image exists first
- name: Check image exists
run: |
docker manifest inspect $IMAGE || {
echo "Image $IMAGE not found in registry"
exit 1
}
- name: Deploy
run: kubectl set image deployment/app app=$IMAGE
4. Prerequisites That Change State¶
Prerequisites should be read-only.
// Bad: prerequisite creates resource
func checkNamespace(name string) error {
_, err := client.GetNamespace(name)
if err != nil {
// Creates namespace as side effect!
return client.CreateNamespace(name)
}
return nil
}
// Good: prerequisite only checks
func checkNamespace(name string) error {
_, err := client.GetNamespace(name)
if err != nil {
return fmt.Errorf("namespace %s does not exist", name)
}
return nil
}