[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71TF1SPJ16SPW1W8VBYRYZB":3,"skill-same:01M71TF1SPJ16SPW1W8VBYRYZB":65},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":25,"publishedAt":37,"linkOnly":38,"markdownContent":39,"markdownBody":40,"frontMatter":41,"refName":45,"commitSha":46,"skillDirectory":47,"forksCount":13,"repositoryHtmlUrl":48,"repositoryHomepageUrl":6,"ownerHtmlUrl":49,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":50,"install":51,"resources":64},"01M71TF1SPJ16SPW1W8VBYRYZB","terraform-skill",null,"Terraform infrastructure as code best practices","javiertarazon\u002Fide-agente-free-jt7-","javiertarazon","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F153141207?v=4","01M71R52TB3S9HXKH6WSNT8A7V","01M71R52VG5KS2DKDDH4GDQ30A",0,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fjaviertarazon\u002Fide-agente-free-jt7-\u002Fblob\u002Frelease\u002Fv4.2.11-panel-pro\u002F.github\u002Fskills\u002Fterraform-skill\u002FSKILL.md",[17,22],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000011","运维与部署","SCENARIO","使用场景",{"categoryNo":23,"categoryName":24,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000023","Skill与智能体开发",[26,27,28,29,30,31,32,33,34,35,36],"terraform skill","terraform","infrastructure as code","code","safe","terraform infrastructure","infrastructure","as","best practices","github","https","2026-11-10 13:02:02",false,"---\nname: terraform-skill\ndescription: \"Terraform infrastructure as code best practices\"\nlicense: Apache-2.0\nmetadata: \nauthor: \"Anton Babenko\"\nversion: 1.5.0\nsource: \"https:\u002F\u002Fgithub.com\u002Fantonbabenko\u002Fterraform-skill\"\nrisk: safe\n---\n# Terraform Skill for Claude\n\nComprehensive Terraform and OpenTofu guidance covering testing, modules, CI\u002FCD, and production patterns. Based on terraform-best-practices.com and enterprise experience.\n\n## When to Use This Skill\n\n**Activate this skill when:**\n- Creating new Terraform or OpenTofu configurations or modules\n- Setting up testing infrastructure for IaC code\n- Deciding between testing approaches (validate, plan, frameworks)\n- Structuring multi-environment deployments\n- Implementing CI\u002FCD for infrastructure-as-code\n- Reviewing or refactoring existing Terraform\u002FOpenTofu projects\n- Choosing between module patterns or state management approaches\n\n**Don't use this skill for:**\n- Basic Terraform\u002FOpenTofu syntax questions (Claude knows this)\n- Provider-specific API reference (link to docs instead)\n- Cloud platform questions unrelated to Terraform\u002FOpenTofu\n\n## Core Principles\n\n### 1. Code Structure Philosophy\n\n**Module Hierarchy:**\n\n| Type | When to Use | Scope |\n|------|-------------|-------|\n| **Resource Module** | Single logical group of connected resources | VPC + subnets, Security group + rules |\n| **Infrastructure Module** | Collection of resource modules for a purpose | Multiple resource modules in one region\u002Faccount |\n| **Composition** | Complete infrastructure | Spans multiple regions\u002Faccounts |\n\n**Hierarchy:** Resource → Resource Module → Infrastructure Module → Composition\n\n**Directory Structure:**\n```\nenvironments\u002F        # Environment-specific configurations\n├── prod\u002F\n├── staging\u002F\n└── dev\u002F\n\nmodules\u002F            # Reusable modules\n├── networking\u002F\n├── compute\u002F\n└── data\u002F\n\nexamples\u002F           # Module usage examples (also serve as tests)\n├── complete\u002F\n└── minimal\u002F\n```\n\n**Key principle from terraform-best-practices.com:**\n- Separate **environments** (prod, staging) from **modules** (reusable components)\n- Use **examples\u002F** as both documentation and integration test fixtures\n- Keep modules small and focused (single responsibility)\n\n**For detailed module architecture, see:** Code Patterns: Module Types & Hierarchy\n\n### 2. Naming Conventions\n\n**Resources:**\n```hcl\n# Good: Descriptive, contextual\nresource \"aws_instance\" \"web_server\" { }\nresource \"aws_s3_bucket\" \"application_logs\" { }\n\n# Good: \"this\" for singleton resources (only one of that type)\nresource \"aws_vpc\" \"this\" { }\nresource \"aws_security_group\" \"this\" { }\n\n# Avoid: Generic names for non-singletons\nresource \"aws_instance\" \"main\" { }\nresource \"aws_s3_bucket\" \"bucket\" { }\n```\n\n**Singleton Resources:**\n\nUse `\"this\"` when your module creates only one resource of that type:\n\n✅ DO:\n```hcl\nresource \"aws_vpc\" \"this\" {}           # Module creates one VPC\nresource \"aws_security_group\" \"this\" {}  # Module creates one SG\n```\n\n❌ DON'T use \"this\" for multiple resources:\n```hcl\nresource \"aws_subnet\" \"this\" {}  # If creating multiple subnets\n```\n\nUse descriptive names when creating multiple resources of the same type.\n\n**Variables:**\n```hcl\n# Prefix with context when needed\nvar.vpc_cidr_block          # Not just \"cidr\"\nvar.database_instance_class # Not just \"instance_class\"\n```\n\n**Files:**\n- `main.tf` - Primary resources\n- `variables.tf` - Input variables\n- `outputs.tf` - Output values\n- `versions.tf` - Provider versions\n- `data.tf` - Data sources (optional)\n\n## Testing Strategy Framework\n\n### Decision Matrix: Which Testing Approach?\n\n| Your Situation | Recommended Approach | Tools | Cost |\n|----------------|---------------------|-------|------|\n| **Quick syntax check** | Static analysis | `terraform validate`, `fmt` | Free |\n| **Pre-commit validation** | Static + lint | `validate`, `tflint`, `trivy`, `checkov` | Free |\n| **Terraform 1.6+, simple logic** | Native test framework | Built-in `terraform test` | Free-Low |\n| **Pre-1.6, or Go expertise** | Integration testing | Terratest | Low-Med |\n| **Security\u002Fcompliance focus** | Policy as code | OPA, Sentinel | Free |\n| **Cost-sensitive workflow** | Mock providers (1.7+) | Native tests + mocking | Free |\n| **Multi-cloud, complex** | Full integration | Terratest + real infra | Med-High |\n\n### Testing Pyramid for Infrastructure\n\n```\n        \u002F\\\n       \u002F  \\          End-to-End Tests (Expensive)\n      \u002F____\\         - Full environment deployment\n     \u002F      \\        - Production-like setup\n    \u002F________\\\n   \u002F          \\      Integration Tests (Moderate)\n  \u002F____________\\     - Module testing in isolation\n \u002F              \\    - Real resources in test account\n\u002F________________\\   Static Analysis (Cheap)\n                     - validate, fmt, lint\n                     - Security scanning\n```\n\n### Native Test Best Practices (1.6+)\n\n**Before generating test code:**\n\n1. **Validate schemas with Terraform MCP:**\n   ```\n   Search provider docs → Get resource schema → Identify block types\n   ```\n\n2. **Choose correct command mode:**\n   - `command = plan` - Fast, for input validation\n   - `command = apply` - Required for computed values and set-type blocks\n\n3. **Handle set-type blocks correctly:**\n   - Cannot index with `[0]`\n   - Use `for` expressions to iterate\n   - Or use `command = apply` to materialize\n\n**Common patterns:**\n- S3 encryption rules: **set** (use for expressions)\n- Lifecycle transitions: **set** (use for expressions)\n- IAM policy statements: **set** (use for expressions)\n\n**For detailed testing guides, see:**\n- **Testing Frameworks Guide** - Deep dive into static analysis, native tests, and Terratest\n- **Quick Reference** - Decision flowchart and command cheat sheet\n\n## Code Structure Standards\n\n### Resource Block Ordering\n\n**Strict ordering for consistency:**\n1. `count` or `for_each` FIRST (blank line after)\n2. Other arguments\n3. `tags` as last real argument\n4. `depends_on` after tags (if needed)\n5. `lifecycle` at the very end (if needed)\n\n```hcl\n# ✅ GOOD - Correct ordering\nresource \"aws_nat_gateway\" \"this\" {\n  count = var.create_nat_gateway ? 1 : 0\n\n  allocation_id = aws_eip.this[0].id\n  subnet_id     = aws_subnet.public[0].id\n\n  tags = {\n    Name = \"${var.name}-nat\"\n  }\n\n  depends_on = [aws_internet_gateway.this]\n\n  lifecycle {\n    create_before_destroy = true\n  }\n}\n```\n\n### Variable Block Ordering\n\n1. `description` (ALWAYS required)\n2. `type`\n3. `default`\n4. `validation`\n5. `nullable` (when setting to false)\n\n```hcl\nvariable \"environment\" {\n  description = \"Environment name for resource tagging\"\n  type        = string\n  default     = \"dev\"\n\n  validation {\n    condition     = contains([\"dev\", \"staging\", \"prod\"], var.environment)\n    error_message = \"Environment must be one of: dev, staging, prod.\"\n  }\n\n  nullable = false\n}\n```\n\n**For complete structure guidelines, see:** Code Patterns: Block Ordering & Structure\n\n## Count vs For_Each: When to Use Each\n\n### Quick Decision Guide\n\n| Scenario | Use | Why |\n|----------|-----|-----|\n| Boolean condition (create or don't) | `count = condition ? 1 : 0` | Simple on\u002Foff toggle |\n| Simple numeric replication | `count = 3` | Fixed number of identical resources |\n| Items may be reordered\u002Fremoved | `for_each = toset(list)` | Stable resource addresses |\n| Reference by key | `for_each = map` | Named access to resources |\n| Multiple named resources | `for_each` | Better maintainability |\n\n### Common Patterns\n\n**Boolean conditions:**\n```hcl\n# ✅ GOOD - Boolean condition\nresource \"aws_nat_gateway\" \"this\" {\n  count = var.create_nat_gateway ? 1 : 0\n  # ...\n}\n```\n\n**Stable addressing with for_each:**\n```hcl\n# ✅ GOOD - Removing \"us-east-1b\" only affects that subnet\nresource \"aws_subnet\" \"private\" {\n  for_each = toset(var.availability_zones)\n\n  availability_zone = each.key\n  # ...\n}\n\n# ❌ BAD - Removing middle AZ recreates all subsequent subnets\nresource \"aws_subnet\" \"private\" {\n  count = length(var.availability_zones)\n\n  availability_zone = var.availability_zones[count.index]\n  # ...\n}\n```\n\n**For migration guides and detailed examples, see:** Code Patterns: Count vs For_Each\n\n## Locals for Dependency Management\n\n**Use locals to ensure correct resource deletion order:**\n\n```hcl\n# Problem: Subnets might be deleted after CIDR blocks, causing errors\n# Solution: Use try() in locals to hint deletion order\n\nlocals {\n  # References secondary CIDR first, falling back to VPC\n  # Forces Terraform to delete subnets before CIDR association\n  vpc_id = try(\n    aws_vpc_ipv4_cidr_block_association.this[0].vpc_id,\n    aws_vpc.this.id,\n    \"\"\n  )\n}\n\nresource \"aws_vpc\" \"this\" {\n  cidr_block = \"10.0.0.0\u002F16\"\n}\n\nresource \"aws_vpc_ipv4_cidr_block_association\" \"this\" {\n  count = var.add_secondary_cidr ? 1 : 0\n\n  vpc_id     = aws_vpc.this.id\n  cidr_block = \"10.1.0.0\u002F16\"\n}\n\nresource \"aws_subnet\" \"public\" {\n  vpc_id     = local.vpc_id  # Uses local, not direct reference\n  cidr_block = \"10.1.0.0\u002F24\"\n}\n```\n\n**Why this matters:**\n- Prevents deletion errors when destroying infrastructure\n- Ensures correct dependency order without explicit `depends_on`\n- Particularly useful for VPC configurations with secondary CIDR blocks\n\n**For detailed examples, see:** Code Patterns: Locals for Dependency Management\n\n## Module Development\n\n### Standard Module Structure\n\n```\nmy-module\u002F\n├── README.md           # Usage documentation\n├── main.tf             # Primary resources\n├── variables.tf        # Input variables with descriptions\n├── outputs.tf          # Output values\n├── versions.tf         # Provider version constraints\n├── examples\u002F\n│   ├── minimal\u002F        # Minimal working example\n│   └── complete\u002F       # Full-featured example\n└── tests\u002F              # Test files\n    └── module_test.tftest.hcl  # Or .go\n```\n\n### Best Practices Summary\n\n**Variables:**\n- ✅ Always include `description`\n- ✅ Use explicit `type` constraints\n- ✅ Provide sensible `default` values where appropriate\n- ✅ Add `validation` blocks for complex constraints\n- ✅ Use `sensitive = true` for secrets\n\n**Outputs:**\n- ✅ Always include `description`\n- ✅ Mark sensitive outputs with `sensitive = true`\n- ✅ Consider returning objects for related values\n- ✅ Document what consumers should do with each output\n\n**For detailed module patterns, see:**\n- **Module Patterns Guide** - Variable best practices, output design, ✅ DO vs ❌ DON'T patterns\n- **Quick Reference** - Resource naming, variable naming, file organization\n\n## CI\u002FCD Integration\n\n### Recommended Workflow Stages\n\n1. **Validate** - Format check + syntax validation + linting\n2. **Test** - Run automated tests (native or Terratest)\n3. **Plan** - Generate and review execution plan\n4. **Apply** - Execute changes (with approvals for production)\n\n### Cost Optimization Strategy\n\n1. **Use mocking for PR validation** (free)\n2. **Run integration tests only on main branch** (controlled cost)\n3. **Implement auto-cleanup** (prevent orphaned resources)\n4. **Tag all test resources** (track spending)\n\n**For complete CI\u002FCD templates, see:**\n- **CI\u002FCD Workflows Guide** - GitHub Actions, GitLab CI, Atlantis integration, cost optimization\n- **Quick Reference** - Common CI\u002FCD issues and solutions\n\n## Security & Compliance\n\n### Essential Security Checks\n\n```bash\n# Static security scanning\ntrivy config .\ncheckov -d .\n```\n\n### Common Issues to Avoid\n\n❌ **Don't:**\n- Store secrets in variables\n- Use default VPC\n- Skip encryption\n- Open security groups to 0.0.0.0\u002F0\n\n✅ **Do:**\n- Use AWS Secrets Manager \u002F Parameter Store\n- Create dedicated VPCs\n- Enable encryption at rest\n- Use least-privilege security groups\n\n**For detailed security guidance, see:**\n- **Security & Compliance Guide** - Trivy\u002FCheckov integration, secrets management, state file security, compliance testing\n\n## Version Management\n\n### Version Constraint Syntax\n\n```hcl\nversion = \"5.0.0\"      # Exact (avoid - inflexible)\nversion = \"~> 5.0\"     # Recommended: 5.0.x only\nversion = \">= 5.0\"     # Minimum (risky - breaking changes)\n```\n\n### Strategy by Component\n\n| Component | Strategy | Example |\n|-----------|----------|---------|\n| **Terraform** | Pin minor version | `required_version = \"~> 1.9\"` |\n| **Providers** | Pin major version | `version = \"~> 5.0\"` |\n| **Modules (prod)** | Pin exact version | `version = \"5.1.2\"` |\n| **Modules (dev)** | Allow patch updates | `version = \"~> 5.1\"` |\n\n### Update Workflow\n\n```bash\n# Lock versions initially\nterraform init              # Creates .terraform.lock.hcl\n\n# Update to latest within constraints\nterraform init -upgrade     # Updates providers\n\n# Review and test\nterraform plan\n```\n\n**For detailed version management, see:** Code Patterns: Version Management\n\n## Modern Terraform Features (1.0+)\n\n### Feature Availability by Version\n\n| Feature | Version | Use Case |\n|---------|---------|----------|\n| `try()` function | 0.13+ | Safe fallbacks, replaces `element(concat())` |\n| `nullable = false` | 1.1+ | Prevent null values in variables |\n| `moved` blocks | 1.1+ | Refactor without destroy\u002Frecreate |\n| `optional()` with defaults | 1.3+ | Optional object attributes |\n| Native testing | 1.6+ | Built-in test framework |\n| Mock providers | 1.7+ | Cost-free unit testing |\n| Provider functions | 1.8+ | Provider-specific data transformation |\n| Cross-variable validation | 1.9+ | Validate relationships between variables |\n| Write-only arguments | 1.11+ | Secrets never stored in state |\n\n### Quick Examples\n\n```hcl\n# try() - Safe fallbacks (0.13+)\noutput \"sg_id\" {\n  value = try(aws_security_group.this[0].id, \"\")\n}\n\n# optional() - Optional attributes with defaults (1.3+)\nvariable \"config\" {\n  type = object({\n    name    = string\n    timeout = optional(number, 300)  # Default: 300\n  })\n}\n\n# Cross-variable validation (1.9+)\nvariable \"environment\" { type = string }\nvariable \"backup_days\" {\n  type = number\n  validation {\n    condition     = var.environment == \"prod\" ? var.backup_days >= 7 : true\n    error_message = \"Production requires backup_days >= 7\"\n  }\n}\n```\n\n**For complete patterns and examples, see:** Code Patterns: Modern Terraform Features\n\n## Version-Specific Guidance\n\n### Terraform 1.0-1.5\n- Use Terratest for testing\n- No native testing framework available\n- Focus on static analysis and plan validation\n\n### Terraform 1.6+ \u002F OpenTofu 1.6+\n- **New:** Native `terraform test` \u002F `tofu test` command\n- Consider migrating from external frameworks for simple tests\n- Keep Terratest only for complex integration tests\n\n### Terraform 1.7+ \u002F OpenTofu 1.7+\n- **New:** Mock providers for unit testing\n- Reduce cost by mocking external dependencies\n- Use real integration tests for final validation\n\n### Terraform vs OpenTofu\n\nBoth are fully supported by this skill. For licensing, governance, and feature comparison, see Quick Reference: Terraform vs OpenTofu.\n\n## Detailed Guides\n\nThis skill uses **progressive disclosure** - essential information is in this main file, detailed guides are available when needed:\n\n📚 **Reference Files:**\n- **Testing Frameworks** - In-depth guide to static analysis, native tests, and Terratest\n- **Module Patterns** - Module structure, variable\u002Foutput best practices, ✅ DO vs ❌ DON'T patterns\n- **CI\u002FCD Workflows** - GitHub Actions, GitLab CI templates, cost optimization, automated cleanup\n- **Security & Compliance** - Trivy\u002FCheckov integration, secrets management, compliance testing\n- **Quick Reference** - Command cheat sheets, decision flowcharts, troubleshooting guide\n\n**How to use:** When you need detailed information on a topic, reference the appropriate guide. Claude will load it on demand to provide comprehensive guidance.\n\n## License\n\nThis skill is licensed under the **Apache License 2.0**. See the LICENSE file for full terms.\n\n**Copyright © 2026 Anton Babenko**\n","# Terraform Skill for Claude\n\nComprehensive Terraform and OpenTofu guidance covering testing, modules, CI\u002FCD, and production patterns. Based on terraform-best-practices.com and enterprise experience.\n\n## When to Use This Skill\n\n**Activate this skill when:**\n- Creating new Terraform or OpenTofu configurations or modules\n- Setting up testing infrastructure for IaC code\n- Deciding between testing approaches (validate, plan, frameworks)\n- Structuring multi-environment deployments\n- Implementing CI\u002FCD for infrastructure-as-code\n- Reviewing or refactoring existing Terraform\u002FOpenTofu projects\n- Choosing between module patterns or state management approaches\n\n**Don't use this skill for:**\n- Basic Terraform\u002FOpenTofu syntax questions (Claude knows this)\n- Provider-specific API reference (link to docs instead)\n- Cloud platform questions unrelated to Terraform\u002FOpenTofu\n\n## Core Principles\n\n### 1. Code Structure Philosophy\n\n**Module Hierarchy:**\n\n| Type | When to Use | Scope |\n|------|-------------|-------|\n| **Resource Module** | Single logical group of connected resources | VPC + subnets, Security group + rules |\n| **Infrastructure Module** | Collection of resource modules for a purpose | Multiple resource modules in one region\u002Faccount |\n| **Composition** | Complete infrastructure | Spans multiple regions\u002Faccounts |\n\n**Hierarchy:** Resource → Resource Module → Infrastructure Module → Composition\n\n**Directory Structure:**\n```\nenvironments\u002F        # Environment-specific configurations\n├── prod\u002F\n├── staging\u002F\n└── dev\u002F\n\nmodules\u002F            # Reusable modules\n├── networking\u002F\n├── compute\u002F\n└── data\u002F\n\nexamples\u002F           # Module usage examples (also serve as tests)\n├── complete\u002F\n└── minimal\u002F\n```\n\n**Key principle from terraform-best-practices.com:**\n- Separate **environments** (prod, staging) from **modules** (reusable components)\n- Use **examples\u002F** as both documentation and integration test fixtures\n- Keep modules small and focused (single responsibility)\n\n**For detailed module architecture, see:** Code Patterns: Module Types & Hierarchy\n\n### 2. Naming Conventions\n\n**Resources:**\n```hcl\n# Good: Descriptive, contextual\nresource \"aws_instance\" \"web_server\" { }\nresource \"aws_s3_bucket\" \"application_logs\" { }\n\n# Good: \"this\" for singleton resources (only one of that type)\nresource \"aws_vpc\" \"this\" { }\nresource \"aws_security_group\" \"this\" { }\n\n# Avoid: Generic names for non-singletons\nresource \"aws_instance\" \"main\" { }\nresource \"aws_s3_bucket\" \"bucket\" { }\n```\n\n**Singleton Resources:**\n\nUse `\"this\"` when your module creates only one resource of that type:\n\n✅ DO:\n```hcl\nresource \"aws_vpc\" \"this\" {}           # Module creates one VPC\nresource \"aws_security_group\" \"this\" {}  # Module creates one SG\n```\n\n❌ DON'T use \"this\" for multiple resources:\n```hcl\nresource \"aws_subnet\" \"this\" {}  # If creating multiple subnets\n```\n\nUse descriptive names when creating multiple resources of the same type.\n\n**Variables:**\n```hcl\n# Prefix with context when needed\nvar.vpc_cidr_block          # Not just \"cidr\"\nvar.database_instance_class # Not just \"instance_class\"\n```\n\n**Files:**\n- `main.tf` - Primary resources\n- `variables.tf` - Input variables\n- `outputs.tf` - Output values\n- `versions.tf` - Provider versions\n- `data.tf` - Data sources (optional)\n\n## Testing Strategy Framework\n\n### Decision Matrix: Which Testing Approach?\n\n| Your Situation | Recommended Approach | Tools | Cost |\n|----------------|---------------------|-------|------|\n| **Quick syntax check** | Static analysis | `terraform validate`, `fmt` | Free |\n| **Pre-commit validation** | Static + lint | `validate`, `tflint`, `trivy`, `checkov` | Free |\n| **Terraform 1.6+, simple logic** | Native test framework | Built-in `terraform test` | Free-Low |\n| **Pre-1.6, or Go expertise** | Integration testing | Terratest | Low-Med |\n| **Security\u002Fcompliance focus** | Policy as code | OPA, Sentinel | Free |\n| **Cost-sensitive workflow** | Mock providers (1.7+) | Native tests + mocking | Free |\n| **Multi-cloud, complex** | Full integration | Terratest + real infra | Med-High |\n\n### Testing Pyramid for Infrastructure\n\n```\n        \u002F\\\n       \u002F  \\          End-to-End Tests (Expensive)\n      \u002F____\\         - Full environment deployment\n     \u002F      \\        - Production-like setup\n    \u002F________\\\n   \u002F          \\      Integration Tests (Moderate)\n  \u002F____________\\     - Module testing in isolation\n \u002F              \\    - Real resources in test account\n\u002F________________\\   Static Analysis (Cheap)\n                     - validate, fmt, lint\n                     - Security scanning\n```\n\n### Native Test Best Practices (1.6+)\n\n**Before generating test code:**\n\n1. **Validate schemas with Terraform MCP:**\n   ```\n   Search provider docs → Get resource schema → Identify block types\n   ```\n\n2. **Choose correct command mode:**\n   - `command = plan` - Fast, for input validation\n   - `command = apply` - Required for computed values and set-type blocks\n\n3. **Handle set-type blocks correctly:**\n   - Cannot index with `[0]`\n   - Use `for` expressions to iterate\n   - Or use `command = apply` to materialize\n\n**Common patterns:**\n- S3 encryption rules: **set** (use for expressions)\n- Lifecycle transitions: **set** (use for expressions)\n- IAM policy statements: **set** (use for expressions)\n\n**For detailed testing guides, see:**\n- **Testing Frameworks Guide** - Deep dive into static analysis, native tests, and Terratest\n- **Quick Reference** - Decision flowchart and command cheat sheet\n\n## Code Structure Standards\n\n### Resource Block Ordering\n\n**Strict ordering for consistency:**\n1. `count` or `for_each` FIRST (blank line after)\n2. Other arguments\n3. `tags` as last real argument\n4. `depends_on` after tags (if needed)\n5. `lifecycle` at the very end (if needed)\n\n```hcl\n# ✅ GOOD - Correct ordering\nresource \"aws_nat_gateway\" \"this\" {\n  count = var.create_nat_gateway ? 1 : 0\n\n  allocation_id = aws_eip.this[0].id\n  subnet_id     = aws_subnet.public[0].id\n\n  tags = {\n    Name = \"${var.name}-nat\"\n  }\n\n  depends_on = [aws_internet_gateway.this]\n\n  lifecycle {\n    create_before_destroy = true\n  }\n}\n```\n\n### Variable Block Ordering\n\n1. `description` (ALWAYS required)\n2. `type`\n3. `default`\n4. `validation`\n5. `nullable` (when setting to false)\n\n```hcl\nvariable \"environment\" {\n  description = \"Environment name for resource tagging\"\n  type        = string\n  default     = \"dev\"\n\n  validation {\n    condition     = contains([\"dev\", \"staging\", \"prod\"], var.environment)\n    error_message = \"Environment must be one of: dev, staging, prod.\"\n  }\n\n  nullable = false\n}\n```\n\n**For complete structure guidelines, see:** Code Patterns: Block Ordering & Structure\n\n## Count vs For_Each: When to Use Each\n\n### Quick Decision Guide\n\n| Scenario | Use | Why |\n|----------|-----|-----|\n| Boolean condition (create or don't) | `count = condition ? 1 : 0` | Simple on\u002Foff toggle |\n| Simple numeric replication | `count = 3` | Fixed number of identical resources |\n| Items may be reordered\u002Fremoved | `for_each = toset(list)` | Stable resource addresses |\n| Reference by key | `for_each = map` | Named access to resources |\n| Multiple named resources | `for_each` | Better maintainability |\n\n### Common Patterns\n\n**Boolean conditions:**\n```hcl\n# ✅ GOOD - Boolean condition\nresource \"aws_nat_gateway\" \"this\" {\n  count = var.create_nat_gateway ? 1 : 0\n  # ...\n}\n```\n\n**Stable addressing with for_each:**\n```hcl\n# ✅ GOOD - Removing \"us-east-1b\" only affects that subnet\nresource \"aws_subnet\" \"private\" {\n  for_each = toset(var.availability_zones)\n\n  availability_zone = each.key\n  # ...\n}\n\n# ❌ BAD - Removing middle AZ recreates all subsequent subnets\nresource \"aws_subnet\" \"private\" {\n  count = length(var.availability_zones)\n\n  availability_zone = var.availability_zones[count.index]\n  # ...\n}\n```\n\n**For migration guides and detailed examples, see:** Code Patterns: Count vs For_Each\n\n## Locals for Dependency Management\n\n**Use locals to ensure correct resource deletion order:**\n\n```hcl\n# Problem: Subnets might be deleted after CIDR blocks, causing errors\n# Solution: Use try() in locals to hint deletion order\n\nlocals {\n  # References secondary CIDR first, falling back to VPC\n  # Forces Terraform to delete subnets before CIDR association\n  vpc_id = try(\n    aws_vpc_ipv4_cidr_block_association.this[0].vpc_id,\n    aws_vpc.this.id,\n    \"\"\n  )\n}\n\nresource \"aws_vpc\" \"this\" {\n  cidr_block = \"10.0.0.0\u002F16\"\n}\n\nresource \"aws_vpc_ipv4_cidr_block_association\" \"this\" {\n  count = var.add_secondary_cidr ? 1 : 0\n\n  vpc_id     = aws_vpc.this.id\n  cidr_block = \"10.1.0.0\u002F16\"\n}\n\nresource \"aws_subnet\" \"public\" {\n  vpc_id     = local.vpc_id  # Uses local, not direct reference\n  cidr_block = \"10.1.0.0\u002F24\"\n}\n```\n\n**Why this matters:**\n- Prevents deletion errors when destroying infrastructure\n- Ensures correct dependency order without explicit `depends_on`\n- Particularly useful for VPC configurations with secondary CIDR blocks\n\n**For detailed examples, see:** Code Patterns: Locals for Dependency Management\n\n## Module Development\n\n### Standard Module Structure\n\n```\nmy-module\u002F\n├── README.md           # Usage documentation\n├── main.tf             # Primary resources\n├── variables.tf        # Input variables with descriptions\n├── outputs.tf          # Output values\n├── versions.tf         # Provider version constraints\n├── examples\u002F\n│   ├── minimal\u002F        # Minimal working example\n│   └── complete\u002F       # Full-featured example\n└── tests\u002F              # Test files\n    └── module_test.tftest.hcl  # Or .go\n```\n\n### Best Practices Summary\n\n**Variables:**\n- ✅ Always include `description`\n- ✅ Use explicit `type` constraints\n- ✅ Provide sensible `default` values where appropriate\n- ✅ Add `validation` blocks for complex constraints\n- ✅ Use `sensitive = true` for secrets\n\n**Outputs:**\n- ✅ Always include `description`\n- ✅ Mark sensitive outputs with `sensitive = true`\n- ✅ Consider returning objects for related values\n- ✅ Document what consumers should do with each output\n\n**For detailed module patterns, see:**\n- **Module Patterns Guide** - Variable best practices, output design, ✅ DO vs ❌ DON'T patterns\n- **Quick Reference** - Resource naming, variable naming, file organization\n\n## CI\u002FCD Integration\n\n### Recommended Workflow Stages\n\n1. **Validate** - Format check + syntax validation + linting\n2. **Test** - Run automated tests (native or Terratest)\n3. **Plan** - Generate and review execution plan\n4. **Apply** - Execute changes (with approvals for production)\n\n### Cost Optimization Strategy\n\n1. **Use mocking for PR validation** (free)\n2. **Run integration tests only on main branch** (controlled cost)\n3. **Implement auto-cleanup** (prevent orphaned resources)\n4. **Tag all test resources** (track spending)\n\n**For complete CI\u002FCD templates, see:**\n- **CI\u002FCD Workflows Guide** - GitHub Actions, GitLab CI, Atlantis integration, cost optimization\n- **Quick Reference** - Common CI\u002FCD issues and solutions\n\n## Security & Compliance\n\n### Essential Security Checks\n\n```bash\n# Static security scanning\ntrivy config .\ncheckov -d .\n```\n\n### Common Issues to Avoid\n\n❌ **Don't:**\n- Store secrets in variables\n- Use default VPC\n- Skip encryption\n- Open security groups to 0.0.0.0\u002F0\n\n✅ **Do:**\n- Use AWS Secrets Manager \u002F Parameter Store\n- Create dedicated VPCs\n- Enable encryption at rest\n- Use least-privilege security groups\n\n**For detailed security guidance, see:**\n- **Security & Compliance Guide** - Trivy\u002FCheckov integration, secrets management, state file security, compliance testing\n\n## Version Management\n\n### Version Constraint Syntax\n\n```hcl\nversion = \"5.0.0\"      # Exact (avoid - inflexible)\nversion = \"~> 5.0\"     # Recommended: 5.0.x only\nversion = \">= 5.0\"     # Minimum (risky - breaking changes)\n```\n\n### Strategy by Component\n\n| Component | Strategy | Example |\n|-----------|----------|---------|\n| **Terraform** | Pin minor version | `required_version = \"~> 1.9\"` |\n| **Providers** | Pin major version | `version = \"~> 5.0\"` |\n| **Modules (prod)** | Pin exact version | `version = \"5.1.2\"` |\n| **Modules (dev)** | Allow patch updates | `version = \"~> 5.1\"` |\n\n### Update Workflow\n\n```bash\n# Lock versions initially\nterraform init              # Creates .terraform.lock.hcl\n\n# Update to latest within constraints\nterraform init -upgrade     # Updates providers\n\n# Review and test\nterraform plan\n```\n\n**For detailed version management, see:** Code Patterns: Version Management\n\n## Modern Terraform Features (1.0+)\n\n### Feature Availability by Version\n\n| Feature | Version | Use Case |\n|---------|---------|----------|\n| `try()` function | 0.13+ | Safe fallbacks, replaces `element(concat())` |\n| `nullable = false` | 1.1+ | Prevent null values in variables |\n| `moved` blocks | 1.1+ | Refactor without destroy\u002Frecreate |\n| `optional()` with defaults | 1.3+ | Optional object attributes |\n| Native testing | 1.6+ | Built-in test framework |\n| Mock providers | 1.7+ | Cost-free unit testing |\n| Provider functions | 1.8+ | Provider-specific data transformation |\n| Cross-variable validation | 1.9+ | Validate relationships between variables |\n| Write-only arguments | 1.11+ | Secrets never stored in state |\n\n### Quick Examples\n\n```hcl\n# try() - Safe fallbacks (0.13+)\noutput \"sg_id\" {\n  value = try(aws_security_group.this[0].id, \"\")\n}\n\n# optional() - Optional attributes with defaults (1.3+)\nvariable \"config\" {\n  type = object({\n    name    = string\n    timeout = optional(number, 300)  # Default: 300\n  })\n}\n\n# Cross-variable validation (1.9+)\nvariable \"environment\" { type = string }\nvariable \"backup_days\" {\n  type = number\n  validation {\n    condition     = var.environment == \"prod\" ? var.backup_days >= 7 : true\n    error_message = \"Production requires backup_days >= 7\"\n  }\n}\n```\n\n**For complete patterns and examples, see:** Code Patterns: Modern Terraform Features\n\n## Version-Specific Guidance\n\n### Terraform 1.0-1.5\n- Use Terratest for testing\n- No native testing framework available\n- Focus on static analysis and plan validation\n\n### Terraform 1.6+ \u002F OpenTofu 1.6+\n- **New:** Native `terraform test` \u002F `tofu test` command\n- Consider migrating from external frameworks for simple tests\n- Keep Terratest only for complex integration tests\n\n### Terraform 1.7+ \u002F OpenTofu 1.7+\n- **New:** Mock providers for unit testing\n- Reduce cost by mocking external dependencies\n- Use real integration tests for final validation\n\n### Terraform vs OpenTofu\n\nBoth are fully supported by this skill. For licensing, governance, and feature comparison, see Quick Reference: Terraform vs OpenTofu.\n\n## Detailed Guides\n\nThis skill uses **progressive disclosure** - essential information is in this main file, detailed guides are available when needed:\n\n📚 **Reference Files:**\n- **Testing Frameworks** - In-depth guide to static analysis, native tests, and Terratest\n- **Module Patterns** - Module structure, variable\u002Foutput best practices, ✅ DO vs ❌ DON'T patterns\n- **CI\u002FCD Workflows** - GitHub Actions, GitLab CI templates, cost optimization, automated cleanup\n- **Security & Compliance** - Trivy\u002FCheckov integration, secrets management, compliance testing\n- **Quick Reference** - Command cheat sheets, decision flowcharts, troubleshooting guide\n\n**How to use:** When you need detailed information on a topic, reference the appropriate guide. Claude will load it on demand to provide comprehensive guidance.\n\n## License\n\nThis skill is licensed under the **Apache License 2.0**. See the LICENSE file for full terms.\n\n**Copyright © 2026 Anton Babenko**\n",{"name":5,"risk":30,"author":42,"source":43,"license":14,"version":44,"metadata":6,"description":7},"Anton Babenko","https:\u002F\u002Fgithub.com\u002Fantonbabenko\u002Fterraform-skill","1.5.0","release\u002Fv4.2.11-panel-pro","a92ea02bcf7e2b3dbaf46d49696c29a3cb490d4f",".github\u002Fskills\u002Fterraform-skill","https:\u002F\u002Fgithub.com\u002Fjaviertarazon\u002Fide-agente-free-jt7-","https:\u002F\u002Fgithub.com\u002Fjaviertarazon","2026-07-12 07:10:45",{"source":8,"skillName":5,"commands":52,"prompt":62,"zipAvailable":63},[53,56,59],{"tool":54,"command":55},"npx","npx skills add javiertarazon\u002Fide-agente-free-jt7- --skill terraform-skill",{"tool":57,"command":58},"bunx","bunx skills add javiertarazon\u002Fide-agente-free-jt7- --skill terraform-skill",{"tool":60,"command":61},"pnpm","pnpm dlx skills add javiertarazon\u002Fide-agente-free-jt7- --skill terraform-skill","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjaviertarazon\u002Fide-agente-free-jt7-\u002Fblob\u002Frelease\u002Fv4.2.11-panel-pro\u002F.github\u002Fskills\u002Fterraform-skill\u002FSKILL.md",true,[],[66,97,122,142,157,178],{"skillNo":67,"name":68,"nameZh":6,"description":69,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":70,"licenseFileUrl":6,"sourceHtmlUrl":71,"categories":72,"keywords":76,"publishedAt":37},"01M71TQ7Q6Z10VWF3C2H5X1KW9","zustand-store-ts","Create Zustand stores with TypeScript, subscribeWithSelector middleware, and proper state\u002Faction separation. Use when building React state management, creating global stores, or implementing reacti...","MIT","https:\u002F\u002Fgithub.com\u002Fjaviertarazon\u002Fide-agente-free-jt7-\u002Fblob\u002Frelease\u002Fv4.2.11-panel-pro\u002F.github\u002Fskills\u002Fzustand-store-ts\u002FSKILL.md",[73],{"categoryNo":74,"categoryName":75,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000009","前端开发",[77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96],"zustand","store","zustand store ts","community","middleware","implementing","use","react state management","when","unknown","react","with","state","create","state management","typescript","action","management","separation","global",{"skillNo":98,"name":99,"nameZh":6,"description":100,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":70,"licenseFileUrl":6,"sourceHtmlUrl":101,"categories":102,"keywords":104,"publishedAt":37},"01M71TQ5EAR40G6W0MV5ZDVEZT","zoom-automation","Automate Zoom meeting creation, management, recordings, webinars, and participant tracking via Rube MCP (Composio). Always search tools first for current schemas.","https:\u002F\u002Fgithub.com\u002Fjaviertarazon\u002Fide-agente-free-jt7-\u002Fblob\u002Frelease\u002Fv4.2.11-panel-pro\u002F.github\u002Fskills\u002Fzoom-automation\u002FSKILL.md",[103],{"categoryNo":23,"categoryName":24,"taxonomyType":20,"taxonomyTypeDesc":21},[105,106,107,80,108,109,110,111,112,86,113,114,115,116,117,118,119,120,94,121],"zoom automation","zoom","automation","creation","for","search","schemas","MCP","first","via","meeting","search tools","tracking","webinars","composio","recordings","Tools",{"skillNo":123,"name":124,"nameZh":6,"description":125,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":70,"licenseFileUrl":6,"sourceHtmlUrl":126,"categories":127,"keywords":129,"publishedAt":37},"01M71TQ29B1EYBCEAP1ZBGXQ1A","zoho-crm-automation","Automate Zoho CRM tasks via Rube MCP (Composio): create\u002Fupdate records, search contacts, manage leads, and convert leads. Always search tools first for current schemas.","https:\u002F\u002Fgithub.com\u002Fjaviertarazon\u002Fide-agente-free-jt7-\u002Fblob\u002Frelease\u002Fv4.2.11-panel-pro\u002F.github\u002Fskills\u002Fzoho-crm-automation\u002FSKILL.md",[128],{"categoryNo":23,"categoryName":24,"taxonomyType":20,"taxonomyTypeDesc":21},[130,131,107,132,133,134,80,135,136,109,137,110,111,138,112,86,139,140,141,90],"crm automation","zoho crm automation","crm","zoho crm","zoho","leads","manage leads","manage","records","convert","tasks","contacts",{"skillNo":143,"name":144,"nameZh":6,"description":145,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":70,"licenseFileUrl":6,"sourceHtmlUrl":146,"categories":147,"keywords":149,"publishedAt":37},"01M71TPZPMN60DH0XV58KVHY23","zendesk-automation","Automate Zendesk tasks via Rube MCP (Composio): tickets, users, organizations, replies. Always search tools first for current schemas.","https:\u002F\u002Fgithub.com\u002Fjaviertarazon\u002Fide-agente-free-jt7-\u002Fblob\u002Frelease\u002Fv4.2.11-panel-pro\u002F.github\u002Fskills\u002Fzendesk-automation\u002FSKILL.md",[148],{"categoryNo":23,"categoryName":24,"taxonomyType":20,"taxonomyTypeDesc":21},[150,107,151,80,109,110,111,112,152,86,140,153,154,113,114,155,116,119,121,156],"zendesk automation","zendesk","organizations","replies","users","tickets","automate",{"skillNo":158,"name":159,"nameZh":6,"description":160,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":70,"licenseFileUrl":6,"sourceHtmlUrl":161,"categories":162,"keywords":163,"publishedAt":37},"01M71TPXDWKHKG4N6TVEPXWD0N","zapier-make-patterns","No-code automation democratizes workflow building. Zapier and Make (formerly Integromat) let non-developers automate business processes without writing code. But no-code doesn't mean no-complexity ...","https:\u002F\u002Fgithub.com\u002Fjaviertarazon\u002Fide-agente-free-jt7-\u002Fblob\u002Frelease\u002Fv4.2.11-panel-pro\u002F.github\u002Fskills\u002Fzapier-make-patterns\u002FSKILL.md",[],[164,165,166,167,168,169,170,171,172,107,173,86,29,174,175,176,177,156],"zapier make patterns","zapier","patterns","make","No-Code","complexity","writing","spawner","business","workflow","integromat","apache","processes","but",{"skillNo":179,"name":180,"nameZh":6,"description":181,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":70,"licenseFileUrl":6,"sourceHtmlUrl":182,"categories":183,"keywords":187,"publishedAt":37},"01M71TPT5T10WXNKW9G7ZXZ27W","youtube-summarizer","Extract transcripts from YouTube videos and generate comprehensive, detailed summaries using intelligent analysis frameworks","https:\u002F\u002Fgithub.com\u002Fjaviertarazon\u002Fide-agente-free-jt7-\u002Fblob\u002Frelease\u002Fv4.2.11-panel-pro\u002F.github\u002Fskills\u002Fyoutube-summarizer\u002FSKILL.md",[184],{"categoryNo":185,"categoryName":186,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000016","图像与多媒体",[188,189,190,191,80,192,193,194,195,196,197,198,29,199,200,201,35,202,203,204],"summarizer","youtube","youtube summarizer","Video","content-analysis","frameworks","copilot","2025","github-copilot","extract transcripts","analysis","codex","cli","summaries","generate","summarization","2026"]