Infrastructure Change
Safe infrastructure change workflow for Terraform, Helm, and Kubernetes. Every mutation requires explicit user approval after reviewing the plan/diff. Applies Agent(devops-engineer) for all steps.
⚠️ SAFETY: No apply, upgrade, delete, or scale command runs without explicit user APPROVE.
0. Gather Context
Read CLAUDE.md (or AGENTS.md) at the project root to identify:
- Infrastructure tools in use (Terraform, Helm, kubectl, Pulumi, OpenTofu)
- Cloud platform (GCP, Azure, AWS) — apply
cloud-platformsskill for platform-specific commands - Environment structure (dev, staging, production)
- State backend and workspace conventions
0a. Detect orchestration / GitOps controllers — route first
Before running terraform apply or helm upgrade directly, check whether the repo's infra changes flow through a controller. If so, the change is a git PR, not an imperative command.
GitOps platform detection (Argo / Flux / Atlantis / HCP / Spacelift / env0) — see @gitops-detection.
0b. Detect Terraform fork
OpenTofu fork detection + command substitution rules — see @terraform-procedures.
0c. Policy-as-code gate (when configured)
If .conftest/ (Conftest), .opa/ (raw OPA Rego), .tflint.hcl (TFLint), or tfsec.yml (tfsec) / .checkov.yml (Checkov) configs are present, run them as a pre-plan gate. A plan that violates policy never advances to apply.
1. Define the Change
Ask the user (or extract from parent workflow context):
- What needs to change? (resource scaling, new service, config update, network change, secret rotation)
- Which tool? Terraform, Helm, kubectl, or combination
- Environment: dev / staging / production
- Risk level: Low (config), Medium (scaling, new resource), High (destroy, DB, auth, prod)
If Risk = HIGH or Environment = production:
⚠️ HIGH-RISK INFRASTRUCTURE CHANGE
Destructive actions require explicit "APPROVE" before execution.
Affected: [list resources/services]
2. Apply Roles
Apply Agent(devops-engineer). For production changes, also apply Agent(sre-engineer) for SLO impact assessment. For cloud infrastructure design (landing zones, networking topology, IAM), consult Agent(cloud-architect). For CI/CD pipeline architecture changes, consult Agent(devops-architect).
3. Review Current State
Before making changes, capture the current state:
3a. Terraform State (if applicable)
Terraform state operations + plan/apply lifecycle + OpenTofu compatibility — see @terraform-procedures.
3b. Helm State (if applicable)
Helm diff + atomic upgrade + rollback procedures — see @helm-procedures.
3c. Kubernetes State (if applicable)
// turbo
kubectl get deployments,services,ingress -n <namespace>
kubectl get pods -n <namespace> -o wide
Record: Current resource counts, versions, replicas, config values as baseline.
4. Implement Changes
Make the infrastructure code changes following Agent(devops-engineer) standards:
For Terraform:
- Modify
.tffiles as needed - Run format and validate:
// turbo
terraform fmt -recursive
terraform validate
For Helm:
- Modify
values.yamlor chart templates - Lint the chart:
// turbo
helm lint <chart-path>
For raw Kubernetes manifests:
- Modify YAML files
- Validate with dry-run:
kubectl apply --dry-run=client -f <manifest>
5. Plan Review — MANDATORY BEFORE APPLY
Generate the plan/diff for the tool in use and present a summary table to the user.
- Terraform: see
@terraform-proceduresforterraform plan -out=tfplanand the plan-summary format (Add / Change / Destroy table, destroy/replace highlight, data-loss flag). - Helm: see
@helm-proceduresforhelm diff upgradeand the diff-summary format (per-object Action / Key Changes table, critical-changes highlight, downtime flag). - Kubectl:
kubectl diff -f <manifest>
WARNING — STOP. Present plan/diff summary and request APPROVE before proceeding to Step 6.
6. Apply — REQUIRES EXPLICIT APPROVE
Only after the user explicitly approves:
- Terraform:
terraform apply tfplan(see@terraform-procedures) - Helm:
helm upgrade ... --atomic --timeout 5m --wait(see@helm-procedures) - Kubectl:
kubectl apply -f <manifest>
Rules:
- Never auto-run apply/upgrade commands
- User must explicitly type "APPROVE" or equivalent
- If the plan changed since review — re-run Step 5
7. Verify
After applying, verify the changes took effect:
// turbo
kubectl get pods -n <namespace> -o wide
kubectl get events -n <namespace> --sort-by='.lastTimestamp' --field-selector type!=Normal
Check:
- All pods healthy (Running, no CrashLoopBackOff)
- Expected replica counts match
- No warning/error events
- Services responding (health check endpoints)
- Logs clean (no new errors)
If production — monitor SLIs for 5–10 minutes after apply.
8. Rollback Plan
Document the rollback before considering the change complete:
- Terraform: revert
.tffiles and re-apply — see@terraform-procedures - Helm:
helm rollback <release> <previous-revision> -n <namespace>— see@helm-procedures - Kubectl:
kubectl rollout undo deployment/<name> -n <namespace>
9. Summary
## Infrastructure Change Summary
- **Change**: [what was changed]
- **Tool**: [Terraform / Helm / kubectl]
- **Environment**: [dev / staging / production]
- **Risk**: [low / medium / high]
- **Plan reviewed**: [yes — summary of add/change/destroy]
- **Applied**: [yes/no — with APPROVE]
- **Verification**: [pass/fail]
- **Rollback plan**: [documented above]
- **Next steps**: [monitoring, follow-up changes]
RALF Loop (optional)
For multi-step infra changes that may need iterative reconciliation (e.g., Terraform plans that depend on prior apply outputs), this skill MAY run inside /ralph per ralph-budget.md rule. Default per-workflow caps: 4 iter / 200K tokens / 45 min. Mandatory --kill-on oracle-pass (oracle: terraform plan -detailed-exitcode returns 0 = no diff).
Integration
- Roles:
Agent(devops-engineer)(primary),Agent(sre-engineer)(review),Agent(cloud-architect)(cloud design review),Agent(devops-architect)(CI/CD pipeline architecture) - Knowledge skills:
@terraform-procedures,@helm-procedures,@gitops-detection,@cloud-platforms - Preceded by:
/plan(infra work stream),/architecture(cloud architecture design) - Followed by:
/deploy-staging,/deploy-production - Rules:
ralph-budget(caps for iterative reconciliation per "RALF Loop" section)