terraform-infrastructure
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTerraform 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关键组件
- Providers: Plugins for infrastructure platforms (AWS, Azure, GCP, Kubernetes, etc.)
- Resources: Infrastructure objects (VMs, networks, databases, storage)
- Data Sources: Query existing infrastructure or external data
- Variables: Parameterize configurations for reusability
- Outputs: Export values for consumption by other configurations
- Modules: Reusable, composable infrastructure components
- State: JSON file tracking managed infrastructure
- Workspaces: Manage multiple instances of infrastructure
- Providers:基础设施平台的插件(AWS、Azure、GCP、Kubernetes等)
- Resources:基础设施对象(虚拟机、网络、数据库、存储)
- Data Sources:查询现有基础设施或外部数据
- Variables:参数化配置以实现复用
- Outputs:导出值供其他配置使用
- Modules:可复用、可组合的基础设施组件
- State:跟踪受管基础设施的JSON文件
- Workspaces:管理多实例基础设施
Terraform Workflow
Terraform工作流
Write → Init → Plan → Apply → Destroy
↓ ↓ ↓ ↓ ↓
.tf Download Review Execute Remove
files providers changes changes resourcesWrite → Init → Plan → Apply → Destroy
↓ ↓ ↓ ↓ ↓
.tf Download Review Execute Remove
files providers changes changes resourcesTerraform Language (HCL)
Terraform语言(HCL)
Basic Syntax
基础语法
HCL (HashiCorp Configuration Language) is declarative and human-readable:
hcl
undefinedHCL(HashiCorp配置语言)是声明式且易读的:
hcl
undefinedBlock 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"
}
}
undefinedresource "aws_instance" "web_server" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
tags = {
Name = "WebServer"
Environment = "production"
}
}
undefinedVariables and Types
变量与类型
Terraform supports rich type system:
hcl
undefinedTerraform支持丰富的类型系统:
hcl
undefinedString 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]
}
undefinedvariable "server_config" {
type = tuple([string, number, bool])
default = ["t3.micro", 2, true]
}
undefinedVariable 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
undefinedTerraform提供内置函数:
hcl
undefinedString 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
undefinedcan(regex("^[a-z]+$", var.name)) # true if valid
try(var.optional_value, "default") # Return first valid value
undefinedConditional Expressions
条件表达式
hcl
undefinedhcl
undefinedTernary 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
}
}
}
undefinedresource "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
}
}
}
undefinedMeta-Arguments
元参数
Resources support special arguments:
hcl
undefined资源支持特殊参数:
hcl
undefineddepends_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
]
}
}
undefinedresource "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
]
}
}
undefinedProviders
云提供商
Provider Configuration
提供商配置
Configure infrastructure platforms:
hcl
undefined配置基础设施平台:
hcl
undefinedAWS 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
...
}
undefinedresource "aws_instance" "east" {
provider = aws.us_east_1
...
}
undefinedProvider Authentication
提供商认证
Secure authentication methods:
hcl
undefined安全认证方式:
hcl
undefinedAWS - 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
}
undefinedprovider "google" {
credentials = file("path/to/service-account-key.json")
project = var.gcp_project_id
region = var.gcp_region
}
undefinedResources
资源
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"
}
}
undefinedresource "aws_s3_bucket_versioning" "data" {
bucket = aws_s3_bucket.data.id # Reference bucket ID
versioning_configuration {
status = "Enabled"
}
}
undefinedResource Lifecycle
资源生命周期
hcl
undefinedhcl
undefinedCreate, 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
]}
}
undefinedresource "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
]}
}
undefinedData Sources
数据源
Query existing infrastructure or external data:
hcl
undefined查询现有基础设施或外部数据:
hcl
undefinedAWS 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
}
}
undefineddata "template_file" "user_data" {
template = file("${path.module}/user-data.sh")
vars = {
server_port = 8080
db_address = aws_db_instance.main.address
}
}
undefinedModules
模块
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.tfCreating a Module
创建模块
hcl
undefinedhcl
undefinedmodules/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
}
undefinedoutput "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
}
undefinedUsing Modules
使用模块
hcl
undefinedhcl
undefinedRoot 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
module "vpc" {
source = "git::https://github.com/organization/terraform-modules.git//vpc?ref=v1.2.0"
...
}
undefinedmodule "vpc" {
source = "git::https://github.com/organization/terraform-modules.git//vpc?ref=v1.2.0"
...
}
undefinedModule Versioning
模块版本控制
hcl
undefinedhcl
undefinedIn 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
...
}
undefinedmodule "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0" # Allow minor and patch updates
...
}
undefinedState Management
状态管理
Local State
本地状态
Default state stored locally:
hcl
undefined默认状态存储在本地:
hcl
undefinedterraform.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"
}
}
]
}
]
}
undefinedRemote State - S3 Backend
远程状态 - S3后端
Store state in S3 for team collaboration:
hcl
undefined将状态存储在S3中以实现团队协作:
hcl
undefinedbackend.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"
}
}
undefinedresource "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"
}
}
undefinedRemote 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]
...
}
undefinedresource "aws_instance" "web" {
subnet_id = data.terraform_remote_state.vpc.outputs.public_subnet_ids[0]
...
}
undefinedWorkspaces
工作区
Manage multiple environments:
bash
undefined管理多环境:
bash
undefinedList 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
undefinedterraform workspace delete staging
undefinedWorkspace-Based Configuration
基于工作区的配置
hcl
undefinedhcl
undefinedUse 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
...
}
undefinedlocals {
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
...
}
undefinedBest 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.mdterraform-project/
├── environments/
│ ├── dev/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ ├── terraform.tfvars
│ │ └── backend.tf
│ ├── staging/
│ │ └── ...
│ └── production/
│ └── ...
├── modules/
│ ├── vpc/
│ ├── compute/
│ └── database/
├── global/
│ ├── iam/
│ └── route53/
└── README.mdNaming Conventions
命名规范
hcl
undefinedhcl
undefinedResource 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"
}
undefinedtags = {
Name = "resource-name"
Environment = var.environment
Project = var.project_name
ManagedBy = "Terraform"
Owner = "team-name"
CostCenter = "engineering"
}
undefinedSecurity Best Practices
安全最佳实践
hcl
undefinedhcl
undefinedNever 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
undefinedDRY (Don't Repeat Yourself)
DRY(不要重复自己)
hcl
undefinedhcl
undefinedUse 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
}
)
}
undefinedresource "aws_instance" "servers" {
for_each = var.servers
ami = each.value.ami
instance_type = each.value.type
tags = merge(
local.common_tags,
{
Name = each.key
}
)
}
undefinedDocumentation
文档
hcl
undefinedhcl
undefinedDocument 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
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| vpc_name | Name of the VPC | string | - | yes |
| vpc_cidr | CIDR block for VPC | string | 10.0.0.0/16 | no |
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| vpc_name | Name of the VPC | string | - | yes |
| vpc_cidr | CIDR block for VPC | string | 10.0.0.0/16 | no |
Outputs
Outputs
| Name | Description |
|---|---|
| vpc_id | ID of the VPC |
| public_subnet_ids | IDs of public subnets |
undefined| Name | Description |
|---|---|
| vpc_id | ID of the VPC |
| public_subnet_ids | IDs of public subnets |
undefinedTesting Infrastructure
测试基础设施
hcl
undefinedhcl
undefinedUse 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
undefinedundefinedAdvanced Patterns
高级模式
Dynamic Backend Configuration
动态后端配置
hcl
undefinedhcl
undefinedbackend-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
undefinedundefinedConditional Resource Creation
条件资源创建
hcl
undefinedhcl
undefinedCreate 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
}
undefinedresource "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
}
undefinedZero-Downtime Deployments
零停机部署
hcl
undefinedhcl
undefinedBlue-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
}
}
undefinedresource "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
}
}
undefinedMoved Blocks for Refactoring
重构时使用Moved块
hcl
undefinedhcl
undefinedRefactor 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"]
}
undefinedmoved {
from = aws_instance.web
to = module.compute.aws_instance.web
}
moved {
from = aws_security_group.web[0]
to = aws_security_group.web["primary"]
}
undefinedImport Existing Resources
导入现有资源
bash
undefinedbash
undefinedImport 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 Cloudterraform import 'aws_instance.servers["web-1"]' i-1234567890abcdef0
---
**技能版本**: 1.0.0
**最后更新**: 2025年10月
**技能分类**: 基础设施即代码、云工程、DevOps
**兼容平台**: AWS、Azure、GCP、Kubernetes、Terraform Cloud