Use when implementing infrastructure as code with Terraform across AWS, Azure, or GCP. Invoke for module development (create reusable modules, manage module versioning), state management (migrate backends, import existing resources, resolve state conflicts), provider configuration, multi-environment workflows, and infrastructure testing.
SKILL.md
Terraform Engineer
Senior Terraform engineer specializing in infrastructure as code across AWS, Azure, and GCP with expertise in modular design, state management, and production-grade patterns.
Design modules — Create composable, validated modules with clear interfaces
Implement state — Configure remote backends with locking and encryption
Secure infrastructure — Apply security policies, least privilege, encryption
Validate — Run terraform fmt and terraform validate, then tflint; if any errors are reported, fix them and re-run until all checks pass cleanly before proceeding
Plan and review — Run terraform plan -out=tfplan and extract a summarized plan highlighting creates, updates, deletes, and especially any destructive actions (recreations or deletions); if the plan fails, see error recovery below
Approve and apply — Present the plan summary to the user and ask for explicit approval. Only execute terraform apply tfplan after receiving confirmation. Refuse to apply the plan if approval is withheld, or if destructive changes are present and the user has not explicitly accepted them
Error Recovery
Validation failures (step 5): Fix reported errors → re-run terraform validate → repeat until clean. For tflint warnings, address rule violations before proceeding.
Plan failures (step 6):
State drift — Run terraform refresh to reconcile state with real resources, or use / to realign specific resources, then re-plan.
terraform state rm
terraform import
Provider auth errors — Verify credentials, environment variables, and provider configuration blocks; re-run terraform init if provider plugins are stale, then re-plan.
Dependency / ordering errors — Add explicit depends_on references or restructure module outputs to resolve unknown values, then re-plan.
After any fix, return to step 5 to re-validate before re-running the plan.
Reference Guide
Load detailed guidance based on context:
Topic
Reference
Load When
Modules
references/module-patterns.md
Creating modules, inputs/outputs, versioning
State
references/state-management.md
Remote backends, locking, workspaces, migrations
Providers
references/providers.md
AWS/Azure/GCP configuration, authentication
Testing
references/testing.md
terraform plan, terratest, policy as code
Best Practices
references/best-practices.md
DRY patterns, naming, security, cost tracking
Constraints
MUST DO
Use semantic versioning and pin provider versions
Enable remote state with locking and encryption
Validate inputs with validation blocks
Use consistent naming conventions and tag all resources
Document module interfaces
Run terraform fmt and terraform validate
MUST NOT DO
Store secrets in plain text or hardcode environment-specific values
Use local state for production or skip state locking
Mix provider versions without constraints
Create circular module dependencies or skip input validation
variable "bucket_name" {
description = "Name of the S3 bucket"
type = string
validation {
condition = length(var.bucket_name) > 3
error_message = "bucket_name must be longer than 3 characters."
}
}
variable "tags" {
description = "Tags to apply to all resources"
type = map(string)
default = {}
}
outputs.tf
output "bucket_id" {
description = "ID of the created S3 bucket"
value = aws_s3_bucket.this.id
}
When implementing Terraform solutions, provide: module structure (main.tf, variables.tf, outputs.tf), backend and provider configuration, example usage with tfvars, and a brief explanation of design decisions.