$npx -y skills add terramate-io/agent-skills --skill terraform-best-practicesTerraform and Infrastructure as Code optimization guidelines from Terramate. This skill should be used when writing, reviewing, or refactoring Terraform/OpenTofu code to ensure optimal patterns for security, maintainability, and reliability. Triggers on tasks involving Terraform
| 1 | # Terraform Best Practices |
| 2 | |
| 3 | Comprehensive optimization guide for Terraform and Infrastructure as Code, maintained by Terramate. Contains 37 rules across 10 categories, prioritized by impact to guide automated refactoring and code generation. |
| 4 | |
| 5 | ## When to Apply |
| 6 | |
| 7 | Reference these guidelines when: |
| 8 | - Writing new Terraform modules or configurations |
| 9 | - Implementing infrastructure patterns (AWS, GCP, Azure, etc.) |
| 10 | - Reviewing code for security and reliability issues |
| 11 | - Refactoring existing Terraform/OpenTofu code |
| 12 | - Optimizing state management and performance |
| 13 | - Setting up team workflows and governance |
| 14 | |
| 15 | ## Rule Categories by Priority |
| 16 | |
| 17 | | Priority | Category | Impact | Prefix | |
| 18 | |----------|----------|--------|--------| |
| 19 | | 1 | Organization & Workflow | CRITICAL | `org-` | |
| 20 | | 2 | State Management | CRITICAL | `state-` | |
| 21 | | 3 | Security Best Practices | CRITICAL | `security-` | |
| 22 | | 4 | Module Design | HIGH | `module-` | |
| 23 | | 5 | Resource Organization | MEDIUM-HIGH | `resource-` | |
| 24 | | 6 | Variable & Output Patterns | MEDIUM | `variable-`, `output-` | |
| 25 | | 7 | Language Best Practices | MEDIUM | `language-` | |
| 26 | | 8 | Provider Configuration | MEDIUM | `provider-` | |
| 27 | | 9 | Performance Optimization | LOW-MEDIUM | `perf-` | |
| 28 | | 10 | Testing & Validation | LOW | `test-` | |
| 29 | |
| 30 | ## Quick Reference |
| 31 | |
| 32 | ### 1. Organization & Workflow (CRITICAL) - 5 rules |
| 33 | |
| 34 | - `org-version-control` - All Terraform code in version control |
| 35 | - `org-workspaces` - One workspace per environment per configuration |
| 36 | - `org-access-control` - Control who can change what infrastructure |
| 37 | - `org-change-workflow` - Formal process for infrastructure changes |
| 38 | - `org-audit-logging` - Track all infrastructure changes |
| 39 | |
| 40 | ### 2. State Management (CRITICAL) - 3 rules |
| 41 | |
| 42 | - `state-remote-backend` - Always use remote state backends |
| 43 | - `state-locking` - Enable state locking to prevent corruption |
| 44 | - `state-import` - Import existing infrastructure into Terraform |
| 45 | |
| 46 | ### 3. Security Best Practices (CRITICAL) - 3 rules |
| 47 | |
| 48 | - `security-no-hardcoded-secrets` - Never hardcode secrets in code |
| 49 | - `security-credentials` - Use proper credential management (OIDC, Vault, IAM roles) |
| 50 | - `security-iam-least-privilege` - Follow least privilege principle |
| 51 | |
| 52 | ### 4. Module Design (HIGH) - 5 rules |
| 53 | |
| 54 | - `module-single-responsibility` - One module per logical component |
| 55 | - `module-naming` - Use consistent naming conventions (terraform-<PROVIDER>-<NAME>) |
| 56 | - `module-versioning` - Version all module references |
| 57 | - `module-composition` - Compose modules like building blocks |
| 58 | - `module-registry` - Use existing community/shared modules |
| 59 | |
| 60 | ### 5. Resource Organization (MEDIUM-HIGH) - 5 rules |
| 61 | |
| 62 | - `resource-naming` - Use consistent naming conventions |
| 63 | - `resource-tagging` - Tag all resources for cost tracking |
| 64 | - `resource-lifecycle` - Use lifecycle blocks (prevent_destroy, ignore_changes) |
| 65 | - `resource-count-vs-foreach` - Prefer for_each over count |
| 66 | - `resource-immutable` - Prefer immutable infrastructure patterns |
| 67 | |
| 68 | ### 6. Variable & Output Patterns (MEDIUM) - 6 rules |
| 69 | |
| 70 | - `variable-types` - Use specific types, positive naming, nullable |
| 71 | - `variable-validation` - Add validation rules for early error detection |
| 72 | - `variable-sensitive` - Mark secrets as sensitive, no defaults |
| 73 | - `variable-descriptions` - Document all variables with descriptions |
| 74 | - `output-descriptions` - Document all outputs with descriptions |
| 75 | - `output-no-secrets` - Never output secrets directly |
| 76 | |
| 77 | ### 7. Language Best Practices (MEDIUM) - 5 rules |
| 78 | |
| 79 | - `language-no-heredoc-json` - Use jsonencode/yamlencode, not HEREDOC |
| 80 | - `language-locals` - Use locals to name complex expressions |
| 81 | - `language-linting` - Run terraform fmt and tflint |
| 82 | - `language-data-sources` - Use data sources instead of hardcoding |
| 83 | - `language-dynamic-blocks` - Use dynamic blocks for DRY code |
| 84 | |
| 85 | ### 8. Provider Configuration (MEDIUM) - 1 rule |
| 86 | |
| 87 | - `provider-version-constraints` - Pin provider versions |
| 88 | |
| 89 | ### 9. Performance Optimization (LOW-MEDIUM) - 2 rules |
| 90 | |
| 91 | - `perf-parallelism` - Tune parallelism for large deployments |
| 92 | - `perf-debug` - Enable debug logging for troubleshooting |
| 93 | |
| 94 | ### 10. Testing & Validation (LOW) - 2 rules |
| 95 | |
| 96 | - `test-strategies` - Testing pyramid (validate, lint, plan, integration) |
| 97 | - `test-policy-as-code` - Implement policy checks (OPA, Checkov, tfsec) |
| 98 | |
| 99 | ## How to Use |
| 100 | |
| 101 | Read individual rule files for detailed explanations and code examples: |
| 102 | |
| 103 | ``` |
| 104 | rules/state-remote-backend.md |
| 105 | rules/security-no-hardcoded-secrets.md |
| 106 | rules/module-versioning.md |
| 107 | ``` |
| 108 | |
| 109 | Each rule file contains: |
| 110 | - Brief explanation of why it matters |
| 111 | - Incorrect code example with explanation |
| 112 | - Correct code example with explanation |
| 113 | - |