terraform-patterns

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Terraform Patterns

Terraform 设计模式

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.

可预测的基础设施、安全的状态、可组合的模块、无配置漂移。
一套具有明确规范的Terraform工作流,可将零散的HCL代码转化为结构清晰、安全可靠的生产级基础设施代码。涵盖模块设计、状态管理、Provider模式、安全加固以及CI/CD集成。
这不是Terraform教程——而是关于如何编写不会在凌晨3点崩溃的基础设施代码的一系列具体决策。

Slash Commands

斜杠命令

CommandWhat 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

命令功能
/terraform:review
分析Terraform代码中的反模式、安全问题和结构缺陷
/terraform:module
设计或重构Terraform模块,包含合理的输入、输出与组合逻辑
/terraform:security
审计Terraform代码中的安全漏洞、密钥泄露和IAM配置错误

When This Skill Activates

技能触发场景

Recognize these patterns from the user:
  • "Review this Terraform code"
  • "Design a Terraform module for..."
  • "My Terraform state is..."
  • "Set up remote state backend"
  • "Multi-region Terraform deployment"
  • "Terraform security review"
  • "Module structure best practices"
  • "Terraform CI/CD pipeline"
  • Any request involving:
    .tf
    files, HCL, Terraform modules, state management, provider configuration, infrastructure-as-code
If the user has
.tf
files or wants to provision infrastructure with Terraform → this skill applies.

当用户出现以下需求模式时自动激活:
  • "帮我审查这段Terraform代码"
  • "为...设计一个Terraform模块"
  • "我的Terraform状态出现了...问题"
  • "配置远程状态后端"
  • "多区域Terraform部署"
  • "Terraform安全审查"
  • "模块结构最佳实践"
  • "Terraform CI/CD流水线"
  • 任何涉及:
    .tf
    文件、HCL、Terraform模块、状态管理、Provider配置、基础设施即代码的请求
如果用户提供了
.tf
文件,或需要使用Terraform部署基础设施→适用本技能。

Workflow

工作流

/terraform:review
— Terraform Code Review

/terraform:review
— Terraform代码审查

  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
  2. Apply 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
  3. Generate report
    bash
    python3 scripts/tf_module_analyzer.py ./terraform
  4. Run security scan
    bash
    python3 scripts/tf_security_scanner.py ./terraform
  1. 分析当前状态
    • 读取目标目录下所有
      .tf
      文件
    • 识别模块结构(扁平式 vs 嵌套式)
    • 统计资源、数据源、变量、输出的数量
    • 检查命名规范
  2. 应用审查检查清单
    模块结构
    ├── 变量包含描述和类型约束
    ├── 输出仅暴露消费者所需内容
    ├── 资源使用统一命名格式:{provider}_{type}_{purpose}
    ├── 使用Locals存储计算值和实现DRY(Don't Repeat Yourself)表达式
    └── 无硬编码值——所有内容均参数化或存储在Locals中
    
    状态与后端
    ├── 已配置远程后端(S3、GCS、Azure Blob、Terraform Cloud)
    ├── 已启用状态锁定(S3使用DynamoDB,其他服务使用原生锁定)
    ├── 已启用静态状态加密
    ├── 状态中未存储密钥(或状态访问已受限)
    ├── 使用工作区或目录隔离不同环境
    
    Providers
    ├── 版本约束使用保守运算符:~> 5.0
    ├── 在terraform {}块中包含required_providers配置
    ├── 为多区域或多账户配置Provider别名
    └── 子模块中未配置Provider
    
    安全
    ├── 无硬编码密钥、密码或令牌
    ├── IAM遵循最小权限原则
    ├── 存储、数据库、密钥已启用加密
    ├── 安全组未过度开放(敏感端口未允许0.0.0.0/0 ingress访问)
    ├── 敏感变量已标记sensitive = true
  3. 生成报告
    bash
    python3 scripts/tf_module_analyzer.py ./terraform
  4. 运行安全扫描
    bash
    python3 scripts/tf_security_scanner.py ./terraform

/terraform:module
— Module Design

/terraform:module
— 模块设计

  1. Identify module scope
    • Single responsibility: one module = one logical grouping
    • Determine inputs (variables), outputs, and resource boundaries
    • Decide: flat module (single directory) vs nested (calling child modules)
  2. 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" }
  3. Generate module scaffold
    • Output file structure with boilerplate
    • Include variable validation blocks
    • Add lifecycle rules where appropriate
  1. 确定模块范围
    • 单一职责:一个模块对应一个逻辑分组
    • 确定输入(变量)、输出和资源边界
    • 选择:扁平模块(单一目录)vs 嵌套模块(调用子模块)
  2. 应用模块设计检查清单
    结构
    ├── main.tf        — 核心资源定义
    ├── variables.tf   — 所有输入变量,包含描述和类型
    ├── outputs.tf     — 所有输出,包含描述
    ├── versions.tf    — terraform {}块,包含required_providers
    ├── locals.tf      — 计算值和命名规范
    ├── data.tf        — 数据源(如有)
    └── README.md      — 使用示例和变量文档
    
    变量
    ├── 每个变量均包含:描述、类型、验证逻辑(如适用)
    ├── 敏感值已标记:sensitive = true
    ├── 可选配置提供默认值
    ├── 使用对象类型管理相关配置:variable "config" { type = object({...}) }
    └── 使用validation块进行校验:validation { condition = ... }
    
    输出
    ├── 输出ID、ARN、端点等消费者所需内容
    ├── 每个输出均包含描述
    ├── 敏感输出已标记:sensitive = true
    └── 不输出整个资源——仅输出特定属性
    
    组合
    ├── 根模块调用子模块
    ├── 子模块不调用其他子模块
    ├── 显式传递值——子模块中无隐藏的数据源查询
    ├── Provider配置仅在根模块中定义
    └使用module "name" { source = "./modules/name" }调用模块
  3. 生成模块脚手架
    • 输出包含样板代码的文件结构
    • 包含变量验证块
    • 按需添加生命周期规则

/terraform:security
— Security Audit

/terraform:security
— 安全审计

  1. Code-level audit
    CheckSeverityFix
    Hardcoded secrets in
    .tf
    files
    CriticalUse variables with sensitive = true or vault
    IAM policy with
    *
    actions
    CriticalScope to specific actions and resources
    Security group with 0.0.0.0/0 on port 22/3389CriticalRestrict to known CIDR blocks or use SSM/bastion
    S3 bucket without encryptionHighAdd
    server_side_encryption_configuration
    block
    S3 bucket with public accessHighAdd
    aws_s3_bucket_public_access_block
    RDS without encryptionHighSet
    storage_encrypted = true
    RDS publicly accessibleHighSet
    publicly_accessible = false
    CloudTrail not enabledMediumAdd
    aws_cloudtrail
    resource
    Missing
    prevent_destroy
    on stateful resources
    MediumAdd
    lifecycle { prevent_destroy = true }
    Variables without
    sensitive = true
    for secrets
    MediumAdd
    sensitive = true
    to secret variables
  2. State security audit
    CheckSeverityFix
    Local state fileCriticalMigrate to remote backend with encryption
    Remote state without encryptionHighEnable encryption on backend (SSE-S3, KMS)
    No state lockingHighEnable DynamoDB for S3, native for TF Cloud
    State accessible to all team membersMediumRestrict via IAM policies or TF Cloud teams
  3. Generate security report
    bash
    python3 scripts/tf_security_scanner.py ./terraform
    python3 scripts/tf_security_scanner.py ./terraform --output json

  1. 代码级审计
    检查项严重程度修复方案
    .tf
    文件中存在硬编码密钥
    严重使用标记sensitive = true的变量,或集成Vault
    IAM策略包含
    *
    操作
    严重限定为具体操作和资源
    安全组在22/3389端口允许0.0.0.0/0访问严重限制为已知CIDR块,或使用SSM/堡垒机
    S3存储桶未启用加密添加
    server_side_encryption_configuration
    S3存储桶允许公共访问添加
    aws_s3_bucket_public_access_block
    配置
    RDS未启用加密设置
    storage_encrypted = true
    RDS可公开访问设置
    publicly_accessible = false
    未启用CloudTrail添加
    aws_cloudtrail
    资源
    有状态资源未配置
    prevent_destroy
    添加
    lifecycle { prevent_destroy = true }
    敏感变量未标记
    sensitive = true
    为敏感变量添加
    sensitive = true
  2. 状态安全审计
    检查项严重程度修复方案
    使用本地状态文件严重迁移到带加密的远程后端
    远程状态未加密在后端启用加密(SSE-S3、KMS)
    未启用状态锁定为S3后端启用DynamoDB,或使用Terraform Cloud原生锁定
    所有团队成员均可访问状态通过IAM策略或Terraform Cloud团队功能限制访问
  3. 生成安全报告
    bash
    python3 scripts/tf_security_scanner.py ./terraform
    python3 scripts/tf_security_scanner.py ./terraform --output json

Tooling

工具集

scripts/tf_module_analyzer.py

scripts/tf_module_analyzer.py

CLI utility for analyzing Terraform directory structure and module quality.
Features:
  • Resource and data source counting
  • Variable and output analysis (missing descriptions, types, validation)
  • Naming convention checks
  • Module composition detection
  • File structure validation
  • JSON and text output
Usage:
bash
undefined
用于分析Terraform目录结构和模块质量的CLI工具。
特性:
  • 资源和数据源统计
  • 变量和输出分析(缺失描述、类型、验证)
  • 命名规范检查
  • 模块组合检测
  • 文件结构验证
  • JSON和文本输出
使用方式:
bash
undefined

Analyze a Terraform directory

分析Terraform目录

python3 scripts/tf_module_analyzer.py ./terraform
python3 scripts/tf_module_analyzer.py ./terraform

JSON output

输出JSON格式结果

python3 scripts/tf_module_analyzer.py ./terraform --output json
python3 scripts/tf_module_analyzer.py ./terraform --output json

Analyze a specific module

分析特定模块

python3 scripts/tf_module_analyzer.py ./modules/vpc
undefined
python3 scripts/tf_module_analyzer.py ./modules/vpc
undefined

scripts/tf_security_scanner.py

scripts/tf_security_scanner.py

CLI utility for scanning
.tf
files for common security issues.
Features:
  • Hardcoded secret detection (AWS keys, passwords, tokens)
  • Overly permissive IAM policy detection
  • Open security group detection (0.0.0.0/0 on sensitive ports)
  • Missing encryption checks (S3, RDS, EBS)
  • Public access detection (S3, RDS, EC2)
  • Sensitive variable audit
  • JSON and text output
Usage:
bash
undefined
用于扫描
.tf
文件中常见安全问题的CLI工具。
特性:
  • 硬编码密钥检测(AWS密钥、密码、令牌)
  • 过度宽松的IAM策略检测
  • 开放安全组检测(敏感端口允许0.0.0.0/0访问)
  • 缺失加密检查(S3、RDS、EBS)
  • 公共访问检测(S3、RDS、EC2)
  • 敏感变量审计
  • JSON和文本输出
使用方式:
bash
undefined

Scan a Terraform directory

扫描Terraform目录

python3 scripts/tf_security_scanner.py ./terraform
python3 scripts/tf_security_scanner.py ./terraform

JSON output

输出JSON格式结果

python3 scripts/tf_security_scanner.py ./terraform --output json
python3 scripts/tf_security_scanner.py ./terraform --output json

Strict mode (elevate warnings)

严格模式(提升警告级别)

python3 scripts/tf_security_scanner.py ./terraform --strict

---
python3 scripts/tf_security_scanner.py ./terraform --strict

---

Module Design Patterns

模块设计模式

Pattern 1: Flat Module (Small/Medium Projects)

模式1:扁平模块(中小型项目)

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/
├── main.tf          # 所有资源
├── variables.tf     # 所有输入
├── outputs.tf       # 所有输出
├── versions.tf      # Provider依赖
├── terraform.tfvars # 环境变量(不提交到版本库)
└── backend.tf       # 远程状态配置
最佳适用场景:单一应用、资源数<20、单团队负责所有内容。

Pattern 2: Nested Modules (Medium/Large Projects)

模式2:嵌套模块(中大型项目)

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/
├── environments/
│   ├── dev/
│   │   ├── main.tf          # 使用dev参数调用模块
│   │   ├── backend.tf       # Dev环境状态后端
│   │   └── terraform.tfvars
│   ├── staging/
│   │   └── ...
│   └── prod/
│       └── ...
├── modules/
│   ├── networking/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   └── outputs.tf
│   ├── compute/
│   │   └── ...
│   └── database/
│       └── ...
└── versions.tf
最佳适用场景:多环境、共享基础设施模式、团队协作。

Pattern 3: Mono-Repo with Terragrunt

模式3:结合Terragrunt的单体仓库

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.

infrastructure/
├── terragrunt.hcl           # 根配置
├── modules/                  # 可复用模块
│   ├── vpc/
│   ├── eks/
│   └── rds/
├── dev/
│   ├── terragrunt.hcl       # Dev环境覆盖配置
│   ├── vpc/
│   │   └── terragrunt.hcl   # 模块调用配置
│   └── eks/
│       └── terragrunt.hcl
└── prod/
    ├── terragrunt.hcl
    └── ...
最佳适用场景:大规模、多环境、DRY配置、团队级隔离。

Provider Configuration Patterns

Provider配置模式

Version Pinning

版本固定

hcl
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"
    }
  }
}
hcl
terraform {
  required_version = ">= 1.5.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"    # 允许5.x版本,禁止6.0+
    }
    random = {
      source  = "hashicorp/random"
      version = "~> 3.5"
    }
  }
}

Multi-Region with Aliases

多区域别名配置

hcl
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"
}
hcl
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"
}

Multi-Account with Assume Role

多账户角色切换配置

hcl
provider "aws" {
  alias  = "production"
  region = "us-east-1"

  assume_role {
    role_arn = "arn:aws:iam::PROD_ACCOUNT_ID:role/TerraformRole"
  }
}

hcl
provider "aws" {
  alias  = "production"
  region = "us-east-1"

  assume_role {
    role_arn = "arn:aws:iam::PROD_ACCOUNT_ID:role/TerraformRole"
  }
}

State Management Decision Tree

状态管理决策树

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)

单开发者、小型项目?
├── 是 → 使用本地状态(但尽快迁移到远程后端)
└── 否
    ├── 使用Terraform Cloud/Enterprise?
    │   └── 是 → 使用Terraform Cloud原生后端(内置锁定、加密、RBAC)
    └── 否
        ├── AWS环境?
        │   └── 是 → S3 + DynamoDB(加密、锁定、版本控制)
        ├── GCP环境?
        │   └── 是 → GCS存储桶(原生锁定、加密)
        ├── Azure环境?
        │   └── 是 → Azure Blob存储(原生锁定、加密)
        └── 其他环境?
            └── 使用Consul或PostgreSQL后端

环境隔离策略:
├── 每个环境使用独立状态文件(推荐)
│   ├── 选项A:独立目录(dev/、staging/、prod/)
│   └── 选项B:Terraform工作区(更简单但隔离性较弱)
└── 所有环境共用单个状态文件(绝对禁止)

CI/CD Integration Patterns

CI/CD集成模式

GitHub Actions Plan/Apply

GitHub Actions计划/执行流程

yaml
undefined
yaml
undefined

.github/workflows/terraform.yml

.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
undefined
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 # 将计划结果作为PR评论发布
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
undefined

Drift Detection

配置漂移检测

yaml
undefined
yaml
undefined

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

---
name: Drift Detection on: schedule: - cron: '0 6 * * 1-5' # 工作日早6点
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.log" # 发送告警(Slack、PagerDuty等) fi

---

Proactive Triggers

主动触发提示

Flag these without being asked:
  • No remote backend configured → Migrate to S3/GCS/Azure Blob with locking and encryption.
  • Provider without version constraint → Add
    version = "~> X.0"
    to prevent breaking upgrades.
  • Hardcoded secrets in .tf files → Use variables with
    sensitive = true
    , or integrate Vault/SSM.
  • IAM policy with
    "Action": "*"
    → Scope to specific actions. No wildcard actions in production.
  • Security group open to 0.0.0.0/0 on SSH/RDP → Restrict to bastion CIDR or use SSM Session Manager.
  • No state locking → Enable DynamoDB table for S3 backend, or use TF Cloud.
  • Resources without tags → Add default_tags in provider block. Tags are mandatory for cost tracking.
  • Missing
    prevent_destroy
    on databases/storage
    → Add lifecycle block to prevent accidental deletion.

无需用户询问,自动标记以下问题:
  • 未配置远程后端 → 迁移到带锁定和加密的S3/GCS/Azure Blob后端。
  • Provider未设置版本约束 → 添加
    version = "~> X.0"
    以避免破坏性升级。
  • .tf
    文件中存在硬编码密钥 → 使用标记
    sensitive = true
    的变量,或集成Vault/SSM。
  • IAM策略包含
    "Action": "*"
    → 限定为具体操作。生产环境禁止使用通配符操作。
  • SSH/RDP端口安全组开放0.0.0.0/0访问 → 限制为堡垒机CIDR或使用SSM会话管理器。
  • 未启用状态锁定 → 为S3后端启用DynamoDB表,或使用Terraform Cloud。
  • 资源未添加标签 → 在Provider块中添加default_tags。标签是成本追踪的必填项。
  • 数据库/存储未配置
    prevent_destroy
    → 添加生命周期块以防止意外删除。

Multi-Cloud Provider Configuration

多云Provider配置

When a single root module must provision across AWS, Azure, and GCP simultaneously.
当单个根模块需要同时在AWS、Azure和GCP上部署资源时的配置方式。

Provider Aliasing Pattern

Provider别名模式

hcl
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
}
hcl
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
}

Shared Variables Across Providers

跨Provider共享变量

hcl
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
  }
}
hcl
variable "environment" {
  description = "所有Provider共用的环境名称"
  type        = string
  validation {
    condition     = contains(["dev", "staging", "prod"], var.environment)
    error_message = "必须是dev、staging或prod。"
  }
}

locals {
  common_tags = {
    environment = var.environment
    managed_by  = "terraform"
    project     = var.project_name
  }
}

When to Use Multi-Cloud

何时使用多云配置

  • Yes: Regulatory requirements mandate data residency across providers, or the org has existing workloads on multiple clouds.
  • No: "Avoiding vendor lock-in" alone is not sufficient justification. Multi-cloud doubles operational complexity. Prefer single-cloud unless there is a concrete business requirement.

  • 适用场景:法规要求数据驻留于多个云服务商,或企业已有多云环境下的工作负载。
  • 不适用场景:仅为“避免厂商锁定”不足以成为理由。多云会使运维复杂度翻倍。除非有明确的业务需求,否则优先选择单云。

OpenTofu Compatibility

OpenTofu兼容性

OpenTofu is an open-source fork of Terraform maintained by the Linux Foundation under the MPL 2.0 license.
OpenTofu是Terraform的开源分支,由Linux基金会维护,使用MPL 2.0许可证。

Migration from Terraform to OpenTofu

从Terraform迁移到OpenTofu

bash
undefined
bash
undefined

1. Install OpenTofu

1. 安装OpenTofu

brew install opentofu # macOS snap install --classic tofu # Linux
brew install opentofu # macOS snap install --classic tofu # Linux

2. Replace the binary — state files are compatible

2. 替换二进制文件——状态文件完全兼容

tofu init # Re-initializes with OpenTofu tofu plan # Identical plan output tofu apply # Same apply workflow
undefined
tofu init # 使用OpenTofu重新初始化 tofu plan # 生成与Terraform一致的执行计划 tofu apply # 执行与Terraform相同的部署流程
undefined

License Considerations

许可证对比

Terraform (1.6+)OpenTofu
LicenseBSL 1.1 (source-available)MPL 2.0 (open-source)
Commercial useRestricted for competing productsUnrestricted
Community governanceHashiCorpLinux Foundation
Terraform (1.6+)OpenTofu
许可证BSL 1.1(源码可用)MPL 2.0(开源)
商业使用竞品使用受限无限制
社区治理HashiCorpLinux基金会

Feature Parity

功能对等性

OpenTofu tracks Terraform 1.6.x features. Key additions unique to OpenTofu:
  • Client-side state encryption (
    tofu init -encryption
    )
  • Early variable/locals evaluation
  • Provider-defined functions
OpenTofu跟进Terraform 1.6.x的功能。OpenTofu独有的关键特性:
  • 客户端状态加密(
    tofu init -encryption
  • 变量/Locals提前求值
  • Provider自定义函数

When to Choose OpenTofu

何时选择OpenTofu

  • You need a fully open-source license for your supply chain.
  • You want client-side state encryption without Terraform Cloud.
  • Otherwise, either tool works — the HCL syntax and provider ecosystem are identical.

  • 供应链需要完全开源的许可证。
  • 无需Terraform Cloud即可实现客户端状态加密。
  • 除此之外,两款工具均可使用——HCL语法和Provider生态完全一致。

Infracost Integration

Infracost集成

Infracost estimates cloud costs from Terraform code before resources are provisioned.
Infracost可在资源部署前通过Terraform代码估算云成本。

PR Workflow

PR工作流

bash
undefined
bash
undefined

Show cost breakdown for current code

显示当前代码的成本明细

infracost breakdown --path .
infracost breakdown --path .

Compare cost difference between current branch and main

对比当前分支与main分支的成本差异

infracost diff --path . --compare-to infracost-base.json
undefined
infracost diff --path . --compare-to infracost-base.json
undefined

GitHub Actions Cost Comment

GitHub Actions成本评论

yaml
undefined
yaml
undefined

.github/workflows/infracost.yml

.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
undefined
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
undefined

Budget Thresholds and Cost Policy

预算阈值与成本策略

yaml
undefined
yaml
undefined

infracost.yml — policy file

infracost.yml — 策略文件

version: 0.1 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

---
version: 0.1 policies:
  • path: "*" max_monthly_cost: "5000" # 若估算月成本超过5000美元则拒绝PR max_cost_increase: "500" # 若成本增幅超过500美元/月则拒绝PR

---

Import Existing Infrastructure

导入现有基础设施

Bring manually-created resources under Terraform management.
将手动创建的资源纳入Terraform管理。

terraform import Workflow

terraform导入工作流

bash
undefined
bash
undefined

1. Write the resource block first (empty body is fine)

1. 先编写资源块(空内容即可)

main.tf:

main.tf:

resource "aws_s3_bucket" "legacy" {}

resource "aws_s3_bucket" "legacy" {}

2. Import the resource into state

2. 将资源导入状态

terraform import aws_s3_bucket.legacy my-existing-bucket-name
terraform import aws_s3_bucket.legacy my-existing-bucket-name

3. Run plan to see attribute diff

3. 执行计划查看属性差异

terraform plan
terraform plan

4. Fill in the resource block until plan shows no changes

4. 填充资源块直到计划显示无变更

undefined
undefined

Bulk Import with Config Generation (Terraform 1.5+)

批量导入与配置生成(Terraform 1.5+)

bash
undefined
bash
undefined

Generate HCL for imported resources

为导入的资源生成HCL代码

terraform plan -generate-config-out=generated.tf
terraform plan -generate-config-out=generated.tf

Review generated.tf, then move resources into proper files

审查generated.tf,然后将资源移动到合适的文件中

undefined
undefined

Common Pitfalls

常见陷阱

  • Resource drift after import: The imported resource may have attributes Terraform does not manage. Run
    terraform plan
    immediately and resolve every diff.
  • State manipulation: Use
    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
    .
  • Sensitive defaults: Imported resources may expose secrets in state. Restrict state access and enable encryption.

  • 导入后资源漂移:导入的资源可能包含Terraform未管理的属性。立即执行
    terraform plan
    并解决所有差异。
  • 状态操作:使用
    terraform state mv
    重命名或重组资源。使用
    terraform state rm
    移除资源而不销毁。操作前务必备份状态:
    terraform state pull > backup.tfstate
  • 敏感默认值:导入的资源可能在状态中暴露密钥。限制状态访问并启用加密。

Terragrunt Patterns

Terragrunt模式

Terragrunt is a thin wrapper around Terraform that provides DRY configuration for multi-environment setups.
Terragrunt是Terraform的轻量包装器,为多环境部署提供DRY配置能力。

Root terragrunt.hcl (Shared Config)

根terragrunt.hcl(共享配置)

hcl
undefined
hcl
undefined

terragrunt.hcl (root)

terragrunt.hcl(根目录)

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" } }
undefined
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" } }
undefined

Child terragrunt.hcl (Environment Override)

子terragrunt.hcl(环境覆盖配置)

hcl
undefined
hcl
undefined

prod/vpc/terragrunt.hcl

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" }
undefined
include "root" { path = find_in_parent_folders() }
terraform { source = "../../modules/vpc" }
inputs = { environment = "prod" cidr_block = "10.0.0.0/16" }
undefined

Dependencies Between Modules

模块间依赖

hcl
undefined
hcl
undefined

prod/eks/terragrunt.hcl

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 }
undefined
dependency "vpc" { config_path = "../vpc" }
inputs = { vpc_id = dependency.vpc.outputs.vpc_id subnet_ids = dependency.vpc.outputs.private_subnet_ids }
undefined

When Terragrunt Adds Value

Terragrunt的适用场景

  • Yes: 3+ environments with identical module structure, shared backend config, or cross-module dependencies.
  • No: Single environment, small team, or simple directory-based isolation already works. Terragrunt adds a learning curve and another binary to manage.

  • 适用场景:3个以上环境、模块结构一致、共享后端配置、或存在跨模块依赖。
  • 不适用场景:单环境、小型团队、或简单的目录隔离已满足需求。Terragrunt会增加学习曲线和额外的二进制文件管理成本。

Installation

安装

One-liner (any tool)

一键安装(任意工具)

bash
git clone https://github.com/alirezarezvani/claude-skills.git
cp -r claude-skills/engineering/terraform-patterns ~/.claude/skills/
bash
git clone https://github.com/alirezarezvani/claude-skills.git
cp -r claude-skills/engineering/terraform-patterns ~/.claude/skills/

Multi-tool install

多工具适配安装

bash
./scripts/convert.sh --skill terraform-patterns --tool codex|gemini|cursor|windsurf|openclaw
bash
./scripts/convert.sh --skill terraform-patterns --tool codex|gemini|cursor|windsurf|openclaw

OpenClaw

OpenClaw安装

bash
clawhub install terraform-patterns

bash
clawhub install terraform-patterns

Related Skills

相关技能

  • senior-devops — Broader DevOps scope (CI/CD, monitoring, containerization). Complementary — use terraform-patterns for IaC-specific work, senior-devops for pipeline and infrastructure operations.
  • aws-solution-architect — AWS architecture design. Complementary — terraform-patterns implements the infrastructure, aws-solution-architect designs it.
  • senior-security — Application security. Complementary — terraform-patterns covers infrastructure security posture, senior-security covers application-level threats.
  • ci-cd-pipeline-builder — Pipeline construction. Complementary — terraform-patterns defines infrastructure, ci-cd-pipeline-builder automates deployment.
  • senior-devops — 更广泛的DevOps范围(CI/CD、监控、容器化)。互补技能——terraform-patterns专注于IaC相关工作,senior-devops负责流水线和基础设施运维。
  • aws-solution-architect — AWS架构设计。互补技能——terraform-patterns实现基础设施部署,aws-solution-architect负责架构设计。
  • senior-security — 应用安全。互补技能——terraform-patterns覆盖基础设施安全态势,senior-security负责应用级威胁防护。
  • ci-cd-pipeline-builder — 流水线构建。互补技能——terraform-patterns定义基础设施,ci-cd-pipeline-builder实现部署自动化。