Complete Terraform & IaC production methodology — project structure, module design, state management, multi-environment deployment, security hardening, testing, CI/CD pipelines, cost optimization, and drift management. Use when designing infrastructure, writing Terraform, reviewing IaC, or managing cloud environments.
Scanned 9/9/2026
Install to Claude Code
npx -y skills add Lord1Egypt/awesome-skill-forge --skill afrexai-terraform-production --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Afrexai Terraform Production?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/lord1egypt-afrexai-terraform-production)More formats (shields.io, HTML) on the badges page.
---
name: Terraform & Infrastructure as Code Production Engineering
description: Complete Terraform & IaC production methodology — project structure, module design, state management, multi-environment deployment, security hardening, testing, CI/CD pipelines, cost optimization, and drift management. Use when designing infrastructure, writing Terraform, reviewing IaC, or managing cloud environments.
---
# Terraform & Infrastructure as Code Production Engineering
Complete 14-phase system for production-grade infrastructure as code. Zero dependencies — works with any cloud provider and any Terraform version.
---
## Phase 1: Quick Health Check
Run this 8-signal triage on any Terraform project:
| # | Signal | ✅ Healthy | 🔴 Fix Now |
|---|--------|-----------|-----------|
| 1 | Remote state backend | S3/GCS/Azure Blob with locking | Local state or no locking |
| 2 | State encryption | Encrypted at rest + restricted access | Plain state, wide access |
| 3 | Module pinning | All modules version-pinned | Unpinned or `ref=main` |
| 4 | Provider pinning | `required_providers` with `~>` constraints | No version constraints |
| 5 | Separate environments | Isolated state per env (dev/staging/prod) | Shared state or workspaces-as-envs |
| 6 | Plan before apply | CI runs `plan`, human approves, CI runs `apply` | Local `apply` without review |
| 7 | Secrets management | No secrets in `.tf` files; vault/SSM/secrets manager | Hardcoded secrets anywhere |
| 8 | Drift detection | Scheduled drift checks (weekly minimum) | No drift monitoring |
**Score: /16** (2 per signal). Below 10 = stop and fix foundations first.
---
## Phase 2: Project Structure
### Recommended Layout
```
infrastructure/
├── modules/ # Reusable modules (internal registry)
│ ├── networking/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ ├── outputs.tf
│ │ ├── versions.tf
│ │ └── README.md
│ ├── compute/
│ ├── database/
│ └── monitoring/
├── environments/ # Environment-specific configs
│ ├── dev/
│ │ ├── main.tf # Module calls with dev params
│ │ ├── backend.tf # Dev state backend
│ │ ├── terraform.tfvars # Dev variable values
│ │ └── versions.tf
│ ├── staging/
│ └── prod/
├── global/ # Shared resources (IAM, DNS, etc.)
│ ├── iam/
│ ├── dns/
│ └── networking/
├── scripts/ # Helper scripts (import, migration)
├── policies/ # OPA/Sentinel policies
└── .github/workflows/ # CI/CD pipelines
```
### 7 Architecture Rules
1. **One module = one responsibility** — networking module doesn't create compute
2. **Environments are thin** — they call modules with different parameters, not duplicate code
3. **State isolation** — separate state file per environment AND per logical group (networking vs compute)
4. **No hardcoded values in modules** — everything is a variable with sensible defaults
5. **Outputs are your API** — if another module/team needs a value, it's an output
6. **README per module** — inputs, outputs, usage example, dependencies
7. **`.terraform.lock.hcl` committed** — reproducible provider versions
### File Naming Convention
| File | Purpose |
|------|---------|
| `main.tf` | Primary resource definitions |
| `variables.tf` | All input variables |
| `outputs.tf` | All outputs |
| `versions.tf` | `terraform` and `required_providers` blocks |
| `backend.tf` | State backend configuration |
| `locals.tf` | Local values and computed expressions |
| `data.tf` | Data sources |
| `providers.tf` | Provider configuration (if complex) |
---
## Phase 3: State Management
### Remote Backend Setup (AWS Example)
```hcl
# backend.tf
terraform {
backend "s3" {
bucket = "company-terraform-state"
key = "environments/prod/networking/terraform.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "terraform-state-lock"
kms_key_id = "alias/terraform-state"
}
}
```
### State Key Strategy
```
{org}/{environment}/{component}/terraform.tfstate
```
Examples:
- `acme/prod/networking/terraform.tfstate`
- `acme/prod/compute/terraform.tfstate`
- `acme/global/iam/terraform.tfstate`
### State Operations Safety Rules
| Operation | Risk | Safe Approach |
|-----------|------|---------------|
| `terraform state mv` | Medium | Plan after to verify no changes |
| `terraform state rm` | High | Only to adopt resource elsewhere |
| `terraform import` | Medium | Write config first, import, plan to verify |
| `terraform state pull` | Low | For inspection only |
| `terraform state push` | CRITICAL | Almost never — breaks consistency |
| `moved` block | Low | Preferred over `state mv` — in config, reviewable |
### 6 State Rules
1. **Never edit state JSON manually** — use CLI commands only
2. **Never share state across environments** — separate backends per env
3. **Always enable locking** — DynamoDB (AWS), Cloud Storage (GCP), Blob lease (Azure)
4. **Enable versioning on state bucket** — rollback capability
5. **Restrict state access** — only CI/CD service accounts, not developers
6. **State contains secrets** — treat state files as sensitive; encrypt at rest + in transit
---
## Phase 4: Module Design
### Module Interface Template
```hcl
# variables.tf — Module inputs
variable "name" {
description = "Name prefix for all resources"
type = string
validation {
condition = can(regex("^[a-z][a-z0-9-]{2,28}[a-z0-9]$", var.name))
error_message = "Name must be 4-30 chars, lowercase alphanumeric + hyphens."
}
}
variable "environment" {
description = "Deployment environment"
type = string
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "Environment must be dev, staging, or prod."
}
}
variable "tags" {
description = "Common tags applied to all resources"
type = map(string)
default = {}
}
```
```hcl
# outputs.tf — Module contract
output "vpc_id" {
description = "ID of the created VPC"
value = aws_vpc.main.id
}
output "private_subnet_ids" {
description = "List of private subnet IDs"
value = aws_subnet.private[*].id
}
```
### Module Composition Pattern
```hcl
# environments/prod/main.tf
module "networking" {
source = "../../modules/networking"
name = "prod"
environment = "prod"
vpc_cidr = "10.0.0.0/16"
azs = ["us-east-1a", "us-east-1b", "us-east-1c"]
tags = local.common_tags
}
module "compute" {
source = "../../modules/compute"
name = "prod"
environment = "prod"
vpc_id = module.networking.vpc_id
private_subnet_ids = module.networking.private_subnet_ids
instance_type = "t3.large"
min_size = 3
max_size = 10
tags = local.common_tags
}
```
### 8 Module Design Rules
1. **Expose what's needed, hide what's not** — minimal variable surface
2. **Use `for_each` over `count`** — stable resource addressing
3. **Validate inputs** — `validation` blocks catch errors at plan time
4. **Default to secure** — encryption on, public access off, least privilege
5. **Version everything** — semver for modules, `~>` for providers
6. **No provider config in modules** — providers configured in root only
7. **Use `moved` blocks for refactoring** — not `state mv`
8. **Test with examples** — `examples/` directory with working configurations
---
## Phase 5: Multi-Environment Strategy
### Environment Comparison
| Aspect | Dev | Staging | Prod |
|--------|-----|---------|------|
| Instance sizes | Small/micro | Match prod types | Right-sized |
| Replica count | 1 | 2 | 3+ (HA) |
| Multi-AZ | Optional | Yes | Yes |
| Backup retention | 1 day | 7 days | 30+ days |
| Monitoring | Basic | Full | Full + PagerDuty |
| Auto-scaling | Off | On | On |
| WAF/Shield | Off | On | On + Advanced |
| State access | Dev team | DevOps | DevOps only |
### Variable Hierarchy Pattern
```hcl
# modules/compute/variables.tf
variable "instance_type" {
type = string
default = "t3.micro" # Safe default
}
variable "min_size" {
type = number
default = 1
}
variable "enable_deletion_protection" {
type = bool
default = true # Safe default — must explicitly disable for dev
}
```
```hcl
# environments/dev/terraform.tfvars
instance_type = "t3.micro"
min_size = 1
enable_deletion_protection = false
# environments/prod/terraform.tfvars
instance_type = "t3.large"
min_size = 3
enable_deletion_protection = true
```
### Promotion Strategy
```
dev → staging → prod
│ │ │
│ │ └─ Manual approval required
│ └─ Auto-apply after plan review
└─ Auto-apply on merge to dev branch
```
---
## Phase 6: Security Hardening
### 15-Point Security Checklist
**P0 — Mandatory:**
- [ ] No secrets in `.tf` files, `.tfvars`, or state (use vault/SSM/secrets manager)
- [ ] State backend encrypted at rest with customer-managed keys
- [ ] State access restricted to CI/CD service accounts only
- [ ] `prevent_destroy` on critical resources (databases, S3 with data)
- [ ] Provider credentials via environment variables or OIDC, never in config
- [ ] `.gitignore` includes `*.tfvars` with secrets, `.terraform/`, `*.tfstate*`
**P1 — Required:**
- [ ] OIDC for CI/CD auth (no long-lived access keys)
- [ ] Least-privilege IAM for Terraform service account
- [ ] Security group rules explicit (no `0.0.0.0/0` ingress except ALB on 443)
- [ ] Encryption enabled on all data stores (RDS, S3, EBS, ElastiCache)
- [ ] VPC flow logs enabled
- [ ] CloudTrail/audit logging for all API calls
**P2 — Recommended:**
- [ ] OPA/Sentinel policies enforced in CI
- [ ] `tfsec` or `checkov` in CI pipeline
- [ ] Separate AWS accounts per environment (AWS Organizations)
### Secrets Management Decision Tree
```
Need a secret in Terraform?
├── Runtime secret (app needs at runtime)
│ └── Use AWS Secrets Manager / HashiCorp Vault
│ └── Reference via data source, pass ARN to app
├── Terraform-time secret (provider needs it)
│ └── Environment variable (TF_VAR_xxx) or OIDC
└── Generated secret (Terraform creates it)
└── random_password resource → store in Secrets Manager
└── Mark output as sensitive = true
```
### OIDC Authentication (GitHub Actions → AWS)
```hcl
# No access keys needed
data "aws_iam_openid_connect_provider" "github" {
url = "https://token.actions.githubusercontent.com"
}
resource "aws_iam_role" "terraform_ci" {
name = "terraform-ci"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Federated = data.aws_iam_openid_connect_provider.github.arn }
Action = "sts:AssumeRoleWithWebIdentity"
Condition = {
StringEquals = {
"token.actions.githubusercontent.com:aud" = "sts.amazonaws.com"
}
StringLike = {
"token.actions.githubusercontent.com:sub" = "repo:org/infra:*"
}
}
}]
})
}
```
---
## Phase 7: Testing Strategy
### 4-Level Test Pyramid
| Level | Tool | What It Tests | When |
|-------|------|---------------|------|
| **Static** | `terraform validate`, `tflint`, `tfsec`, `checkov` | Syntax, best practices, security | Every commit |
| **Plan** | `terraform plan` + policy checks | Expected changes, no surprises | Every PR |
| **Contract** | `terratest` / `tftest` (TF 1.6+) | Module inputs/outputs, behavior | PR + nightly |
| **Integration** | `terratest` with real cloud | Actual infrastructure works | Nightly/weekly |
### Native Terraform Test (TF 1.6+)
```hcl
# tests/networking.tftest.hcl
run "creates_vpc_with_correct_cidr" {
command = plan
variables {
name = "test"
environment = "dev"
vpc_cidr = "10.0.0.0/16"
azs = ["us-east-1a"]
}
assert {
condition = aws_vpc.main.cidr_block == "10.0.0.0/16"
error_message = "VPC CIDR doesn't match input"
}
assert {
condition = aws_vpc.main.enable_dns_hostnames == true
error_message = "DNS hostnames should be enabled"
}
}
run "rejects_invalid_environment" {
command = plan
expect_failures = [var.environment]
variables {
name = "test"
environment = "invalid"
vpc_cidr = "10.0.0.0/16"
azs = ["us-east-1a"]
}
}
```
### Static Analysis CI Step
```yaml
- name: Terraform Lint & Security
run: |
terraform fmt -check -recursive
terraform validate
tflint --recursive
tfsec .
checkov -d . --framework terraform
```
### 7 Testing Rules
1. **Static analysis on every commit** — catches 80% of issues for free
2. **Plan review on every PR** — humans approve infrastructure changes
3. **Native tests for modules** — `terraform test` is built-in, use it
4. **Integration tests destroy after** — `defer cleanup` to avoid orphaned resources
5. **Test in isolated account** — never test against production state
6. **Pin test dependencies** — terratest Go modules, provider versions
7. **Cost estimation in CI** — `infracost` to catch expensive surprises
---
## Phase 8: CI/CD Pipeline
### GitHub Actions Pipeline
```yaml
name: Terraform
on:
pull_request:
paths: ['infrastructure/**']
push:
branches: [main]
paths: ['infrastructure/**']
permissions:
id-token: write # OIDC
contents: read
pull-requests: write # PR comments
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: "1.7.x"
- run: terraform fmt -check -recursive
- run: terraform init -backend=false
- run: terraform validate
- run: tflint --recursive
- run: tfsec . --soft-fail
plan:
needs: validate
runs-on: ubuntu-latest
strategy:
matrix:
environment: [dev, staging, prod]
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::role/terraform-ci
aws-region: us-east-1
- uses: hashicorp/setup-terraform@v3
- working-directory: infrastructure/environments/${{ matrix.environment }}
run: |
terraform init
terraform plan -out=tfplan -no-color
- uses: actions/upload-artifact@v4
with:
name: tfplan-${{ matrix.environment }}
path: infrastructure/environments/${{ matrix.environment }}/tfplan
apply:
if: github.ref == 'refs/heads/main'
needs: plan
runs-on: ubuntu-latest
environment: production # Requires approval
strategy:
matrix:
environment: [dev, staging, prod]
max-parallel: 1 # Sequential: dev → staging → prod
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::role/terraform-ci
aws-region: us-east-1
- uses: hashicorp/setup-terraform@v3
- uses: actions/download-artifact@v4
with:
name: tfplan-${{ matrix.environment }}
path: infrastructure/environments/${{ matrix.environment }}
- working-directory: infrastructure/environments/${{ matrix.environment }}
run: terraform apply tfplan
```
### CI/CD Rules
1. **Never `apply` from local machines** — CI/CD only
2. **Plan artifact = apply input** — same plan that was reviewed gets applied
3. **Sequential environment promotion** — dev → staging → prod, not parallel
4. **Production requires approval** — GitHub Environment protection rules
5. **Drift detection on schedule** — weekly `plan` to detect manual changes
6. **Cost estimation on PR** — Infracost or similar
---
## Phase 9: Resource Patterns
### Tagging Strategy
```hcl
locals {
common_tags = {
Project = var.project_name
Environment = var.environment
ManagedBy = "terraform"
Team = var.team
CostCenter = var.cost_center
Repository = "github.com/org/infrastructure"
}
}
# Apply to all resources
resource "aws_instance" "app" {
# ...
tags = merge(local.common_tags, {
Name = "${var.name}-app"
Role = "application"
})
}
```
### Naming Convention
```
{project}-{environment}-{component}-{qualifier}
```
Examples: `acme-prod-vpc-main`, `acme-staging-rds-primary`, `acme-prod-alb-api`
### Common Patterns
**Conditional Resource Creation:**
```hcl
resource "aws_cloudwatch_metric_alarm" "cpu" {
count = var.environment == "prod" ? 1 : 0
# Only create alarms in prod
}
```
**Dynamic Blocks:**
```hcl
resource "aws_security_group" "app" {
name = "${var.name}-app"
vpc_id = var.vpc_id
dynamic "ingress" {
for_each = var.ingress_rules
content {
from_port = ingress.value.port
to_port = ingress.value.port
protocol = "tcp"
cidr_blocks = ingress.value.cidrs
description = ingress.value.description
}
}
}
```
**Data Source for Cross-Stack References:**
```hcl
# Instead of hardcoding VPC ID
data "terraform_remote_state" "networking" {
backend = "s3"
config = {
bucket = "company-terraform-state"
key = "environments/prod/networking/terraform.tfstate"
region = "us-east-1"
}
}
# Use: data.terraform_remote_state.networking.outputs.vpc_id
```
---
## Phase 10: Drift Management
### Drift Detection Schedule
```yaml
# .github/workflows/drift-detection.yml
name: Drift Detection
on:
schedule:
- cron: '0 8 * * 1' # Weekly Monday 8 AM UTC
jobs:
detect:
runs-on: ubuntu-latest
strategy:
matrix:
environment: [dev, staging, prod]
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::role/terraform-ci
aws-region: us-east-1
- uses: hashicorp/setup-terraform@v3
- working-directory: infrastructure/environments/${{ matrix.environment }}
run: |
terraform init
terraform plan -detailed-exitcode -no-color 2>&1 | tee plan.txt
EXIT_CODE=$?
if [ $EXIT_CODE -eq 2 ]; then
echo "::warning::Drift detected in ${{ matrix.environment }}"
# Send Slack alert
fi
```
### Drift Response Playbook
| Drift Type | Response |
|-----------|----------|
| Manual console change (cosmetic) | Import or update config to match |
| Manual console change (critical) | Investigate who/why, then align |
| Auto-scaling / ASG changes | Expected — use `ignore_changes` for dynamic attributes |
| AWS service updates | Update provider version, review changelog |
| Security group modified manually | 🚨 Security incident — investigate immediately |
### `ignore_changes` Decision Guide
Use `ignore_changes` ONLY for:
- Attributes modified by the application at runtime (e.g., ASG desired count)
- Tags managed by external systems (e.g., AWS Backup tags)
- Attributes that drift due to API behavior (e.g., default security group rules)
**Never `ignore_changes` for:**
- Security configurations
- Network rules
- IAM policies
- Encryption settings
---
## Phase 11: Cost Optimization
### Infracost in CI
```yaml
- name: Infracost
run: |
infracost breakdown --path infrastructure/environments/prod/ \
--format json --out-file infracost.json
infracost output --path infracost.json --format github-comment \
--out-file comment.md
# Post as PR comment
```
### Cost Optimization Checklist
| Strategy | Savings | Implementation |
|----------|---------|----------------|
| Reserved Instances / Savings Plans | 30-60% | Annual commitment for stable workloads |
| Right-sizing | 20-40% | Monitor CPU/memory, downsize over-provisioned |
| Spot/Preemptible for non-critical | 60-90% | Batch jobs, dev environments |
| S3 lifecycle policies | 20-50% storage | Transition to IA → Glacier → delete |
| NAT Gateway alternatives | $30-100/mo per GW | NAT instances for dev, VPC endpoints |
| Dev environment scheduling | 60-70% | Destroy nights/weekends, recreate on demand |
| Unused resource cleanup | Variable | Tag with TTL, auto-delete untagged after 7 days |
### Tagging for Cost Allocation
Required cost tags (enforce via policy):
- `CostCenter` — maps to business unit
- `Environment` — dev/staging/prod
- `Project` — which project owns this
- `Team` — responsible team
- `ManagedBy` — terraform/manual/other
---
## Phase 12: Advanced Patterns
### Terragrunt for DRY Environments
When you have 5+ environments with identical module structures, Terragrunt eliminates repetition:
```hcl
# terragrunt.hcl (root)
remote_state {
backend = "s3"
generate = { path = "backend.tf", if_exists = "overwrite_terragrunt" }
config = {
bucket = "company-terraform-state"
key = "${path_relative_to_include()}/terraform.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "terraform-state-lock"
}
}
```
### Import Block (TF 1.5+)
```hcl
# Declarative import — reviewable in PR
import {
to = aws_s3_bucket.existing
id = "my-existing-bucket"
}
resource "aws_s3_bucket" "existing" {
bucket = "my-existing-bucket"
# Write config to match existing resource
}
```
### Provider Aliases for Multi-Region
```hcl
provider "aws" {
region = "us-east-1"
}
provider "aws" {
alias = "eu"
region = "eu-west-1"
}
module "eu_networking" {
source = "../../modules/networking"
providers = { aws = aws.eu }
# ...
}
```
### `moved` Block for Refactoring
```hcl
# Rename without destroy+create
moved {
from = aws_instance.app
to = aws_instance.application
}
# Move into module
moved {
from = aws_instance.app
to = module.compute.aws_instance.app
}
```
---
## Phase 13: Disaster Recovery & Migration
### State Recovery
```bash
# Enable versioning on state bucket (BEFORE you need it)
aws s3api put-bucket-versioning \
--bucket company-terraform-state \
--versioning-configuration Status=Enabled
# List state versions
aws s3api list-object-versions \
--bucket company-terraform-state \
--prefix environments/prod/networking/terraform.tfstate
# Restore previous version
aws s3api get-object \
--bucket company-terraform-state \
--key environments/prod/networking/terraform.tfstate \
--version-id "versionId123" \
restored-state.tfstate
```
### Migration Checklist (Moving Between Backends)
1. [ ] `terraform state pull > backup.tfstate` — backup current state
2. [ ] Update `backend.tf` with new backend config
3. [ ] `terraform init -migrate-state` — Terraform copies state
4. [ ] `terraform plan` — verify no changes (state matches)
5. [ ] Test apply on non-critical resource
6. [ ] Delete old state after verification period (7 days)
### Breaking Changes Protocol
When upgrading major Terraform or provider versions:
1. Read changelog for breaking changes
2. Test upgrade in dev first
3. Update `.terraform.lock.hcl`
4. Run `terraform plan` in all environments
5. Apply dev → staging → prod with 24h gaps
---
## Phase 14: Quality Scoring
### 100-Point Terraform Quality Rubric
| Dimension | Weight | Score Range |
|-----------|--------|-------------|
| State management | 20% | 0-20 |
| Security posture | 20% | 0-20 |
| Module design | 15% | 0-15 |
| Testing coverage | 15% | 0-15 |
| CI/CD automation | 10% | 0-10 |
| Documentation | 10% | 0-10 |
| Cost governance | 5% | 0-5 |
| Drift management | 5% | 0-5 |
**Scoring Guide:**
- **90-100**: Production-grade, fully automated, battle-tested
- **70-89**: Solid foundation, some gaps to address
- **50-69**: Functional but risky — prioritize security and state management
- **Below 50**: Stop deploying and fix fundamentals
### 10 Terraform Commandments
1. **Remote state with locking or don't start**
2. **Never hardcode secrets — not in code, not in state if avoidable**
3. **Plan is sacred — review every plan, apply only reviewed plans**
4. **Modules are contracts — version them, test them, document them**
5. **Environments are isolated — separate state, separate accounts ideally**
6. **`for_each` over `count` — stable addressing saves you**
7. **CI/CD applies, humans don't — no local `terraform apply` in prod**
8. **Tag everything — cost allocation, ownership, lifecycle**
9. **Drift is a bug — detect it weekly, fix it immediately**
10. **Upgrade deliberately — test in dev, read changelogs, lock versions**
### 10 Common Mistakes
| Mistake | Impact | Fix |
|---------|--------|-----|
| Local state for team projects | State conflicts, data loss | Remote backend day 1 |
| Secrets in `.tfvars` committed to git | Credential exposure | Use vault/SSM + env vars |
| `count` for optional resources | Index shift on removal | `for_each` with conditional map |
| Monolithic state file | Slow plans, blast radius | Split by component (networking/compute/data) |
| No `prevent_destroy` on data stores | Accidental database deletion | Lifecycle rule on stateful resources |
| Unpinned module versions | Breaking changes on init | Pin with `?ref=v1.2.3` or `version = "~> 1.2"` |
| `terraform apply -auto-approve` in prod | Unreviewed changes | Plan artifact → human review → apply |
| Using workspaces as environments | Shared state, shared blast radius | Separate directories + backends per env |
| No cost estimation in CI | $10K surprise bills | Infracost or similar on every PR |
| Manual changes "just this once" | Permanent drift | Always go through code, even for emergencies |
---
## Natural Language Commands
- "Review this Terraform code" → Run Phase 1 health check + static analysis recommendations
- "Design infrastructure for [service]" → Phase 2 structure + Phase 4 module design
- "Set up remote state" → Phase 3 backend configuration
- "Create a module for [resource]" → Phase 4 module template with variables/outputs
- "Compare environments" → Phase 5 environment matrix
- "Security audit my Terraform" → Phase 6 security checklist
- "Add tests to this module" → Phase 7 native test examples
- "Set up CI/CD for Terraform" → Phase 8 GitHub Actions pipeline
- "Check for drift" → Phase 10 drift detection setup
- "Estimate infrastructure costs" → Phase 11 Infracost integration
- "Migrate state to new backend" → Phase 13 migration checklist
- "Score this Terraform project" → Phase 14 quality rubric
---
## ⚡ Level Up
This skill covers Terraform methodology and best practices. For industry-specific infrastructure patterns:
- **SaaS Infrastructure** → [AfrexAI SaaS Context Pack ($47)](https://afrexai-cto.github.io/context-packs/)
- **Fintech Compliance Infrastructure** → [AfrexAI Fintech Context Pack ($47)](https://afrexai-cto.github.io/context-packs/)
- **Healthcare HIPAA Infrastructure** → [AfrexAI Healthcare Context Pack ($47)](https://afrexai-cto.github.io/context-packs/)
## 🔗 More Free Skills by AfrexAI
- `clawhub install afrexai-devops-engine` — Complete DevOps & Platform Engineering
- `clawhub install afrexai-cybersecurity-engine` — Security Hardening & Compliance
- `clawhub install afrexai-system-architect` — System Architecture Decision Frameworks
- `clawhub install afrexai-api-architect` — API Design & Lifecycle Management
- `clawhub install afrexai-cicd-engineering` — CI/CD Pipeline Engineering
Browse all AfrexAI skills: [clawhub.com](https://clawhub.com) → Search "afrexai"
Storefront: [afrexai-cto.github.io/context-packs](https://afrexai-cto.github.io/context-packs/)
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!