Best for
- Use when: user wants to design Terraform modules, manage state backends, review Terraform security, implement multi-region deployments, or follow IaC best practices.
alirezarezvani/claude-skills/engineering/terraform-patterns/skills/terraform-patterns/SKILL.md
Terraform infrastructure-as-code agent skill and plugin for Claude Code, Codex, Gemini CLI, Cursor, OpenClaw. Covers module design patterns, state management strategies, provider configuration, security hardening, policy-as-code with Sentinel/OPA, and CI/CD plan/apply workflows. Use when: user wants to design Terraform modules, manage state backends, review Terraform security, implement multi-region deployments, or follow IaC best practices.
Decision brief
Predictable infrastructure. Secure state. Modules that compose. No drift.
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Declared | Source record | Install path and trigger |
| Claude Code | Declared | Source record | Install path and trigger |
| Cursor | Declared | Source record | Install path and trigger |
| Gemini CLI | Declared | Source record | Install path and trigger |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/alirezarezvani/claude-skills --skill "engineering/terraform-patterns/skills/terraform-patterns"Inspect the Agent Skill "terraform-patterns" from https://github.com/alirezarezvani/claude-skills/blob/aa8d778811a557a2c28ccadda4cf3d0bd028a4cc/engineering/terraform-patterns/skills/terraform-patterns/SKILL.md at commit aa8d778811a557a2c28ccadda4cf3d0bd028a4cc. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
1. Analyze current state - Read all .tf files in the target directory - Identify module structure (flat vs nested) - Count resources, data sources, variables, outputs - Check naming conventions
1. Analyze current state - Read all .tf files in the target directory - Identify module structure (flat vs nested) - Count resources, data sources, variables, outputs - Check naming conventions
Review the “PR Workflow” section in the pinned source before continuing.
Review the “terraform import Workflow” section in the pinned source before continuing.
Review the “Review generated.tf, then move resources into proper files” section in the pinned source before continuing.
Permission review
The documentation asks the agent to read local files, directories, or repositories.
Read all `.tf` files in the target directoryThe documentation asks the agent to run terminal commands or scripts.
python3 scripts/tf_module_analyzer.py ./terraformThe documentation asks the agent to run terminal commands or scripts.
python3 scripts/tf_security_scanner.py ./terraformThe documentation asks the agent to read local files, directories, or repositories.
# Scan a Terraform directoryThe documentation includes network, browsing, or remote request actions.
git clone https://github.com/alirezarezvani/claude-skills.gitEvidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 90/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 23,781 | Source | Repository attention, not individual Skill quality |
| Compatibility | 4 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Predictable infrastructure. Secure state. Modules that compose. No drift.
Opinionated Terraform workflow that turns sprawling HCL into well-structured, secure, production-grade infrastructure code. Covers module design, state management, provider patterns, security hardening, and CI/CD integration.
Not a Terraform tutorial — a set of concrete decisions about how to write infrastructure code that doesn't break at 3 AM.
| Command | What it does |
|---|---|
/terraform:review | Analyze Terraform code for anti-patterns, security issues, and structure problems |
/terraform:module | Design or refactor a Terraform module with proper inputs, outputs, and composition |
/terraform:security | Audit Terraform code for security vulnerabilities, secrets exposure, and IAM misconfigurations |
Recognize these patterns from the user:
.tf files, HCL, Terraform modules, state management, provider configuration, infrastructure-as-codeIf the user has .tf files or wants to provision infrastructure with Terraform → this skill applies.
/terraform:review — Terraform Code ReviewAnalyze current state
.tf files in the target directoryApply review checklist
MODULE STRUCTURE
├── Variables have descriptions and type constraints
├── Outputs expose only what consumers need
├── Resources use consistent naming: {provider}_{type}_{purpose}
├── Locals used for computed values and DRY expressions
└── No hardcoded values — everything parameterized or in locals
STATE & BACKEND
├── Remote backend configured (S3, GCS, Azure Blob, Terraform Cloud)
├── State locking enabled (DynamoDB for S3, native for others)
├── State encryption at rest enabled
├── No secrets stored in state (or state access is restricted)
└── Workspaces or directory isolation for environments
PROVIDERS
├── Version constraints use pessimistic operator: ~> 5.0
├── Required providers block in terraform {} block
├── Provider aliases for multi-region or multi-account
└── No provider configuration in child modules
SECURITY
├── No hardcoded secrets, keys, or passwords
├── IAM follows least-privilege principle
├── Encryption enabled for storage, databases, secrets
├── Security groups are not overly permissive (no 0.0.0.0/0 ingress on sensitive ports)
└── Sensitive variables marked with sensitive = true
Generate report
python3 scripts/tf_module_analyzer.py ./terraform
Run security scan
python3 scripts/tf_security_scanner.py ./terraform
/terraform:module — Module DesignIdentify module scope
Apply module design checklist
STRUCTURE
├── main.tf — Primary resources
├── variables.tf — All input variables with descriptions and types
├── outputs.tf — All outputs with descriptions
├── versions.tf — terraform {} block with required_providers
├── locals.tf — Computed values and naming conventions
├── data.tf — Data sources (if any)
└── README.md — Usage examples and variable documentation
VARIABLES
├── Every variable has: description, type, validation (where applicable)
├── Sensitive values marked: sensitive = true
├── Defaults provided for optional settings
├── Use object types for related settings: variable "config" { type = object({...}) }
└── Validate with: validation { condition = ... }
OUTPUTS
├── Output IDs, ARNs, endpoints — things consumers need
├── Include description on every output
├── Mark sensitive outputs: sensitive = true
└── Don't output entire resources — only specific attributes
COMPOSITION
├── Root module calls child modules
├── Child modules never call other child modules
├── Pass values explicitly — no hidden data source lookups in child modules
├── Provider configuration only in root module
└── Use module "name" { source = "./modules/name" }
Generate module scaffold
/terraform:security — Security AuditCode-level audit
| Check | Severity | Fix |
|---|---|---|
Hardcoded secrets in .tf files | Critical | Use variables with sensitive = true or vault |
IAM policy with * actions | Critical | Scope to specific actions and resources |
| Security group with 0.0.0.0/0 on port 22/3389 | Critical | Restrict to known CIDR blocks or use SSM/bastion |
| S3 bucket without encryption | High | Add server_side_encryption_configuration block |
| S3 bucket with public access | High | Add aws_s3_bucket_public_access_block |
| RDS without encryption | High | Set storage_encrypted = true |
| RDS publicly accessible | High | Set publicly_accessible = false |
| CloudTrail not enabled | Medium | Add aws_cloudtrail resource |
Missing prevent_destroy on stateful resources | Medium | Add lifecycle { prevent_destroy = true } |
Variables without sensitive = true for secrets | Medium | Add sensitive = true to secret variables |
State security audit
| Check | Severity | Fix |
|---|---|---|
| Local state file | Critical | Migrate to remote backend with encryption |
| Remote state without encryption | High | Enable encryption on backend (SSE-S3, KMS) |
| No state locking | High | Enable DynamoDB for S3, native for TF Cloud |
| State accessible to all team members | Medium | Restrict via IAM policies or TF Cloud teams |
Generate security report
python3 scripts/tf_security_scanner.py ./terraform
python3 scripts/tf_security_scanner.py ./terraform --output json
scripts/tf_module_analyzer.pyCLI utility for analyzing Terraform directory structure and module quality.
Features:
Usage:
# Analyze a Terraform directory
python3 scripts/tf_module_analyzer.py ./terraform
# JSON output
python3 scripts/tf_module_analyzer.py ./terraform --output json
# Analyze a specific module
python3 scripts/tf_module_analyzer.py ./modules/vpc
scripts/tf_security_scanner.pyCLI utility for scanning .tf files for common security issues.
Features:
Usage:
# Scan a Terraform directory
python3 scripts/tf_security_scanner.py ./terraform
# JSON output
python3 scripts/tf_security_scanner.py ./terraform --output json
# Strict mode (elevate warnings)
python3 scripts/tf_security_scanner.py ./terraform --strict
infrastructure/
├── main.tf # All resources
├── variables.tf # All inputs
├── outputs.tf # All outputs
├── versions.tf # Provider requirements
├── terraform.tfvars # Environment values (not committed)
└── backend.tf # Remote state configuration
Best for: Single application, < 20 resources, one team owns everything.
infrastructure/
├── environments/
│ ├── dev/
│ │ ├── main.tf # Calls modules with dev params
│ │ ├── backend.tf # Dev state backend
│ │ └── terraform.tfvars
│ ├── staging/
│ │ └── ...
│ └── prod/
│ └── ...
├── modules/
│ ├── networking/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ ├── compute/
│ │ └── ...
│ └── database/
│ └── ...
└── versions.tf
Best for: Multiple environments, shared infrastructure patterns, team collaboration.
infrastructure/
├── terragrunt.hcl # Root config
├── modules/ # Reusable modules
│ ├── vpc/
│ ├── eks/
│ └── rds/
├── dev/
│ ├── terragrunt.hcl # Dev overrides
│ ├── vpc/
│ │ └── terragrunt.hcl # Module invocation
│ └── eks/
│ └── terragrunt.hcl
└── prod/
├── terragrunt.hcl
└── ...
Best for: Large-scale, many environments, DRY configuration, team-level isolation.
terraform {
required_version = ">= 1.5.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0" # Allow 5.x, block 6.0
}
random = {
source = "hashicorp/random"
version = "~> 3.5"
}
}
}
provider "aws" {
region = "us-east-1"
}
provider "aws" {
alias = "west"
region = "us-west-2"
}
resource "aws_s3_bucket" "primary" {
bucket = "my-app-primary"
}
resource "aws_s3_bucket" "replica" {
provider = aws.west
bucket = "my-app-replica"
}
provider "aws" {
alias = "production"
region = "us-east-1"
assume_role {
role_arn = "arn:aws:iam::PROD_ACCOUNT_ID:role/TerraformRole"
}
}
Single developer, small project?
├── Yes → Local state (but migrate to remote ASAP)
└── No
├── Using Terraform Cloud/Enterprise?
│ └── Yes → TF Cloud native backend (built-in locking, encryption, RBAC)
└── No
├── AWS?
│ └── S3 + DynamoDB (encryption, locking, versioning)
├── GCP?
│ └── GCS bucket (native locking, encryption)
├── Azure?
│ └── Azure Blob Storage (native locking, encryption)
└── Other?
└── Consul or PostgreSQL backend
Environment isolation strategy:
├── Separate state files per environment (recommended)
│ ├── Option A: Separate directories (dev/, staging/, prod/)
│ └── Option B: Terraform workspaces (simpler but less isolation)
└── Single state file for all environments (never do this)
# .github/workflows/terraform.yml
name: Terraform
on:
pull_request:
paths: ['terraform/**']
push:
branches: [main]
paths: ['terraform/**']
jobs:
plan:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- run: terraform init
- run: terraform validate
- run: terraform plan -out=tfplan
- run: terraform show -json tfplan > plan.json
# Post plan as PR comment
apply:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
environment: production
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- run: terraform init
- run: terraform apply -auto-approve
# Run on schedule to detect drift
name: Drift Detection
on:
schedule:
- cron: '0 6 * * 1-5' # Weekdays at 6 AM
jobs:
detect:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- run: terraform init
- run: |
terraform plan -detailed-exitcode -out=drift.tfplan 2>&1 | tee drift.log
EXIT_CODE=$?
if [ $EXIT_CODE -eq 2 ]; then
echo "DRIFT DETECTED — review drift.log"
# Send alert (Slack, PagerDuty, etc.)
fi
Flag these without being asked:
version = "~> X.0" to prevent breaking upgrades.sensitive = true, or integrate Vault/SSM."Action": "*" → Scope to specific actions. No wildcard actions in production.prevent_destroy on databases/storage → Add lifecycle block to prevent accidental deletion.When a single root module must provision across AWS, Azure, and GCP simultaneously.
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.0"
}
google = {
source = "hashicorp/google"
version = "~> 5.0"
}
}
}
provider "aws" {
region = var.aws_region
}
provider "azurerm" {
features {}
subscription_id = var.azure_subscription_id
}
provider "google" {
project = var.gcp_project_id
region = var.gcp_region
}
variable "environment" {
description = "Environment name used across all providers"
type = string
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "Must be dev, staging, or prod."
}
}
locals {
common_tags = {
environment = var.environment
managed_by = "terraform"
project = var.project_name
}
}
OpenTofu is an open-source fork of Terraform maintained by the Linux Foundation under the MPL 2.0 license.
# 1. Install OpenTofu
brew install opentofu # macOS
snap install --classic tofu # Linux
# 2. Replace the binary — state files are compatible
tofu init # Re-initializes with OpenTofu
tofu plan # Identical plan output
tofu apply # Same apply workflow
| Terraform (1.6+) | OpenTofu | |
|---|---|---|
| License | BSL 1.1 (source-available) | MPL 2.0 (open-source) |
| Commercial use | Restricted for competing products | Unrestricted |
| Community governance | HashiCorp | Linux Foundation |
OpenTofu tracks Terraform 1.6.x features. Key additions unique to OpenTofu:
tofu init -encryption)Infracost estimates cloud costs from Terraform code before resources are provisioned.
# Show cost breakdown for current code
infracost breakdown --path .
# Compare cost difference between current branch and main
infracost diff --path . --compare-to infracost-base.json
# .github/workflows/infracost.yml
name: Infracost
on: [pull_request]
jobs:
cost:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: infracost/actions/setup@v3
with:
api-key: ${{ secrets.INFRACOST_API_KEY }}
- run: infracost breakdown --path ./terraform --format json --out-file /tmp/infracost.json
- run: infracost comment github --path /tmp/infracost.json --repo $GITHUB_REPOSITORY --pull-request ${{ github.event.pull_request.number }} --github-token ${{ secrets.GITHUB_TOKEN }} --behavior update
# infracost.yml — policy file
version: 2.9.0
policies:
- path: "*"
max_monthly_cost: "5000" # Fail PR if estimated cost exceeds $5,000/month
max_cost_increase: "500" # Fail PR if cost increase exceeds $500/month
Bring manually-created resources under Terraform management.
# 1. Write the resource block first (empty body is fine)
# main.tf:
# resource "aws_s3_bucket" "legacy" {}
# 2. Import the resource into state
terraform import aws_s3_bucket.legacy my-existing-bucket-name
# 3. Run plan to see attribute diff
terraform plan
# 4. Fill in the resource block until plan shows no changes
# Generate HCL for imported resources
terraform plan -generate-config-out=generated.tf
# Review generated.tf, then move resources into proper files
terraform plan immediately and resolve every diff.terraform state mv to rename or reorganize. Use terraform state rm to remove without destroying. Always back up state before manipulation: terraform state pull > backup.tfstate.Terragrunt is a thin wrapper around Terraform that provides DRY configuration for multi-environment setups.
# terragrunt.hcl (root)
remote_state {
backend = "s3"
generate = {
path = "backend.tf"
if_exists = "overwrite_terragrunt"
}
config = {
bucket = "my-org-terraform-state"
key = "${path_relative_to_include()}/terraform.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "terraform-locks"
}
}
# prod/vpc/terragrunt.hcl
include "root" {
path = find_in_parent_folders()
}
terraform {
source = "../../modules/vpc"
}
inputs = {
environment = "prod"
cidr_block = "10.0.0.0/16"
}
# prod/eks/terragrunt.hcl
dependency "vpc" {
config_path = "../vpc"
}
inputs = {
vpc_id = dependency.vpc.outputs.vpc_id
subnet_ids = dependency.vpc.outputs.private_subnet_ids
}
git clone https://github.com/alirezarezvani/claude-skills.git
cp -r claude-skills/engineering/terraform-patterns ~/.claude/skills/
./scripts/convert.sh --skill terraform-patterns --tool codex|gemini|cursor|windsurf|openclaw
clawhub install terraform-patterns
Alternatives
alirezarezvani/claude-skills
Helm chart development agent skill and plugin for Claude Code, Codex, Gemini CLI, Cursor, OpenClaw — chart scaffolding, values design, template patterns, dependency management, security hardening, and chart testing. Use when: user wants to create or improve Helm charts, design values.yaml files, implement template helpers, audit chart security (RBAC, network policies, pod security), manage subcharts, or run helm lint/test.
PramodDutta/qaskills
Identify and log user experience friction points including excessive clicks, confusing navigation, slow interactions, and workflow bottlenecks through automated heuristic analysis
alirezarezvani/claude-skills
Use when designing or revisiting product pricing — selecting a pricing model (subscription seat-based, usage-based, value-based, freemium, or hybrid), running Van Westendorp Price Sensitivity Meter analysis on WTP survey data, or designing Good/Better/Best packaging tiers. Recommends a model and a price range with trade-offs, never a single number. For Commercial leads, Product Marketing, and CMOs at the pricing-design moment — not deal-by-deal discounting, not brand positioning.
alirezarezvani/claude-skills
Use when planning and synthesizing product/user research as a method-and-repository discipline — selecting the right method for the goal (generative interviews vs usability test vs concept test vs validation), computing method-based saturation/sample size with an explicit confidence level, or synthesizing coded observations into insights while flagging single-source anecdotes. Never fabricates user insight; an insight requires recurrence across independent participants. Distinct from product-tea