feat: add 61 new skills from VoltAgent repository
- 27 official team skills (Sentry, Trail of Bits, Expo, Hugging Face, etc.) - 34 community skills including context engineering suite - All skills validated and compliant with V4 quality bar - Complete source attribution maintained Skills added: - Official: commit, create-pr, find-bugs, iterate-pr, culture-index, fix-review, sharp-edges, expo-deployment, upgrading-expo, hugging-face-cli, hugging-face-jobs, vercel-deploy-claimable, design-md, using-neon, n8n-*, swiftui-expert-skill, fal-*, deep-research, imagen, readme, screenshots - Community: frontend-slides, linear-claude-skill, skill-rails-upgrade, context-*, multi-agent-patterns, tool-design, evaluation, memory-systems, terraform-skill, and more
This commit is contained in:
517
skills/terraform-skill/SKILL.md
Normal file
517
skills/terraform-skill/SKILL.md
Normal file
@@ -0,0 +1,517 @@
|
||||
---
|
||||
name: terraform-skill
|
||||
description: "Terraform infrastructure as code best practices"
|
||||
license: Apache-2.0
|
||||
metadata:
|
||||
author: "Anton Babenko"
|
||||
version: 1.5.0
|
||||
source: "https://github.com/antonbabenko/terraform-skill"
|
||||
risk: safe
|
||||
---
|
||||
# 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.
|
||||
|
||||
## 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
|
||||
|
||||
## Core Principles
|
||||
|
||||
### 1. Code Structure Philosophy
|
||||
|
||||
**Module Hierarchy:**
|
||||
|
||||
| Type | When to Use | Scope |
|
||||
|------|-------------|-------|
|
||||
| **Resource Module** | Single logical group of connected resources | VPC + subnets, Security group + rules |
|
||||
| **Infrastructure Module** | Collection of resource modules for a purpose | Multiple resource modules in one region/account |
|
||||
| **Composition** | Complete infrastructure | Spans multiple regions/accounts |
|
||||
|
||||
**Hierarchy:** Resource → Resource Module → Infrastructure Module → Composition
|
||||
|
||||
**Directory Structure:**
|
||||
```
|
||||
environments/ # Environment-specific configurations
|
||||
├── prod/
|
||||
├── staging/
|
||||
└── dev/
|
||||
|
||||
modules/ # Reusable modules
|
||||
├── networking/
|
||||
├── compute/
|
||||
└── data/
|
||||
|
||||
examples/ # Module usage examples (also serve as tests)
|
||||
├── complete/
|
||||
└── minimal/
|
||||
```
|
||||
|
||||
**Key principle from terraform-best-practices.com:**
|
||||
- Separate **environments** (prod, staging) from **modules** (reusable components)
|
||||
- Use **examples/** as both documentation and integration test fixtures
|
||||
- Keep modules small and focused (single responsibility)
|
||||
|
||||
**For detailed module architecture, see:** [Code Patterns: Module Types & Hierarchy](references/code-patterns.md)
|
||||
|
||||
### 2. Naming Conventions
|
||||
|
||||
**Resources:**
|
||||
```hcl
|
||||
# Good: Descriptive, contextual
|
||||
resource "aws_instance" "web_server" { }
|
||||
resource "aws_s3_bucket" "application_logs" { }
|
||||
|
||||
# Good: "this" for singleton resources (only one of that type)
|
||||
resource "aws_vpc" "this" { }
|
||||
resource "aws_security_group" "this" { }
|
||||
|
||||
# Avoid: Generic names for non-singletons
|
||||
resource "aws_instance" "main" { }
|
||||
resource "aws_s3_bucket" "bucket" { }
|
||||
```
|
||||
|
||||
**Singleton Resources:**
|
||||
|
||||
Use `"this"` when your module creates only one resource of that type:
|
||||
|
||||
✅ DO:
|
||||
```hcl
|
||||
resource "aws_vpc" "this" {} # Module creates one VPC
|
||||
resource "aws_security_group" "this" {} # Module creates one SG
|
||||
```
|
||||
|
||||
❌ DON'T use "this" for multiple resources:
|
||||
```hcl
|
||||
resource "aws_subnet" "this" {} # If creating multiple subnets
|
||||
```
|
||||
|
||||
Use descriptive names when creating multiple resources of the same type.
|
||||
|
||||
**Variables:**
|
||||
```hcl
|
||||
# Prefix with context when needed
|
||||
var.vpc_cidr_block # Not just "cidr"
|
||||
var.database_instance_class # Not just "instance_class"
|
||||
```
|
||||
|
||||
**Files:**
|
||||
- `main.tf` - Primary resources
|
||||
- `variables.tf` - Input variables
|
||||
- `outputs.tf` - Output values
|
||||
- `versions.tf` - Provider versions
|
||||
- `data.tf` - Data sources (optional)
|
||||
|
||||
## Testing Strategy Framework
|
||||
|
||||
### Decision Matrix: Which Testing Approach?
|
||||
|
||||
| Your Situation | Recommended Approach | Tools | Cost |
|
||||
|----------------|---------------------|-------|------|
|
||||
| **Quick syntax check** | Static analysis | `terraform validate`, `fmt` | Free |
|
||||
| **Pre-commit validation** | Static + lint | `validate`, `tflint`, `trivy`, `checkov` | Free |
|
||||
| **Terraform 1.6+, simple logic** | Native test framework | Built-in `terraform test` | Free-Low |
|
||||
| **Pre-1.6, or Go expertise** | Integration testing | Terratest | Low-Med |
|
||||
| **Security/compliance focus** | Policy as code | OPA, Sentinel | Free |
|
||||
| **Cost-sensitive workflow** | Mock providers (1.7+) | Native tests + mocking | Free |
|
||||
| **Multi-cloud, complex** | Full integration | Terratest + real infra | Med-High |
|
||||
|
||||
### Testing Pyramid for Infrastructure
|
||||
|
||||
```
|
||||
/\
|
||||
/ \ End-to-End Tests (Expensive)
|
||||
/____\ - Full environment deployment
|
||||
/ \ - Production-like setup
|
||||
/________\
|
||||
/ \ Integration Tests (Moderate)
|
||||
/____________\ - Module testing in isolation
|
||||
/ \ - Real resources in test account
|
||||
/________________\ Static Analysis (Cheap)
|
||||
- validate, fmt, lint
|
||||
- Security scanning
|
||||
```
|
||||
|
||||
### Native Test Best Practices (1.6+)
|
||||
|
||||
**Before generating test code:**
|
||||
|
||||
1. **Validate schemas with Terraform MCP:**
|
||||
```
|
||||
Search provider docs → Get resource schema → Identify block types
|
||||
```
|
||||
|
||||
2. **Choose correct command mode:**
|
||||
- `command = plan` - Fast, for input validation
|
||||
- `command = apply` - Required for computed values and set-type blocks
|
||||
|
||||
3. **Handle set-type blocks correctly:**
|
||||
- Cannot index with `[0]`
|
||||
- Use `for` expressions to iterate
|
||||
- Or use `command = apply` to materialize
|
||||
|
||||
**Common patterns:**
|
||||
- S3 encryption rules: **set** (use for expressions)
|
||||
- Lifecycle transitions: **set** (use for expressions)
|
||||
- IAM policy statements: **set** (use for expressions)
|
||||
|
||||
**For detailed testing guides, see:**
|
||||
- **[Testing Frameworks Guide](references/testing-frameworks.md)** - Deep dive into static analysis, native tests, and Terratest
|
||||
- **[Quick Reference](references/quick-reference.md#testing-approach-selection)** - Decision flowchart and command cheat sheet
|
||||
|
||||
## Code Structure Standards
|
||||
|
||||
### Resource Block Ordering
|
||||
|
||||
**Strict ordering for consistency:**
|
||||
1. `count` or `for_each` FIRST (blank line after)
|
||||
2. Other arguments
|
||||
3. `tags` as last real argument
|
||||
4. `depends_on` after tags (if needed)
|
||||
5. `lifecycle` at the very end (if needed)
|
||||
|
||||
```hcl
|
||||
# ✅ GOOD - Correct ordering
|
||||
resource "aws_nat_gateway" "this" {
|
||||
count = var.create_nat_gateway ? 1 : 0
|
||||
|
||||
allocation_id = aws_eip.this[0].id
|
||||
subnet_id = aws_subnet.public[0].id
|
||||
|
||||
tags = {
|
||||
Name = "${var.name}-nat"
|
||||
}
|
||||
|
||||
depends_on = [aws_internet_gateway.this]
|
||||
|
||||
lifecycle {
|
||||
create_before_destroy = true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Variable Block Ordering
|
||||
|
||||
1. `description` (ALWAYS required)
|
||||
2. `type`
|
||||
3. `default`
|
||||
4. `validation`
|
||||
5. `nullable` (when setting to false)
|
||||
|
||||
```hcl
|
||||
variable "environment" {
|
||||
description = "Environment name for resource tagging"
|
||||
type = string
|
||||
default = "dev"
|
||||
|
||||
validation {
|
||||
condition = contains(["dev", "staging", "prod"], var.environment)
|
||||
error_message = "Environment must be one of: dev, staging, prod."
|
||||
}
|
||||
|
||||
nullable = false
|
||||
}
|
||||
```
|
||||
|
||||
**For complete structure guidelines, see:** [Code Patterns: Block Ordering & Structure](references/code-patterns.md#block-ordering--structure)
|
||||
|
||||
## 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:**
|
||||
```hcl
|
||||
# ✅ GOOD - Boolean condition
|
||||
resource "aws_nat_gateway" "this" {
|
||||
count = var.create_nat_gateway ? 1 : 0
|
||||
# ...
|
||||
}
|
||||
```
|
||||
|
||||
**Stable addressing with for_each:**
|
||||
```hcl
|
||||
# ✅ 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](references/code-patterns.md#count-vs-for_each-deep-dive)
|
||||
|
||||
## Locals for Dependency Management
|
||||
|
||||
**Use locals to ensure correct resource deletion order:**
|
||||
|
||||
```hcl
|
||||
# Problem: Subnets might be deleted after CIDR blocks, causing errors
|
||||
# Solution: Use try() in locals to hint deletion order
|
||||
|
||||
locals {
|
||||
# References secondary CIDR first, falling back to VPC
|
||||
# Forces Terraform to delete subnets before CIDR association
|
||||
vpc_id = try(
|
||||
aws_vpc_ipv4_cidr_block_association.this[0].vpc_id,
|
||||
aws_vpc.this.id,
|
||||
""
|
||||
)
|
||||
}
|
||||
|
||||
resource "aws_vpc" "this" {
|
||||
cidr_block = "10.0.0.0/16"
|
||||
}
|
||||
|
||||
resource "aws_vpc_ipv4_cidr_block_association" "this" {
|
||||
count = var.add_secondary_cidr ? 1 : 0
|
||||
|
||||
vpc_id = aws_vpc.this.id
|
||||
cidr_block = "10.1.0.0/16"
|
||||
}
|
||||
|
||||
resource "aws_subnet" "public" {
|
||||
vpc_id = local.vpc_id # Uses local, not direct reference
|
||||
cidr_block = "10.1.0.0/24"
|
||||
}
|
||||
```
|
||||
|
||||
**Why this matters:**
|
||||
- Prevents deletion errors when destroying infrastructure
|
||||
- Ensures correct dependency order without explicit `depends_on`
|
||||
- Particularly useful for VPC configurations with secondary CIDR blocks
|
||||
|
||||
**For detailed examples, see:** [Code Patterns: Locals for Dependency Management](references/code-patterns.md#locals-for-dependency-management)
|
||||
|
||||
## Module Development
|
||||
|
||||
### Standard Module Structure
|
||||
|
||||
```
|
||||
my-module/
|
||||
├── README.md # Usage documentation
|
||||
├── main.tf # Primary resources
|
||||
├── variables.tf # Input variables with descriptions
|
||||
├── outputs.tf # Output values
|
||||
├── versions.tf # Provider version constraints
|
||||
├── examples/
|
||||
│ ├── minimal/ # Minimal working example
|
||||
│ └── complete/ # Full-featured example
|
||||
└── tests/ # Test files
|
||||
└── module_test.tftest.hcl # Or .go
|
||||
```
|
||||
|
||||
### Best Practices Summary
|
||||
|
||||
**Variables:**
|
||||
- ✅ Always include `description`
|
||||
- ✅ Use explicit `type` constraints
|
||||
- ✅ Provide sensible `default` values where appropriate
|
||||
- ✅ Add `validation` blocks for complex constraints
|
||||
- ✅ Use `sensitive = true` for secrets
|
||||
|
||||
**Outputs:**
|
||||
- ✅ Always include `description`
|
||||
- ✅ Mark sensitive outputs with `sensitive = true`
|
||||
- ✅ Consider returning objects for related values
|
||||
- ✅ Document what consumers should do with each output
|
||||
|
||||
**For detailed module patterns, see:**
|
||||
- **[Module Patterns Guide](references/module-patterns.md)** - Variable best practices, output design, ✅ DO vs ❌ DON'T patterns
|
||||
- **[Quick Reference](references/quick-reference.md#common-patterns)** - Resource naming, variable naming, file organization
|
||||
|
||||
## CI/CD Integration
|
||||
|
||||
### Recommended Workflow Stages
|
||||
|
||||
1. **Validate** - Format check + syntax validation + linting
|
||||
2. **Test** - Run automated tests (native or Terratest)
|
||||
3. **Plan** - Generate and review execution plan
|
||||
4. **Apply** - Execute changes (with approvals for production)
|
||||
|
||||
### Cost Optimization Strategy
|
||||
|
||||
1. **Use mocking for PR validation** (free)
|
||||
2. **Run integration tests only on main branch** (controlled cost)
|
||||
3. **Implement auto-cleanup** (prevent orphaned resources)
|
||||
4. **Tag all test resources** (track spending)
|
||||
|
||||
**For complete CI/CD templates, see:**
|
||||
- **[CI/CD Workflows Guide](references/ci-cd-workflows.md)** - GitHub Actions, GitLab CI, Atlantis integration, cost optimization
|
||||
- **[Quick Reference](references/quick-reference.md#troubleshooting-guide)** - Common CI/CD issues and solutions
|
||||
|
||||
## Security & Compliance
|
||||
|
||||
### Essential Security Checks
|
||||
|
||||
```bash
|
||||
# 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](references/security-compliance.md)** - Trivy/Checkov integration, secrets management, state file security, compliance testing
|
||||
|
||||
## Version Management
|
||||
|
||||
### Version Constraint Syntax
|
||||
|
||||
```hcl
|
||||
version = "5.0.0" # Exact (avoid - inflexible)
|
||||
version = "~> 5.0" # Recommended: 5.0.x only
|
||||
version = ">= 5.0" # Minimum (risky - breaking changes)
|
||||
```
|
||||
|
||||
### Strategy by Component
|
||||
|
||||
| Component | Strategy | Example |
|
||||
|-----------|----------|---------|
|
||||
| **Terraform** | Pin minor version | `required_version = "~> 1.9"` |
|
||||
| **Providers** | Pin major version | `version = "~> 5.0"` |
|
||||
| **Modules (prod)** | Pin exact version | `version = "5.1.2"` |
|
||||
| **Modules (dev)** | Allow patch updates | `version = "~> 5.1"` |
|
||||
|
||||
### Update Workflow
|
||||
|
||||
```bash
|
||||
# Lock versions initially
|
||||
terraform init # Creates .terraform.lock.hcl
|
||||
|
||||
# Update to latest within constraints
|
||||
terraform init -upgrade # Updates providers
|
||||
|
||||
# Review and test
|
||||
terraform plan
|
||||
```
|
||||
|
||||
**For detailed version management, see:** [Code Patterns: Version Management](references/code-patterns.md#version-management)
|
||||
|
||||
## Modern Terraform Features (1.0+)
|
||||
|
||||
### Feature Availability by Version
|
||||
|
||||
| Feature | Version | Use Case |
|
||||
|---------|---------|----------|
|
||||
| `try()` function | 0.13+ | Safe fallbacks, replaces `element(concat())` |
|
||||
| `nullable = false` | 1.1+ | Prevent null values in variables |
|
||||
| `moved` blocks | 1.1+ | Refactor without destroy/recreate |
|
||||
| `optional()` with defaults | 1.3+ | Optional object attributes |
|
||||
| Native testing | 1.6+ | Built-in test framework |
|
||||
| Mock providers | 1.7+ | Cost-free unit testing |
|
||||
| Provider functions | 1.8+ | Provider-specific data transformation |
|
||||
| Cross-variable validation | 1.9+ | Validate relationships between variables |
|
||||
| Write-only arguments | 1.11+ | Secrets never stored in state |
|
||||
|
||||
### Quick Examples
|
||||
|
||||
```hcl
|
||||
# try() - Safe fallbacks (0.13+)
|
||||
output "sg_id" {
|
||||
value = try(aws_security_group.this[0].id, "")
|
||||
}
|
||||
|
||||
# optional() - Optional attributes with defaults (1.3+)
|
||||
variable "config" {
|
||||
type = object({
|
||||
name = string
|
||||
timeout = optional(number, 300) # Default: 300
|
||||
})
|
||||
}
|
||||
|
||||
# Cross-variable validation (1.9+)
|
||||
variable "environment" { type = string }
|
||||
variable "backup_days" {
|
||||
type = number
|
||||
validation {
|
||||
condition = var.environment == "prod" ? var.backup_days >= 7 : true
|
||||
error_message = "Production requires backup_days >= 7"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**For complete patterns and examples, see:** [Code Patterns: Modern Terraform Features](references/code-patterns.md#modern-terraform-features-10)
|
||||
|
||||
## Version-Specific Guidance
|
||||
|
||||
### Terraform 1.0-1.5
|
||||
- Use Terratest for testing
|
||||
- No native testing framework available
|
||||
- Focus on static analysis and plan validation
|
||||
|
||||
### Terraform 1.6+ / OpenTofu 1.6+
|
||||
- **New:** Native `terraform test` / `tofu test` command
|
||||
- Consider migrating from external frameworks for simple tests
|
||||
- Keep Terratest only for complex integration tests
|
||||
|
||||
### Terraform 1.7+ / OpenTofu 1.7+
|
||||
- **New:** Mock providers for unit testing
|
||||
- Reduce cost by mocking external dependencies
|
||||
- Use real integration tests for final validation
|
||||
|
||||
### Terraform vs OpenTofu
|
||||
|
||||
Both are fully supported by this skill. For licensing, governance, and feature comparison, see [Quick Reference: Terraform vs OpenTofu](references/quick-reference.md#terraform-vs-opentofu-comparison).
|
||||
|
||||
## Detailed Guides
|
||||
|
||||
This skill uses **progressive disclosure** - essential information is in this main file, detailed guides are available when needed:
|
||||
|
||||
📚 **Reference Files:**
|
||||
- **[Testing Frameworks](references/testing-frameworks.md)** - In-depth guide to static analysis, native tests, and Terratest
|
||||
- **[Module Patterns](references/module-patterns.md)** - Module structure, variable/output best practices, ✅ DO vs ❌ DON'T patterns
|
||||
- **[CI/CD Workflows](references/ci-cd-workflows.md)** - GitHub Actions, GitLab CI templates, cost optimization, automated cleanup
|
||||
- **[Security & Compliance](references/security-compliance.md)** - Trivy/Checkov integration, secrets management, compliance testing
|
||||
- **[Quick Reference](references/quick-reference.md)** - Command cheat sheets, decision flowcharts, troubleshooting guide
|
||||
|
||||
**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.
|
||||
|
||||
## License
|
||||
|
||||
This skill is licensed under the **Apache License 2.0**. See the LICENSE file for full terms.
|
||||
|
||||
**Copyright © 2026 Anton Babenko**
|
||||
Reference in New Issue
Block a user