terraform-infrastructure

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Terraform Infrastructure-as-Code

Terraform基础设施即代码

A comprehensive skill for building, managing, and scaling cloud infrastructure using Terraform. Master declarative infrastructure, multi-cloud deployments, state management, module composition, and enterprise-grade patterns for AWS, Azure, GCP, and other providers.
这是一项使用Terraform构建、管理和扩展云基础设施的全面技能。掌握声明式基础设施、多云部署、状态管理、模块组合以及适用于AWS、Azure、GCP和其他云提供商的企业级模式。

When to Use This Skill

何时使用此技能

Use this skill when:
  • Provisioning cloud infrastructure across AWS, Azure, GCP, or multi-cloud environments
  • Building reusable infrastructure modules for teams and organizations
  • Managing infrastructure state across multiple environments (dev, staging, production)
  • Implementing infrastructure as code (IaC) best practices and governance
  • Migrating from manual infrastructure to automated, version-controlled deployments
  • Creating repeatable, testable infrastructure configurations
  • Orchestrating complex multi-tier application architectures
  • Managing Kubernetes clusters, databases, networks, and compute resources
  • Implementing disaster recovery and multi-region deployments
  • Collaborating on infrastructure changes with teams using GitOps workflows
在以下场景使用此技能:
  • 在AWS、Azure、GCP或多云环境中配置云基础设施
  • 为团队和组织构建可复用的基础设施模块
  • 在多环境(开发、预发布、生产)中管理基础设施状态
  • 实施基础设施即代码(IaC)最佳实践和治理
  • 从手动基础设施迁移到自动化、版本控制的部署
  • 创建可重复、可测试的基础设施配置
  • 编排复杂的多层应用架构
  • 管理Kubernetes集群、数据库、网络和计算资源
  • 实施灾难恢复和多区域部署
  • 使用GitOps工作流与团队协作进行基础设施变更

Core Concepts

核心概念

Infrastructure as Code Philosophy

基础设施即代码理念

Terraform enables declarative infrastructure management:
  • Declarative Configuration: Define desired state, Terraform handles execution
  • Immutable Infrastructure: Replace rather than modify infrastructure
  • Version Control: Track infrastructure changes like application code
  • Plan Before Apply: Preview changes before execution
  • Resource Graph: Automatic dependency resolution and parallel execution
  • State Management: Track real-world resources and their configuration
Terraform支持声明式基础设施管理:
  • 声明式配置:定义期望状态,Terraform负责执行
  • 不可变基础设施:替换而非修改基础设施
  • 版本控制:像跟踪应用代码一样跟踪基础设施变更
  • 先计划再执行:执行前预览变更
  • 资源图:自动依赖解析和并行执行
  • 状态管理:跟踪实际资源及其配置

Key Terraform Components

Terraform关键组件

  1. Providers: Plugins for infrastructure platforms (AWS, Azure, GCP, Kubernetes, etc.)
  2. Resources: Infrastructure objects (VMs, networks, databases, storage)
  3. Data Sources: Query existing infrastructure or external data
  4. Variables: Parameterize configurations for reusability
  5. Outputs: Export values for consumption by other configurations
  6. Modules: Reusable, composable infrastructure components
  7. State: JSON file tracking managed infrastructure
  8. Workspaces: Manage multiple instances of infrastructure
  1. Providers:基础设施平台的插件(AWS、Azure、GCP、Kubernetes等)
  2. Resources:基础设施对象(虚拟机、网络、数据库、存储)
  3. Data Sources:查询现有基础设施或外部数据
  4. Variables:参数化配置以实现复用
  5. Outputs:导出值供其他配置使用
  6. Modules:可复用、可组合的基础设施组件
  7. State:跟踪受管基础设施的JSON文件
  8. Workspaces:管理多实例基础设施

Terraform Workflow

Terraform工作流

Write → Init → Plan → Apply → Destroy
  ↓       ↓       ↓       ↓       ↓
 .tf    Download Review  Execute Remove
files   providers changes changes resources
Write → Init → Plan → Apply → Destroy
  ↓       ↓       ↓       ↓       ↓
 .tf    Download Review  Execute Remove
files   providers changes changes resources

Terraform Language (HCL)

Terraform语言(HCL)

Basic Syntax

基础语法

HCL (HashiCorp Configuration Language) is declarative and human-readable:
hcl
undefined
HCL(HashiCorp配置语言)是声明式且易读的:
hcl
undefined

Block structure

Block structure

block_type "block_label" "block_name" { argument_name = argument_value
nested_block { nested_argument = value } }
block_type "block_label" "block_name" { argument_name = argument_value
nested_block { nested_argument = value } }

Example: EC2 instance resource

Example: EC2 instance resource

resource "aws_instance" "web_server" { ami = "ami-0c55b159cbfafe1f0" instance_type = "t3.micro"
tags = { Name = "WebServer" Environment = "production" } }
undefined
resource "aws_instance" "web_server" { ami = "ami-0c55b159cbfafe1f0" instance_type = "t3.micro"
tags = { Name = "WebServer" Environment = "production" } }
undefined

Variables and Types

变量与类型

Terraform supports rich type system:
hcl
undefined
Terraform支持丰富的类型系统:
hcl
undefined

String variable

String variable

variable "region" { type = string description = "AWS region for resources" default = "us-east-1" }
variable "region" { type = string description = "AWS region for resources" default = "us-east-1" }

Number variable

Number variable

variable "instance_count" { type = number default = 3 }
variable "instance_count" { type = number default = 3 }

Boolean variable

Boolean variable

variable "enable_monitoring" { type = bool default = true }
variable "enable_monitoring" { type = bool default = true }

List variable

List variable

variable "availability_zones" { type = list(string) default = ["us-east-1a", "us-east-1b", "us-east-1c"] }
variable "availability_zones" { type = list(string) default = ["us-east-1a", "us-east-1b", "us-east-1c"] }

Map variable

Map variable

variable "instance_tags" { type = map(string) default = { Environment = "production" Project = "web-app" } }
variable "instance_tags" { type = map(string) default = { Environment = "production" Project = "web-app" } }

Object variable

Object variable

variable "database_config" { type = object({ engine = string engine_version = string instance_class = string allocated_storage = number }) default = { engine = "postgres" engine_version = "13.7" instance_class = "db.t3.micro" allocated_storage = 20 } }
variable "database_config" { type = object({ engine = string engine_version = string instance_class = string allocated_storage = number }) default = { engine = "postgres" engine_version = "13.7" instance_class = "db.t3.micro" allocated_storage = 20 } }

Set variable

Set variable

variable "allowed_cidr_blocks" { type = set(string) default = ["10.0.0.0/8", "172.16.0.0/12"] }
variable "allowed_cidr_blocks" { type = set(string) default = ["10.0.0.0/8", "172.16.0.0/12"] }

Tuple variable

Tuple variable

variable "server_config" { type = tuple([string, number, bool]) default = ["t3.micro", 2, true] }
undefined
variable "server_config" { type = tuple([string, number, bool]) default = ["t3.micro", 2, true] }
undefined

Variable Validation

变量验证

Add custom validation rules:
hcl
variable "instance_type" {
  type        = string
  description = "EC2 instance type"

  validation {
    condition     = contains(["t3.micro", "t3.small", "t3.medium"], var.instance_type)
    error_message = "Instance type must be t3.micro, t3.small, or t3.medium."
  }
}

variable "environment" {
  type = string

  validation {
    condition     = can(regex("^(dev|staging|prod)$", var.environment))
    error_message = "Environment must be dev, staging, or prod."
  }
}

variable "cidr_block" {
  type = string

  validation {
    condition     = can(cidrhost(var.cidr_block, 0))
    error_message = "Must be a valid IPv4 CIDR block."
  }
}
添加自定义验证规则:
hcl
variable "instance_type" {
  type        = string
  description = "EC2 instance type"

  validation {
    condition     = contains(["t3.micro", "t3.small", "t3.medium"], var.instance_type)
    error_message = "Instance type must be t3.micro, t3.small, or t3.medium."
  }
}

variable "environment" {
  type = string

  validation {
    condition     = can(regex("^(dev|staging|prod)$", var.environment))
    error_message = "Environment must be dev, staging, or prod."
  }
}

variable "cidr_block" {
  type = string

  validation {
    condition     = can(cidrhost(var.cidr_block, 0))
    error_message = "Must be a valid IPv4 CIDR block."
  }
}

Locals and Expressions

本地值与表达式

Locals compute values once and reuse them:
hcl
locals {
  # Simple local
  environment = terraform.workspace

  # Computed local
  common_tags = {
    Environment = local.environment
    ManagedBy   = "Terraform"
    Project     = var.project_name
  }

  # Conditional local
  instance_count = var.environment == "prod" ? 5 : 2

  # List manipulation
  all_subnets = concat(var.public_subnets, var.private_subnets)

  # Map merging
  merged_tags = merge(
    local.common_tags,
    var.additional_tags
  )

  # String interpolation
  bucket_name = "${var.project_name}-${local.environment}-data"

  # For expression
  subnet_ids = [for subnet in aws_subnet.private : subnet.id]

  # For expression with filtering
  prod_instances = [
    for instance in aws_instance.app :
    instance.id if instance.tags["Environment"] == "prod"
  ]

  # Map transformation
  instance_map = {
    for idx, instance in aws_instance.app :
    instance.tags["Name"] => instance.id
  }
}
本地值计算一次后可复用:
hcl
locals {
  # Simple local
  environment = terraform.workspace

  # Computed local
  common_tags = {
    Environment = local.environment
    ManagedBy   = "Terraform"
    Project     = var.project_name
  }

  # Conditional local
  instance_count = var.environment == "prod" ? 5 : 2

  # List manipulation
  all_subnets = concat(var.public_subnets, var.private_subnets)

  # Map merging
  merged_tags = merge(
    local.common_tags,
    var.additional_tags
  )

  # String interpolation
  bucket_name = "${var.project_name}-${local.environment}-data"

  # For expression
  subnet_ids = [for subnet in aws_subnet.private : subnet.id]

  # For expression with filtering
  prod_instances = [
    for instance in aws_instance.app :
    instance.id if instance.tags["Environment"] == "prod"
  ]

  # Map transformation
  instance_map = {
    for idx, instance in aws_instance.app :
    instance.tags["Name"] => instance.id
  }
}

Functions

函数

Terraform provides built-in functions:
hcl
undefined
Terraform提供内置函数:
hcl
undefined

String functions

String functions

upper("hello") # "HELLO" lower("WORLD") # "world" title("hello world") # "Hello World" trim(" spaces ") # "spaces" trimprefix("prefix-value", "prefix-") # "value" format("Server %03d", 1) # "Server 001" join("-", ["a", "b", "c"]) # "a-b-c" split("-", "a-b-c") # ["a", "b", "c"] substr("hello", 0, 3) # "hel" replace("hello", "l", "r") # "herro"
upper("hello") # "HELLO" lower("WORLD") # "world" title("hello world") # "Hello World" trim(" spaces ") # "spaces" trimprefix("prefix-value", "prefix-") # "value" format("Server %03d", 1) # "Server 001" join("-", ["a", "b", "c"]) # "a-b-c" split("-", "a-b-c") # ["a", "b", "c"] substr("hello", 0, 3) # "hel" replace("hello", "l", "r") # "herro"

Numeric functions

Numeric functions

max(5, 12, 9) # 12 min(5, 12, 9) # 5 ceil(5.1) # 6 floor(5.9) # 5 parseint("100", 10) # 100
max(5, 12, 9) # 12 min(5, 12, 9) # 5 ceil(5.1) # 6 floor(5.9) # 5 parseint("100", 10) # 100

Collection functions

Collection functions

length([1, 2, 3]) # 3 element(["a", "b", "c"], 1) # "b" concat([1, 2], [3, 4]) # [1, 2, 3, 4] contains(["a", "b"], "a") # true distinct([1, 2, 2, 3]) # [1, 2, 3] flatten([[1, 2], [3, 4]]) # [1, 2, 3, 4] keys({a = 1, b = 2}) # ["a", "b"] values({a = 1, b = 2}) # [1, 2] lookup({a = 1, b = 2}, "a", 0) # 1 merge({a = 1}, {b = 2}) # {a = 1, b = 2} reverse([1, 2, 3]) # [3, 2, 1] slice([1, 2, 3, 4], 1, 3) # [2, 3] sort(["c", "a", "b"]) # ["a", "b", "c"]
length([1, 2, 3]) # 3 element(["a", "b", "c"], 1) # "b" concat([1, 2], [3, 4]) # [1, 2, 3, 4] contains(["a", "b"], "a") # true distinct([1, 2, 2, 3]) # [1, 2, 3] flatten([[1, 2], [3, 4]]) # [1, 2, 3, 4] keys({a = 1, b = 2}) # ["a", "b"] values({a = 1, b = 2}) # [1, 2] lookup({a = 1, b = 2}, "a", 0) # 1 merge({a = 1}, {b = 2}) # {a = 1, b = 2} reverse([1, 2, 3]) # [3, 2, 1] slice([1, 2, 3, 4], 1, 3) # [2, 3] sort(["c", "a", "b"]) # ["a", "b", "c"]

Encoding functions

Encoding functions

base64encode("hello") # "aGVsbG8=" base64decode("aGVsbG8=") # "hello" jsonencode({key = "value"}) # "{"key":"value"}" jsondecode("{"key":"value"}") # {key = "value"} yamlencode({key = "value"}) # "key: value\n" yamldecode("key: value") # {key = "value"}
base64encode("hello") # "aGVsbG8=" base64decode("aGVsbG8=") # "hello" jsonencode({key = "value"}) # "{"key":"value"}" jsondecode("{"key":"value"}") # {key = "value"} yamlencode({key = "value"}) # "key: value\n" yamldecode("key: value") # {key = "value"}

Filesystem functions

Filesystem functions

file("path/to/file.txt") # Read file content templatefile("template.tpl", { # Render template var1 = "value1" })
file("path/to/file.txt") # Read file content templatefile("template.tpl", { # Render template var1 = "value1" })

Date/time functions

Date/time functions

timestamp() # "2024-01-15T12:30:45Z" formatdate("DD MMM YYYY", timestamp()) # "15 Jan 2024"
timestamp() # "2024-01-15T12:30:45Z" formatdate("DD MMM YYYY", timestamp()) # "15 Jan 2024"

Network functions

Network functions

cidrhost("10.0.0.0/24", 5) # "10.0.0.5" cidrnetmask("10.0.0.0/24") # "255.255.255.0" cidrsubnet("10.0.0.0/16", 8, 2) # "10.0.2.0/24"
cidrhost("10.0.0.0/24", 5) # "10.0.0.5" cidrnetmask("10.0.0.0/24") # "255.255.255.0" cidrsubnet("10.0.0.0/16", 8, 2) # "10.0.2.0/24"

Type conversion

Type conversion

tostring(42) # "42" tonumber("42") # 42 tobool("true") # true tolist([1, 2, 3]) # [1, 2, 3] toset([1, 2, 2, 3]) # [1, 2, 3] tomap({a = 1}) # {a = 1}
tostring(42) # "42" tonumber("42") # 42 tobool("true") # true tolist([1, 2, 3]) # [1, 2, 3] toset([1, 2, 2, 3]) # [1, 2, 3] tomap({a = 1}) # {a = 1}

Conditional functions

Conditional functions

can(regex("^[a-z]+$", var.name)) # true if valid try(var.optional_value, "default") # Return first valid value
undefined
can(regex("^[a-z]+$", var.name)) # true if valid try(var.optional_value, "default") # Return first valid value
undefined

Conditional Expressions

条件表达式

hcl
undefined
hcl
undefined

Ternary operator

Ternary operator

instance_type = var.environment == "prod" ? "t3.large" : "t3.micro"
instance_type = var.environment == "prod" ? "t3.large" : "t3.micro"

With count for conditional resources

With count for conditional resources

resource "aws_instance" "web" { count = var.create_instance ? 1 : 0

... configuration

}
resource "aws_instance" "web" { count = var.create_instance ? 1 : 0

... configuration

}

Dynamic blocks

Dynamic blocks

resource "aws_security_group" "example" { name = "example"
dynamic "ingress" { for_each = var.ingress_rules content { from_port = ingress.value.from_port to_port = ingress.value.to_port protocol = ingress.value.protocol cidr_blocks = ingress.value.cidr_blocks } } }
undefined
resource "aws_security_group" "example" { name = "example"
dynamic "ingress" { for_each = var.ingress_rules content { from_port = ingress.value.from_port to_port = ingress.value.to_port protocol = ingress.value.protocol cidr_blocks = ingress.value.cidr_blocks } } }
undefined

Meta-Arguments

元参数

Resources support special arguments:
hcl
undefined
资源支持特殊参数:
hcl
undefined

depends_on: Explicit dependencies

depends_on: Explicit dependencies

resource "aws_instance" "web" { depends_on = [aws_security_group.web_sg]

...

}
resource "aws_instance" "web" { depends_on = [aws_security_group.web_sg]

...

}

count: Create multiple instances

count: Create multiple instances

resource "aws_instance" "web" { count = 3 ami = var.ami_id instance_type = "t3.micro"
tags = { Name = "web-server-${count.index}" } }
resource "aws_instance" "web" { count = 3 ami = var.ami_id instance_type = "t3.micro"
tags = { Name = "web-server-${count.index}" } }

for_each: Create from map or set

for_each: Create from map or set

resource "aws_instance" "servers" { for_each = var.servers # map or set
ami = each.value.ami instance_type = each.value.type
tags = { Name = each.key } }
resource "aws_instance" "servers" { for_each = var.servers # map or set
ami = each.value.ami instance_type = each.value.type
tags = { Name = each.key } }

provider: Specify provider configuration

provider: Specify provider configuration

resource "aws_instance" "replica" { provider = aws.us-west-2

...

}
resource "aws_instance" "replica" { provider = aws.us-west-2

...

}

lifecycle: Control resource behavior

lifecycle: Control resource behavior

resource "aws_instance" "web" { ami = var.ami_id instance_type = "t3.micro"
lifecycle { create_before_destroy = true # Create new before destroying old prevent_destroy = true # Prevent accidental deletion ignore_changes = [ # Ignore specific changes tags, user_data ] } }
undefined
resource "aws_instance" "web" { ami = var.ami_id instance_type = "t3.micro"
lifecycle { create_before_destroy = true # Create new before destroying old prevent_destroy = true # Prevent accidental deletion ignore_changes = [ # Ignore specific changes tags, user_data ] } }
undefined

Providers

云提供商

Provider Configuration

提供商配置

Configure infrastructure platforms:
hcl
undefined
配置基础设施平台:
hcl
undefined

AWS Provider

AWS Provider

terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } } }
provider "aws" { region = var.aws_region
default_tags { tags = { ManagedBy = "Terraform" Project = var.project_name } } }
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } } }
provider "aws" { region = var.aws_region
default_tags { tags = { ManagedBy = "Terraform" Project = var.project_name } } }

Azure Provider

Azure Provider

provider "azurerm" { features { resource_group { prevent_deletion_if_contains_resources = true } } }
provider "azurerm" { features { resource_group { prevent_deletion_if_contains_resources = true } } }

GCP Provider

GCP Provider

provider "google" { project = var.gcp_project_id region = var.gcp_region }
provider "google" { project = var.gcp_project_id region = var.gcp_region }

Kubernetes Provider

Kubernetes Provider

provider "kubernetes" { config_path = "~/.kube/config" }
provider "kubernetes" { config_path = "~/.kube/config" }

Multiple provider configurations (aliases)

Multiple provider configurations (aliases)

provider "aws" { alias = "us_east_1" region = "us-east-1" }
provider "aws" { alias = "us_west_2" region = "us-west-2" }
provider "aws" { alias = "us_east_1" region = "us-east-1" }
provider "aws" { alias = "us_west_2" region = "us-west-2" }

Use aliased provider

Use aliased provider

resource "aws_instance" "east" { provider = aws.us_east_1

...

}
undefined
resource "aws_instance" "east" { provider = aws.us_east_1

...

}
undefined

Provider Authentication

提供商认证

Secure authentication methods:
hcl
undefined
安全认证方式:
hcl
undefined

AWS - Environment variables (recommended)

AWS - Environment variables (recommended)

export AWS_ACCESS_KEY_ID="..."

export AWS_ACCESS_KEY_ID="..."

export AWS_SECRET_ACCESS_KEY="..."

export AWS_SECRET_ACCESS_KEY="..."

export AWS_SESSION_TOKEN="..." # for temporary credentials

export AWS_SESSION_TOKEN="..." # for temporary credentials

provider "aws" { region = "us-east-1"

Credentials from environment or ~/.aws/credentials

}
provider "aws" { region = "us-east-1"

Credentials from environment or ~/.aws/credentials

}

AWS - Assume role

AWS - Assume role

provider "aws" { region = "us-east-1"
assume_role { role_arn = "arn:aws:iam::123456789012:role/TerraformRole" session_name = "terraform-session" external_id = "unique-id" } }
provider "aws" { region = "us-east-1"
assume_role { role_arn = "arn:aws:iam::123456789012:role/TerraformRole" session_name = "terraform-session" external_id = "unique-id" } }

Azure - Service principal

Azure - Service principal

provider "azurerm" { features {}
client_id = var.azure_client_id client_secret = var.azure_client_secret tenant_id = var.azure_tenant_id subscription_id = var.azure_subscription_id }
provider "azurerm" { features {}
client_id = var.azure_client_id client_secret = var.azure_client_secret tenant_id = var.azure_tenant_id subscription_id = var.azure_subscription_id }

Azure - Managed identity

Azure - Managed identity

provider "azurerm" { features {} use_msi = true }
provider "azurerm" { features {} use_msi = true }

GCP - Service account

GCP - Service account

provider "google" { credentials = file("path/to/service-account-key.json") project = var.gcp_project_id region = var.gcp_region }
undefined
provider "google" { credentials = file("path/to/service-account-key.json") project = var.gcp_project_id region = var.gcp_region }
undefined

Resources

资源

Resource Declaration

资源声明

Define infrastructure components:
hcl
resource "resource_type" "resource_name" {
  argument_name = argument_value
}
定义基础设施组件:
hcl
resource "resource_type" "resource_name" {
  argument_name = argument_value
}

Example: S3 bucket

Example: S3 bucket

resource "aws_s3_bucket" "data" { bucket = "my-application-data"
tags = { Name = "Data Bucket" Environment = "production" } }
resource "aws_s3_bucket" "data" { bucket = "my-application-data"
tags = { Name = "Data Bucket" Environment = "production" } }

Reference resource attributes

Reference resource attributes

resource "aws_s3_bucket_versioning" "data" { bucket = aws_s3_bucket.data.id # Reference bucket ID
versioning_configuration { status = "Enabled" } }
undefined
resource "aws_s3_bucket_versioning" "data" { bucket = aws_s3_bucket.data.id # Reference bucket ID
versioning_configuration { status = "Enabled" } }
undefined

Resource Lifecycle

资源生命周期

hcl
undefined
hcl
undefined

Create, update, destroy lifecycle

Create, update, destroy lifecycle

resource "aws_instance" "web" { ami = var.ami_id instance_type = var.instance_type

Lifecycle customization

lifecycle { # Create replacement before destroying create_before_destroy = true
# Prevent destruction
prevent_destroy = false

# Ignore changes to specific attributes
ignore_changes = [
  tags["LastModified"],
  user_data
]

# Replace if specific attributes change
replace_triggered_by = [
  aws_security_group.web.id
]
} }
undefined
resource "aws_instance" "web" { ami = var.ami_id instance_type = var.instance_type

Lifecycle customization

lifecycle { # Create replacement before destroying create_before_destroy = true
# Prevent destruction
prevent_destroy = false

# Ignore changes to specific attributes
ignore_changes = [
  tags["LastModified"],
  user_data
]

# Replace if specific attributes change
replace_triggered_by = [
  aws_security_group.web.id
]
} }
undefined

Data Sources

数据源

Query existing infrastructure or external data:
hcl
undefined
查询现有基础设施或外部数据:
hcl
undefined

AWS AMI lookup

AWS AMI lookup

data "aws_ami" "ubuntu" { most_recent = true owners = ["099720109477"] # Canonical
filter { name = "name" values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"] }
filter { name = "virtualization-type" values = ["hvm"] } }
data "aws_ami" "ubuntu" { most_recent = true owners = ["099720109477"] # Canonical
filter { name = "name" values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"] }
filter { name = "virtualization-type" values = ["hvm"] } }

Use data source in resource

Use data source in resource

resource "aws_instance" "web" { ami = data.aws_ami.ubuntu.id instance_type = "t3.micro" }
resource "aws_instance" "web" { ami = data.aws_ami.ubuntu.id instance_type = "t3.micro" }

VPC lookup

VPC lookup

data "aws_vpc" "default" { default = true }
data "aws_vpc" "default" { default = true }

Availability zones

Availability zones

data "aws_availability_zones" "available" { state = "available" }
data "aws_availability_zones" "available" { state = "available" }

Current region

Current region

data "aws_region" "current" {}
data "aws_region" "current" {}

Current account

Current account

data "aws_caller_identity" "current" {}
data "aws_caller_identity" "current" {}

External data source

External data source

data "external" "example" { program = ["python", "${path.module}/script.py"]
query = { key = "value" } }
data "external" "example" { program = ["python", "${path.module}/script.py"]
query = { key = "value" } }

HTTP data source

HTTP data source

data "http" "ip" { url = "https://ifconfig.me" }
data "http" "ip" { url = "https://ifconfig.me" }

Template file (deprecated, use templatefile())

Template file (deprecated, use templatefile())

data "template_file" "user_data" { template = file("${path.module}/user-data.sh")
vars = { server_port = 8080 db_address = aws_db_instance.main.address } }
undefined
data "template_file" "user_data" { template = file("${path.module}/user-data.sh")
vars = { server_port = 8080 db_address = aws_db_instance.main.address } }
undefined

Modules

模块

Module Structure

模块结构

Organize code into reusable modules:
modules/
├── vpc/
│   ├── main.tf       # Resources
│   ├── variables.tf  # Input variables
│   ├── outputs.tf    # Output values
│   └── README.md     # Documentation
├── compute/
│   ├── main.tf
│   ├── variables.tf
│   ├── outputs.tf
│   └── versions.tf   # Provider requirements
└── database/
    ├── main.tf
    ├── variables.tf
    └── outputs.tf
将代码组织为可复用模块:
modules/
├── vpc/
│   ├── main.tf       # Resources
│   ├── variables.tf  # Input variables
│   ├── outputs.tf    # Output values
│   └── README.md     # Documentation
├── compute/
│   ├── main.tf
│   ├── variables.tf
│   ├── outputs.tf
│   └── versions.tf   # Provider requirements
└── database/
    ├── main.tf
    ├── variables.tf
    └── outputs.tf

Creating a Module

创建模块

hcl
undefined
hcl
undefined

modules/vpc/variables.tf

modules/vpc/variables.tf

variable "vpc_name" { type = string description = "Name of the VPC" }
variable "vpc_cidr" { type = string description = "CIDR block for VPC" default = "10.0.0.0/16" }
variable "availability_zones" { type = list(string) description = "List of availability zones" }
variable "public_subnet_cidrs" { type = list(string) description = "CIDR blocks for public subnets" }
variable "private_subnet_cidrs" { type = list(string) description = "CIDR blocks for private subnets" }
variable "enable_nat_gateway" { type = bool description = "Enable NAT gateway for private subnets" default = true }
variable "tags" { type = map(string) description = "Tags to apply to resources" default = {} }
variable "vpc_name" { type = string description = "Name of the VPC" }
variable "vpc_cidr" { type = string description = "CIDR block for VPC" default = "10.0.0.0/16" }
variable "availability_zones" { type = list(string) description = "List of availability zones" }
variable "public_subnet_cidrs" { type = list(string) description = "CIDR blocks for public subnets" }
variable "private_subnet_cidrs" { type = list(string) description = "CIDR blocks for private subnets" }
variable "enable_nat_gateway" { type = bool description = "Enable NAT gateway for private subnets" default = true }
variable "tags" { type = map(string) description = "Tags to apply to resources" default = {} }

modules/vpc/main.tf

modules/vpc/main.tf

resource "aws_vpc" "main" { cidr_block = var.vpc_cidr enable_dns_hostnames = true enable_dns_support = true
tags = merge( var.tags, { Name = var.vpc_name } ) }
resource "aws_internet_gateway" "main" { vpc_id = aws_vpc.main.id
tags = merge( var.tags, { Name = "${var.vpc_name}-igw" } ) }
resource "aws_subnet" "public" { count = length(var.public_subnet_cidrs) vpc_id = aws_vpc.main.id cidr_block = var.public_subnet_cidrs[count.index] availability_zone = var.availability_zones[count.index]
map_public_ip_on_launch = true
tags = merge( var.tags, { Name = "${var.vpc_name}-public-${count.index + 1}" Type = "public" } ) }
resource "aws_subnet" "private" { count = length(var.private_subnet_cidrs) vpc_id = aws_vpc.main.id cidr_block = var.private_subnet_cidrs[count.index] availability_zone = var.availability_zones[count.index]
tags = merge( var.tags, { Name = "${var.vpc_name}-private-${count.index + 1}" Type = "private" } ) }
resource "aws_eip" "nat" { count = var.enable_nat_gateway ? length(var.public_subnet_cidrs) : 0 domain = "vpc"
tags = merge( var.tags, { Name = "${var.vpc_name}-nat-eip-${count.index + 1}" } ) }
resource "aws_nat_gateway" "main" { count = var.enable_nat_gateway ? length(var.public_subnet_cidrs) : 0 allocation_id = aws_eip.nat[count.index].id subnet_id = aws_subnet.public[count.index].id
tags = merge( var.tags, { Name = "${var.vpc_name}-nat-${count.index + 1}" } )
depends_on = [aws_internet_gateway.main] }
resource "aws_vpc" "main" { cidr_block = var.vpc_cidr enable_dns_hostnames = true enable_dns_support = true
tags = merge( var.tags, { Name = var.vpc_name } ) }
resource "aws_internet_gateway" "main" { vpc_id = aws_vpc.main.id
tags = merge( var.tags, { Name = "${var.vpc_name}-igw" } ) }
resource "aws_subnet" "public" { count = length(var.public_subnet_cidrs) vpc_id = aws_vpc.main.id cidr_block = var.public_subnet_cidrs[count.index] availability_zone = var.availability_zones[count.index]
map_public_ip_on_launch = true
tags = merge( var.tags, { Name = "${var.vpc_name}-public-${count.index + 1}" Type = "public" } ) }
resource "aws_subnet" "private" { count = length(var.private_subnet_cidrs) vpc_id = aws_vpc.main.id cidr_block = var.private_subnet_cidrs[count.index] availability_zone = var.availability_zones[count.index]
tags = merge( var.tags, { Name = "${var.vpc_name}-private-${count.index + 1}" Type = "private" } ) }
resource "aws_eip" "nat" { count = var.enable_nat_gateway ? length(var.public_subnet_cidrs) : 0 domain = "vpc"
tags = merge( var.tags, { Name = "${var.vpc_name}-nat-eip-${count.index + 1}" } ) }
resource "aws_nat_gateway" "main" { count = var.enable_nat_gateway ? length(var.public_subnet_cidrs) : 0 allocation_id = aws_eip.nat[count.index].id subnet_id = aws_subnet.public[count.index].id
tags = merge( var.tags, { Name = "${var.vpc_name}-nat-${count.index + 1}" } )
depends_on = [aws_internet_gateway.main] }

modules/vpc/outputs.tf

modules/vpc/outputs.tf

output "vpc_id" { description = "ID of the VPC" value = aws_vpc.main.id }
output "vpc_cidr" { description = "CIDR block of the VPC" value = aws_vpc.main.cidr_block }
output "public_subnet_ids" { description = "IDs of public subnets" value = aws_subnet.public[*].id }
output "private_subnet_ids" { description = "IDs of private subnets" value = aws_subnet.private[*].id }
output "nat_gateway_ids" { description = "IDs of NAT gateways" value = aws_nat_gateway.main[*].id }
output "internet_gateway_id" { description = "ID of the internet gateway" value = aws_internet_gateway.main.id }
undefined
output "vpc_id" { description = "ID of the VPC" value = aws_vpc.main.id }
output "vpc_cidr" { description = "CIDR block of the VPC" value = aws_vpc.main.cidr_block }
output "public_subnet_ids" { description = "IDs of public subnets" value = aws_subnet.public[*].id }
output "private_subnet_ids" { description = "IDs of private subnets" value = aws_subnet.private[*].id }
output "nat_gateway_ids" { description = "IDs of NAT gateways" value = aws_nat_gateway.main[*].id }
output "internet_gateway_id" { description = "ID of the internet gateway" value = aws_internet_gateway.main.id }
undefined

Using Modules

使用模块

hcl
undefined
hcl
undefined

Root main.tf

Root main.tf

module "vpc" { source = "./modules/vpc"
vpc_name = "production-vpc" vpc_cidr = "10.0.0.0/16" availability_zones = ["us-east-1a", "us-east-1b", "us-east-1c"] public_subnet_cidrs = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] private_subnet_cidrs = ["10.0.11.0/24", "10.0.12.0/24", "10.0.13.0/24"] enable_nat_gateway = true
tags = { Environment = "production" ManagedBy = "Terraform" } }
module "vpc" { source = "./modules/vpc"
vpc_name = "production-vpc" vpc_cidr = "10.0.0.0/16" availability_zones = ["us-east-1a", "us-east-1b", "us-east-1c"] public_subnet_cidrs = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] private_subnet_cidrs = ["10.0.11.0/24", "10.0.12.0/24", "10.0.13.0/24"] enable_nat_gateway = true
tags = { Environment = "production" ManagedBy = "Terraform" } }

Reference module outputs

Reference module outputs

resource "aws_instance" "web" { ami = data.aws_ami.ubuntu.id instance_type = "t3.micro" subnet_id = module.vpc.public_subnet_ids[0]
tags = { Name = "web-server" } }
resource "aws_instance" "web" { ami = data.aws_ami.ubuntu.id instance_type = "t3.micro" subnet_id = module.vpc.public_subnet_ids[0]
tags = { Name = "web-server" } }

Use remote module from Terraform Registry

Use remote module from Terraform Registry

module "s3_bucket" { source = "terraform-aws-modules/s3-bucket/aws" version = "3.15.0"
bucket = "my-application-bucket" acl = "private"
versioning = { enabled = true } }
module "s3_bucket" { source = "terraform-aws-modules/s3-bucket/aws" version = "3.15.0"
bucket = "my-application-bucket" acl = "private"
versioning = { enabled = true } }

Use module from GitHub

Use module from GitHub

module "consul" { source = "github.com/hashicorp/consul//terraform/aws"
servers = 3 }
module "consul" { source = "github.com/hashicorp/consul//terraform/aws"
servers = 3 }

Use module from Git with specific branch

Use module from Git with specific branch

...

}
undefined

...

}
undefined

Module Versioning

模块版本控制

hcl
undefined
hcl
undefined

In module source (versions.tf)

In module source (versions.tf)

terraform { required_version = ">= 1.5.0"
required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } } }
terraform { required_version = ">= 1.5.0"
required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } } }

Using versioned modules

Using versioned modules

module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "~> 5.0" # Allow minor and patch updates

...

}
undefined
module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "~> 5.0" # Allow minor and patch updates

...

}
undefined

State Management

状态管理

Local State

本地状态

Default state stored locally:
hcl
undefined
默认状态存储在本地:
hcl
undefined

terraform.tfstate (automatically created)

terraform.tfstate (automatically created)

{ "version": 4, "terraform_version": "1.5.0", "resources": [ { "mode": "managed", "type": "aws_instance", "name": "web", "provider": "provider["registry.terraform.io/hashicorp/aws"]", "instances": [ { "attributes": { "id": "i-1234567890abcdef0", "ami": "ami-0c55b159cbfafe1f0", "instance_type": "t3.micro" } } ] } ] }
undefined
{ "version": 4, "terraform_version": "1.5.0", "resources": [ { "mode": "managed", "type": "aws_instance", "name": "web", "provider": "provider["registry.terraform.io/hashicorp/aws"]", "instances": [ { "attributes": { "id": "i-1234567890abcdef0", "ami": "ami-0c55b159cbfafe1f0", "instance_type": "t3.micro" } } ] } ] }
undefined

Remote State - S3 Backend

远程状态 - S3后端

Store state in S3 for team collaboration:
hcl
undefined
将状态存储在S3中以实现团队协作:
hcl
undefined

backend.tf

backend.tf

terraform { backend "s3" { bucket = "my-terraform-state" key = "production/terraform.tfstate" region = "us-east-1" encrypt = true dynamodb_table = "terraform-locks"
# Optional: KMS encryption
kms_key_id = "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012"
} }
terraform { backend "s3" { bucket = "my-terraform-state" key = "production/terraform.tfstate" region = "us-east-1" encrypt = true dynamodb_table = "terraform-locks"
# Optional: KMS encryption
kms_key_id = "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012"
} }

Create S3 bucket and DynamoDB table for state

Create S3 bucket and DynamoDB table for state

resource "aws_s3_bucket" "terraform_state" { bucket = "my-terraform-state"
lifecycle { prevent_destroy = true } }
resource "aws_s3_bucket_versioning" "terraform_state" { bucket = aws_s3_bucket.terraform_state.id
versioning_configuration { status = "Enabled" } }
resource "aws_s3_bucket_server_side_encryption_configuration" "terraform_state" { bucket = aws_s3_bucket.terraform_state.id
rule { apply_server_side_encryption_by_default { sse_algorithm = "AES256" } } }
resource "aws_dynamodb_table" "terraform_locks" { name = "terraform-locks" billing_mode = "PAY_PER_REQUEST" hash_key = "LockID"
attribute { name = "LockID" type = "S" } }
undefined
resource "aws_s3_bucket" "terraform_state" { bucket = "my-terraform-state"
lifecycle { prevent_destroy = true } }
resource "aws_s3_bucket_versioning" "terraform_state" { bucket = aws_s3_bucket.terraform_state.id
versioning_configuration { status = "Enabled" } }
resource "aws_s3_bucket_server_side_encryption_configuration" "terraform_state" { bucket = aws_s3_bucket.terraform_state.id
rule { apply_server_side_encryption_by_default { sse_algorithm = "AES256" } } }
resource "aws_dynamodb_table" "terraform_locks" { name = "terraform-locks" billing_mode = "PAY_PER_REQUEST" hash_key = "LockID"
attribute { name = "LockID" type = "S" } }
undefined

Remote State - Azure Backend

远程状态 - Azure后端

hcl
terraform {
  backend "azurerm" {
    resource_group_name  = "terraform-state-rg"
    storage_account_name = "terraformstate12345"
    container_name       = "tfstate"
    key                  = "production.terraform.tfstate"
  }
}
hcl
terraform {
  backend "azurerm" {
    resource_group_name  = "terraform-state-rg"
    storage_account_name = "terraformstate12345"
    container_name       = "tfstate"
    key                  = "production.terraform.tfstate"
  }
}

Remote State - GCS Backend

远程状态 - GCS后端

hcl
terraform {
  backend "gcs" {
    bucket = "my-terraform-state"
    prefix = "production"
  }
}
hcl
terraform {
  backend "gcs" {
    bucket = "my-terraform-state"
    prefix = "production"
  }
}

Remote State - Terraform Cloud

远程状态 - Terraform Cloud

hcl
terraform {
  cloud {
    organization = "my-organization"

    workspaces {
      name = "production-infrastructure"
    }
  }
}
hcl
terraform {
  cloud {
    organization = "my-organization"

    workspaces {
      name = "production-infrastructure"
    }
  }
}

Remote State Data Source

远程状态数据源

Read state from another configuration:
hcl
data "terraform_remote_state" "vpc" {
  backend = "s3"

  config = {
    bucket = "my-terraform-state"
    key    = "vpc/terraform.tfstate"
    region = "us-east-1"
  }
}
从其他配置中读取状态:
hcl
data "terraform_remote_state" "vpc" {
  backend = "s3"

  config = {
    bucket = "my-terraform-state"
    key    = "vpc/terraform.tfstate"
    region = "us-east-1"
  }
}

Use outputs from remote state

Use outputs from remote state

resource "aws_instance" "web" { subnet_id = data.terraform_remote_state.vpc.outputs.public_subnet_ids[0]

...

}
undefined
resource "aws_instance" "web" { subnet_id = data.terraform_remote_state.vpc.outputs.public_subnet_ids[0]

...

}
undefined

Workspaces

工作区

Manage multiple environments:
bash
undefined
管理多环境:
bash
undefined

List workspaces

List workspaces

terraform workspace list
terraform workspace list

Create new workspace

Create new workspace

terraform workspace new staging terraform workspace new production
terraform workspace new staging terraform workspace new production

Select workspace

Select workspace

terraform workspace select staging
terraform workspace select staging

Show current workspace

Show current workspace

terraform workspace show
terraform workspace show

Delete workspace

Delete workspace

terraform workspace delete staging
undefined
terraform workspace delete staging
undefined

Workspace-Based Configuration

基于工作区的配置

hcl
undefined
hcl
undefined

Use workspace in resource naming

Use workspace in resource naming

resource "aws_instance" "web" { ami = var.ami_id instance_type = terraform.workspace == "prod" ? "t3.large" : "t3.micro"
tags = { Name = "web-${terraform.workspace}" Environment = terraform.workspace } }
resource "aws_instance" "web" { ami = var.ami_id instance_type = terraform.workspace == "prod" ? "t3.large" : "t3.micro"
tags = { Name = "web-${terraform.workspace}" Environment = terraform.workspace } }

Workspace-specific variables

Workspace-specific variables

locals { env_config = { dev = { instance_count = 1 instance_type = "t3.micro" } staging = { instance_count = 2 instance_type = "t3.small" } prod = { instance_count = 5 instance_type = "t3.large" } }
current_env = local.env_config[terraform.workspace] }
resource "aws_instance" "app" { count = local.current_env.instance_count instance_type = local.current_env.instance_type

...

}
undefined
locals { env_config = { dev = { instance_count = 1 instance_type = "t3.micro" } staging = { instance_count = 2 instance_type = "t3.small" } prod = { instance_count = 5 instance_type = "t3.large" } }
current_env = local.env_config[terraform.workspace] }
resource "aws_instance" "app" { count = local.current_env.instance_count instance_type = local.current_env.instance_type

...

}
undefined

Best Practices

最佳实践

Code Organization

代码组织

terraform-project/
├── environments/
│   ├── dev/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   ├── terraform.tfvars
│   │   └── backend.tf
│   ├── staging/
│   │   └── ...
│   └── production/
│       └── ...
├── modules/
│   ├── vpc/
│   ├── compute/
│   └── database/
├── global/
│   ├── iam/
│   └── route53/
└── README.md
terraform-project/
├── environments/
│   ├── dev/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   ├── terraform.tfvars
│   │   └── backend.tf
│   ├── staging/
│   │   └── ...
│   └── production/
│       └── ...
├── modules/
│   ├── vpc/
│   ├── compute/
│   └── database/
├── global/
│   ├── iam/
│   └── route53/
└── README.md

Naming Conventions

命名规范

hcl
undefined
hcl
undefined

Resource naming: <resource_type><name><purpose>

Resource naming: <resource_type><name><purpose>

resource "aws_security_group" "web_server_public" { } resource "aws_instance" "web_server_primary" { }
resource "aws_security_group" "web_server_public" { } resource "aws_instance" "web_server_primary" { }

Variable naming: descriptive and specific

Variable naming: descriptive and specific

variable "vpc_cidr_block" { } variable "database_instance_class" { } variable "enable_auto_scaling" { }
variable "vpc_cidr_block" { } variable "database_instance_class" { } variable "enable_auto_scaling" { }

Tags: consistent and comprehensive

Tags: consistent and comprehensive

tags = { Name = "resource-name" Environment = var.environment Project = var.project_name ManagedBy = "Terraform" Owner = "team-name" CostCenter = "engineering" }
undefined
tags = { Name = "resource-name" Environment = var.environment Project = var.project_name ManagedBy = "Terraform" Owner = "team-name" CostCenter = "engineering" }
undefined

Security Best Practices

安全最佳实践

hcl
undefined
hcl
undefined

Never hardcode credentials

Never hardcode credentials

BAD

BAD

provider "aws" { access_key = "AKIAIOSFODNN7EXAMPLE" secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" }
provider "aws" { access_key = "AKIAIOSFODNN7EXAMPLE" secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" }

GOOD - Use environment variables or IAM roles

GOOD - Use environment variables or IAM roles

provider "aws" { region = "us-east-1" }
provider "aws" { region = "us-east-1" }

Use sensitive flag for secrets

Use sensitive flag for secrets

variable "database_password" { type = string sensitive = true }
variable "database_password" { type = string sensitive = true }

Encrypt state files

Encrypt state files

terraform { backend "s3" { bucket = "terraform-state" key = "terraform.tfstate" encrypt = true } }
terraform { backend "s3" { bucket = "terraform-state" key = "terraform.tfstate" encrypt = true } }

Use .gitignore

Use .gitignore

.gitignore

.gitignore

*.tfstate .tfstate. .terraform/ *.tfvars # if contains secrets crash.log override.tf override.tf.json
undefined
*.tfstate .tfstate. .terraform/ *.tfvars # if contains secrets crash.log override.tf override.tf.json
undefined

DRY (Don't Repeat Yourself)

DRY(不要重复自己)

hcl
undefined
hcl
undefined

Use locals for repeated values

Use locals for repeated values

locals { common_tags = { Environment = var.environment ManagedBy = "Terraform" Project = var.project_name } }
resource "aws_instance" "web" { tags = local.common_tags }
resource "aws_s3_bucket" "data" { tags = local.common_tags }
locals { common_tags = { Environment = var.environment ManagedBy = "Terraform" Project = var.project_name } }
resource "aws_instance" "web" { tags = local.common_tags }
resource "aws_s3_bucket" "data" { tags = local.common_tags }

Use modules for reusable infrastructure

Use modules for reusable infrastructure

module "web_server" { source = "./modules/ec2-instance"
instance_type = "t3.micro" tags = local.common_tags }
module "web_server" { source = "./modules/ec2-instance"
instance_type = "t3.micro" tags = local.common_tags }

Use for_each to avoid duplication

Use for_each to avoid duplication

resource "aws_instance" "servers" { for_each = var.servers
ami = each.value.ami instance_type = each.value.type
tags = merge( local.common_tags, { Name = each.key } ) }
undefined
resource "aws_instance" "servers" { for_each = var.servers
ami = each.value.ami instance_type = each.value.type
tags = merge( local.common_tags, { Name = each.key } ) }
undefined

Documentation

文档

hcl
undefined
hcl
undefined

Document variables

Document variables

variable "vpc_cidr" { type = string description = "CIDR block for VPC. Must not overlap with existing VPCs." default = "10.0.0.0/16"
validation { condition = can(cidrhost(var.vpc_cidr, 0)) error_message = "Must be a valid IPv4 CIDR block." } }
variable "vpc_cidr" { type = string description = "CIDR block for VPC. Must not overlap with existing VPCs." default = "10.0.0.0/16"
validation { condition = can(cidrhost(var.vpc_cidr, 0)) error_message = "Must be a valid IPv4 CIDR block." } }

Document outputs

Document outputs

output "vpc_id" { description = "ID of the VPC. Use this to reference the VPC in other configurations." value = aws_vpc.main.id }
output "vpc_id" { description = "ID of the VPC. Use this to reference the VPC in other configurations." value = aws_vpc.main.id }

Add README.md to modules

Add README.md to modules

modules/vpc/README.md

modules/vpc/README.md

VPC Module

VPC Module

Creates a VPC with public and private subnets across multiple AZs.
Creates a VPC with public and private subnets across multiple AZs.

Usage

Usage

hcl
module "vpc" {
  source = "./modules/vpc"

  vpc_name             = "my-vpc"
  vpc_cidr             = "10.0.0.0/16"
  availability_zones   = ["us-east-1a", "us-east-1b"]
  public_subnet_cidrs  = ["10.0.1.0/24", "10.0.2.0/24"]
  private_subnet_cidrs = ["10.0.11.0/24", "10.0.12.0/24"]
}
hcl
module "vpc" {
  source = "./modules/vpc"

  vpc_name             = "my-vpc"
  vpc_cidr             = "10.0.0.0/16"
  availability_zones   = ["us-east-1a", "us-east-1b"]
  public_subnet_cidrs  = ["10.0.1.0/24", "10.0.2.0/24"]
  private_subnet_cidrs = ["10.0.11.0/24", "10.0.12.0/24"]
}

Inputs

Inputs

NameDescriptionTypeDefaultRequired
vpc_nameName of the VPCstring-yes
vpc_cidrCIDR block for VPCstring10.0.0.0/16no
NameDescriptionTypeDefaultRequired
vpc_nameName of the VPCstring-yes
vpc_cidrCIDR block for VPCstring10.0.0.0/16no

Outputs

Outputs

NameDescription
vpc_idID of the VPC
public_subnet_idsIDs of public subnets
undefined
NameDescription
vpc_idID of the VPC
public_subnet_idsIDs of public subnets
undefined

Testing Infrastructure

测试基础设施

hcl
undefined
hcl
undefined

Use terraform validate

Use terraform validate

terraform validate
terraform validate

Use terraform plan

Use terraform plan

terraform plan -out=tfplan
terraform plan -out=tfplan

Use terraform fmt for consistent formatting

Use terraform fmt for consistent formatting

terraform fmt -recursive
terraform fmt -recursive

Use external tools

Use external tools

tflint - Terraform linter

tflint - Terraform linter

checkov - Security scanner

checkov - Security scanner

terraform-docs - Generate documentation

terraform-docs - Generate documentation

terrascan - Policy scanner

terrascan - Policy scanner

undefined
undefined

Advanced Patterns

高级模式

Dynamic Backend Configuration

动态后端配置

hcl
undefined
hcl
undefined

backend-config-dev.hcl

backend-config-dev.hcl

bucket = "terraform-state-dev" key = "dev/terraform.tfstate" region = "us-east-1"
bucket = "terraform-state-dev" key = "dev/terraform.tfstate" region = "us-east-1"

backend-config-prod.hcl

backend-config-prod.hcl

bucket = "terraform-state-prod" key = "prod/terraform.tfstate" region = "us-east-1"
bucket = "terraform-state-prod" key = "prod/terraform.tfstate" region = "us-east-1"

Initialize with backend config

Initialize with backend config

terraform init -backend-config=backend-config-dev.hcl

terraform init -backend-config=backend-config-dev.hcl

undefined
undefined

Conditional Resource Creation

条件资源创建

hcl
undefined
hcl
undefined

Create resource only in production

Create resource only in production

resource "aws_cloudwatch_alarm" "high_cpu" { count = var.environment == "prod" ? 1 : 0
alarm_name = "high-cpu-utilization" comparison_operator = "GreaterThanThreshold" evaluation_periods = 2 metric_name = "CPUUtilization" namespace = "AWS/EC2" period = 300 statistic = "Average" threshold = 80 }
undefined
resource "aws_cloudwatch_alarm" "high_cpu" { count = var.environment == "prod" ? 1 : 0
alarm_name = "high-cpu-utilization" comparison_operator = "GreaterThanThreshold" evaluation_periods = 2 metric_name = "CPUUtilization" namespace = "AWS/EC2" period = 300 statistic = "Average" threshold = 80 }
undefined

Zero-Downtime Deployments

零停机部署

hcl
undefined
hcl
undefined

Blue-Green deployment with create_before_destroy

Blue-Green deployment with create_before_destroy

resource "aws_autoscaling_group" "app" { name = "${var.app_name}-${var.version}" launch_configuration = aws_launch_configuration.app.name min_size = var.min_size max_size = var.max_size
lifecycle { create_before_destroy = true } }
resource "aws_launch_configuration" "app" { name_prefix = "${var.app_name}-" image_id = var.ami_id instance_type = var.instance_type
lifecycle { create_before_destroy = true } }
undefined
resource "aws_autoscaling_group" "app" { name = "${var.app_name}-${var.version}" launch_configuration = aws_launch_configuration.app.name min_size = var.min_size max_size = var.max_size
lifecycle { create_before_destroy = true } }
resource "aws_launch_configuration" "app" { name_prefix = "${var.app_name}-" image_id = var.ami_id instance_type = var.instance_type
lifecycle { create_before_destroy = true } }
undefined

Moved Blocks for Refactoring

重构时使用Moved块

hcl
undefined
hcl
undefined

Refactor without destroying resources

Refactor without destroying resources

moved { from = aws_instance.web to = module.compute.aws_instance.web }
moved { from = aws_security_group.web[0] to = aws_security_group.web["primary"] }
undefined
moved { from = aws_instance.web to = module.compute.aws_instance.web }
moved { from = aws_security_group.web[0] to = aws_security_group.web["primary"] }
undefined

Import Existing Resources

导入现有资源

bash
undefined
bash
undefined

Import existing resource into Terraform state

Import existing resource into Terraform state

terraform import aws_instance.web i-1234567890abcdef0
terraform import aws_instance.web i-1234567890abcdef0

Import with for_each

Import with for_each

terraform import 'aws_instance.servers["web-1"]' i-1234567890abcdef0

---

**Skill Version**: 1.0.0
**Last Updated**: October 2025
**Skill Category**: Infrastructure as Code, Cloud Engineering, DevOps
**Compatible With**: AWS, Azure, GCP, Kubernetes, Terraform Cloud
terraform import 'aws_instance.servers["web-1"]' i-1234567890abcdef0

---

**技能版本**: 1.0.0
**最后更新**: 2025年10月
**技能分类**: 基础设施即代码、云工程、DevOps
**兼容平台**: AWS、Azure、GCP、Kubernetes、Terraform Cloud