SKILL.md
Terraform Skill for Claude
Comprehensive Terraform and OpenTofu guidance covering testing, modules, CI/CD, and production patterns. Based on terraform-best-practices.com and enterprise experience.
Detailed Guide
Read [the detailed guide](references/detailed-guide.md) before executing this skill. It retains the complete procedure and reference material. Treat its safety, prerequisites, and validation requirements as mandatory. For focused work, load the relevant sections; for end-to-end work, read the guide completely.
When to Use This Skill
Activate this skill when:
- Creating new Terraform or OpenTofu configurations or modules
- Setting up testing infrastructure for IaC code
- Deciding between testing approaches (validate, plan, frameworks)
- Structuring multi-environment deployments
- Implementing CI/CD for infrastructure-as-code
- Reviewing or refactoring existing Terraform/OpenTofu projects
- Choosing between module patterns or state management approaches
Don't use this skill for:
- Basic Terraform/OpenTofu syntax questions (Claude knows this)
- Provider-specific API reference (link to docs instead)
- Cloud platform questions unrelated to Terraform/OpenTofu
Count vs For_Each: When to Use Each
Quick Decision Guide
| Scenario | Use | Why |
|---|---|---|
| Boolean condition (create or don't) | count = condition ? 1 : 0 |
Simple on/off toggle |
| Simple numeric replication | count = 3 |
Fixed number of identical resources |
| Items may be reordered/removed | for_each = toset(list) |
Stable resource addresses |
| Reference by key | for_each = map |
Named access to resources |
| Multiple named resources | for_each |
Better maintainability |
Common Patterns
Boolean conditions:
# ✅ GOOD - Boolean condition
resource "aws_nat_gateway" "this" {
count = var.create_nat_gateway ? 1 : 0
# ...
}
Stable addressing with for_each:
# ✅ GOOD - Removing "us-east-1b" only affects that subnet
resource "aws_subnet" "private" {
for_each = toset(var.availability_zones)
availability_zone = each.key
# ...
}
# ❌ BAD - Removing middle AZ recreates all subsequent subnets
resource "aws_subnet" "private" {
count = length(var.availability_zones)
availability_zone = var.availability_zones[count.index]
# ...
}
For migration guides and detailed examples, see: Code Patterns: Count vs For_Each
Security & Compliance
Essential Security Checks
# Static security scanning
trivy config .
checkov -d .
Common Issues to Avoid
❌ Don't:
- Store secrets in variables
- Use default VPC
- Skip encryption
- Open security groups to 0.0.0.0/0
✅ Do:
- Use AWS Secrets Manager / Parameter Store
- Create dedicated VPCs
- Enable encryption at rest
- Use least-privilege security groups
For detailed security guidance, see:
- Security & Compliance Guide - Trivy/Checkov integration, secrets management, state file security, compliance testing
Limitations
- Use this skill only when the task clearly matches the scope described above.
- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.
- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.