terraform-infrastructure

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Terraform Infrastructure

Terraform基础设施

Overview

概述

Build scalable infrastructure as code with Terraform, managing AWS, Azure, GCP, and on-premise resources through declarative configuration, remote state, and automated provisioning.
使用Terraform构建可扩展的基础设施即代码,通过声明式配置、远程状态和自动化预置来管理AWS、Azure、GCP和本地资源。

When to Use

适用场景

  • Cloud infrastructure provisioning
  • Multi-environment management (dev, staging, prod)
  • Infrastructure versioning and code review
  • Cost tracking and resource optimization
  • Disaster recovery and environment replication
  • Automated infrastructure testing
  • Cross-region deployments
  • 云基础设施预置
  • 多环境管理(开发、测试、生产)
  • 基础设施版本控制与代码评审
  • 成本追踪与资源优化
  • 灾难恢复与环境复制
  • 基础设施自动化测试
  • 跨区域部署

Implementation Examples

实现示例

1. AWS Infrastructure Module

1. AWS基础设施模块

hcl
undefined
hcl
undefined

terraform/main.tf

terraform/main.tf

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

Remote state configuration

backend "s3" { bucket = "terraform-state-prod" key = "prod/terraform.tfstate" region = "us-east-1" encrypt = true dynamodb_table = "terraform-locks" } }
provider "aws" { region = var.aws_region
default_tags { tags = { Environment = var.environment ManagedBy = "Terraform" Project = var.project_name } } }
terraform { required_version = ">= 1.0"
required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } }

Remote state configuration

backend "s3" { bucket = "terraform-state-prod" key = "prod/terraform.tfstate" region = "us-east-1" encrypt = true dynamodb_table = "terraform-locks" } }
provider "aws" { region = var.aws_region
default_tags { tags = { Environment = var.environment ManagedBy = "Terraform" Project = var.project_name } } }

VPC and networking

VPC and networking

resource "aws_vpc" "main" { cidr_block = var.vpc_cidr enable_dns_hostnames = true enable_dns_support = true
tags = { Name = "${var.project_name}-vpc" } }
resource "aws_subnet" "public" { count = length(var.public_subnets) vpc_id = aws_vpc.main.id cidr_block = var.public_subnets[count.index] availability_zone = data.aws_availability_zones.available.names[count.index] map_public_ip_on_launch = true
tags = { Name = "${var.project_name}-public-${count.index + 1}" } }
resource "aws_subnet" "private" { count = length(var.private_subnets) vpc_id = aws_vpc.main.id cidr_block = var.private_subnets[count.index] availability_zone = data.aws_availability_zones.available.names[count.index]
tags = { Name = "${var.project_name}-private-${count.index + 1}" } }
resource "aws_vpc" "main" { cidr_block = var.vpc_cidr enable_dns_hostnames = true enable_dns_support = true
tags = { Name = "${var.project_name}-vpc" } }
resource "aws_subnet" "public" { count = length(var.public_subnets) vpc_id = aws_vpc.main.id cidr_block = var.public_subnets[count.index] availability_zone = data.aws_availability_zones.available.names[count.index] map_public_ip_on_launch = true
tags = { Name = "${var.project_name}-public-${count.index + 1}" } }
resource "aws_subnet" "private" { count = length(var.private_subnets) vpc_id = aws_vpc.main.id cidr_block = var.private_subnets[count.index] availability_zone = data.aws_availability_zones.available.names[count.index]
tags = { Name = "${var.project_name}-private-${count.index + 1}" } }

Internet Gateway

Internet Gateway

resource "aws_internet_gateway" "main" { vpc_id = aws_vpc.main.id
tags = { Name = "${var.project_name}-igw" } }
resource "aws_internet_gateway" "main" { vpc_id = aws_vpc.main.id
tags = { Name = "${var.project_name}-igw" } }

NAT Gateway for private subnets

NAT Gateway for private subnets

resource "aws_eip" "nat" { count = length(var.public_subnets) domain = "vpc"
tags = { Name = "${var.project_name}-eip-${count.index + 1}" }
depends_on = [aws_internet_gateway.main] }
resource "aws_nat_gateway" "main" { count = length(var.public_subnets) allocation_id = aws_eip.nat[count.index].id subnet_id = aws_subnet.public[count.index].id
tags = { Name = "${var.project_name}-nat-${count.index + 1}" }
depends_on = [aws_internet_gateway.main] }
resource "aws_eip" "nat" { count = length(var.public_subnets) domain = "vpc"
tags = { Name = "${var.project_name}-eip-${count.index + 1}" }
depends_on = [aws_internet_gateway.main] }
resource "aws_nat_gateway" "main" { count = length(var.public_subnets) allocation_id = aws_eip.nat[count.index].id subnet_id = aws_subnet.public[count.index].id
tags = { Name = "${var.project_name}-nat-${count.index + 1}" }
depends_on = [aws_internet_gateway.main] }

Route tables

Route tables

resource "aws_route_table" "public" { vpc_id = aws_vpc.main.id
route { cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.main.id }
tags = { Name = "${var.project_name}-public-rt" } }
resource "aws_route_table" "private" { count = length(var.private_subnets) vpc_id = aws_vpc.main.id
route { cidr_block = "0.0.0.0/0" nat_gateway_id = aws_nat_gateway.main[count.index].id }
tags = { Name = "${var.project_name}-private-rt-${count.index + 1}" } }
resource "aws_route_table" "public" { vpc_id = aws_vpc.main.id
route { cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.main.id }
tags = { Name = "${var.project_name}-public-rt" } }
resource "aws_route_table" "private" { count = length(var.private_subnets) vpc_id = aws_vpc.main.id
route { cidr_block = "0.0.0.0/0" nat_gateway_id = aws_nat_gateway.main[count.index].id }
tags = { Name = "${var.project_name}-private-rt-${count.index + 1}" } }

Route table associations

Route table associations

resource "aws_route_table_association" "public" { count = length(var.public_subnets) subnet_id = aws_subnet.public[count.index].id route_table_id = aws_route_table.public.id }
resource "aws_route_table_association" "private" { count = length(var.private_subnets) subnet_id = aws_subnet.private[count.index].id route_table_id = aws_route_table.private[count.index].id }
resource "aws_route_table_association" "public" { count = length(var.public_subnets) subnet_id = aws_subnet.public[count.index].id route_table_id = aws_route_table.public.id }
resource "aws_route_table_association" "private" { count = length(var.private_subnets) subnet_id = aws_subnet.private[count.index].id route_table_id = aws_route_table.private[count.index].id }

Security Group

Security Group

resource "aws_security_group" "alb" { name = "${var.project_name}-alb-sg" description = "Security group for ALB" vpc_id = aws_vpc.main.id
ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] }
ingress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] }
egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] }
tags = { Name = "${var.project_name}-alb-sg" } }
resource "aws_security_group" "alb" { name = "${var.project_name}-alb-sg" description = "Security group for ALB" vpc_id = aws_vpc.main.id
ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] }
ingress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] }
egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] }
tags = { Name = "${var.project_name}-alb-sg" } }

Application Load Balancer

Application Load Balancer

resource "aws_lb" "main" { name = "${var.project_name}-alb" internal = false load_balancer_type = "application" security_groups = [aws_security_group.alb.id] subnets = aws_subnet.public[*].id
enable_deletion_protection = var.environment == "production" ? true : false
tags = { Name = "${var.project_name}-alb" } }
resource "aws_lb" "main" { name = "${var.project_name}-alb" internal = false load_balancer_type = "application" security_groups = [aws_security_group.alb.id] subnets = aws_subnet.public[*].id
enable_deletion_protection = var.environment == "production" ? true : false
tags = { Name = "${var.project_name}-alb" } }

Data source for availability zones

Data source for availability zones

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

2. Variables and Outputs

2. 变量与输出

hcl
undefined
hcl
undefined

terraform/variables.tf

terraform/variables.tf

variable "aws_region" { description = "AWS region" type = string default = "us-east-1" }
variable "environment" { description = "Environment name" type = string validation { condition = contains(["dev", "staging", "production"], var.environment) error_message = "Environment must be dev, staging, or production." } }
variable "project_name" { description = "Project name for resource naming" type = string }
variable "vpc_cidr" { description = "CIDR block for VPC" type = string default = "10.0.0.0/16" }
variable "public_subnets" { description = "Public subnet CIDR blocks" type = list(string) default = ["10.0.1.0/24", "10.0.2.0/24"] }
variable "private_subnets" { description = "Private subnet CIDR blocks" type = list(string) default = ["10.0.10.0/24", "10.0.11.0/24"] }
variable "aws_region" { description = "AWS region" type = string default = "us-east-1" }
variable "environment" { description = "Environment name" type = string validation { condition = contains(["dev", "staging", "production"], var.environment) error_message = "Environment must be dev, staging, or production." } }
variable "project_name" { description = "Project name for resource naming" type = string }
variable "vpc_cidr" { description = "CIDR block for VPC" type = string default = "10.0.0.0/16" }
variable "public_subnets" { description = "Public subnet CIDR blocks" type = list(string) default = ["10.0.1.0/24", "10.0.2.0/24"] }
variable "private_subnets" { description = "Private subnet CIDR blocks" type = list(string) default = ["10.0.10.0/24", "10.0.11.0/24"] }

terraform/outputs.tf

terraform/outputs.tf

output "vpc_id" { description = "VPC ID" value = aws_vpc.main.id }
output "vpc_cidr" { description = "VPC CIDR block" value = aws_vpc.main.cidr_block }
output "public_subnet_ids" { description = "Public subnet IDs" value = aws_subnet.public[*].id }
output "private_subnet_ids" { description = "Private subnet IDs" value = aws_subnet.private[*].id }
output "alb_dns_name" { description = "DNS name of the ALB" value = aws_lb.main.dns_name }
output "alb_arn" { description = "ARN of the ALB" value = aws_lb.main.arn }
undefined
output "vpc_id" { description = "VPC ID" value = aws_vpc.main.id }
output "vpc_cidr" { description = "VPC CIDR block" value = aws_vpc.main.cidr_block }
output "public_subnet_ids" { description = "Public subnet IDs" value = aws_subnet.public[*].id }
output "private_subnet_ids" { description = "Private subnet IDs" value = aws_subnet.private[*].id }
output "alb_dns_name" { description = "DNS name of the ALB" value = aws_lb.main.dns_name }
output "alb_arn" { description = "ARN of the ALB" value = aws_lb.main.arn }
undefined

3. Terraform Deployment Script

3. Terraform部署脚本

bash
#!/bin/bash
bash
#!/bin/bash

deploy-terraform.sh - Terraform deployment automation

deploy-terraform.sh - Terraform deployment automation

set -euo pipefail
ENVIRONMENT="${1:-dev}" ACTION="${2:-plan}" TF_DIR="terraform"
echo "Terraform $ACTION for environment: $ENVIRONMENT"
cd "$TF_DIR"
set -euo pipefail
ENVIRONMENT="${1:-dev}" ACTION="${2:-plan}" TF_DIR="terraform"
echo "Terraform $ACTION for environment: $ENVIRONMENT"
cd "$TF_DIR"

Initialize Terraform

Initialize Terraform

echo "Initializing Terraform..." terraform init -upgrade
echo "Initializing Terraform..." terraform init -upgrade

Format and validate

Format and validate

echo "Validating Terraform configuration..." terraform fmt -recursive -check . terraform validate
echo "Validating Terraform configuration..." terraform fmt -recursive -check . terraform validate

Create/select workspace

Create/select workspace

echo "Creating/selecting workspace: $ENVIRONMENT" terraform workspace select -or-create "$ENVIRONMENT"
echo "Creating/selecting workspace: $ENVIRONMENT" terraform workspace select -or-create "$ENVIRONMENT"

Plan or apply

Plan or apply

case "$ACTION" in plan) echo "Creating Terraform plan..." terraform plan
-var-file="environments/$ENVIRONMENT.tfvars"
-out="tfplan-$ENVIRONMENT" ;; apply) echo "Applying Terraform changes..." terraform apply
-var-file="environments/$ENVIRONMENT.tfvars"
-auto-approve ;; destroy) echo "WARNING: Destroying infrastructure in $ENVIRONMENT" read -p "Are you sure? (yes/no): " confirm if [ "$confirm" = "yes" ]; then terraform destroy
-var-file="environments/$ENVIRONMENT.tfvars"
-auto-approve fi ;; *) echo "Unknown action: $ACTION" exit 1 ;; esac
echo "Terraform $ACTION complete!"
undefined
case "$ACTION" in plan) echo "Creating Terraform plan..." terraform plan
-var-file="environments/$ENVIRONMENT.tfvars"
-out="tfplan-$ENVIRONMENT" ;; apply) echo "Applying Terraform changes..." terraform apply
-var-file="environments/$ENVIRONMENT.tfvars"
-auto-approve ;; destroy) echo "WARNING: Destroying infrastructure in $ENVIRONMENT" read -p "Are you sure? (yes/no): " confirm if [ "$confirm" = "yes" ]; then terraform destroy
-var-file="environments/$ENVIRONMENT.tfvars"
-auto-approve fi ;; *) echo "Unknown action: $ACTION" exit 1 ;; esac
echo "Terraform $ACTION complete!"
undefined

Best Practices

最佳实践

✅ DO

✅ 建议

  • Use remote state (S3, Terraform Cloud)
  • Implement state locking (DynamoDB)
  • Organize code into modules
  • Use workspaces for environments
  • Apply tags consistently
  • Use variables for flexibility
  • Implement code review before apply
  • Keep sensitive data in separate variable files
  • 使用远程状态(S3、Terraform Cloud)
  • 实现状态锁定(DynamoDB)
  • 将代码组织为模块
  • 使用工作区管理环境
  • 一致地应用标签
  • 使用变量提升灵活性
  • 在执行apply前进行代码评审
  • 将敏感数据存放在单独的变量文件中

❌ DON'T

❌ 避免

  • Store state files locally in git
  • Use hardcoded values
  • Mix environments in single state
  • Skip terraform plan review
  • Use root module for everything
  • Store secrets in code
  • Disable state locking
  • 在Git中存储本地状态文件
  • 使用硬编码值
  • 在单一状态中混合多个环境
  • 跳过terraform plan评审
  • 所有内容都使用根模块
  • 在代码中存储密钥
  • 禁用状态锁定

Terraform Commands

Terraform命令

bash
terraform init        # Initialize Terraform
terraform validate    # Validate configuration
terraform fmt         # Format code
terraform plan        # Preview changes
terraform apply       # Apply changes
terraform destroy     # Remove resources
terraform workspace   # Manage workspaces
bash
terraform init        # 初始化Terraform
terraform validate    # 验证配置
terraform fmt         # 格式化代码
terraform plan        # 预览变更
terraform apply       # 应用变更
terraform destroy     # 删除资源
terraform workspace   # 管理工作区

Resources

资源