← 返回资讯
苏晴
资深编辑
已审核

Terraform 基础设施即代码:从入门到生产实践

title: "Terraform 基础设施即代码:从入门到生产实践"

Terraform 基础设施即代码:从入门到生产实践

title: "Terraform 基础设施即代码:从入门到生产实践"

date: "2026-07-10"

tags: ["Terraform", "IaC", "DevOps", "云原生"]


Terraform 基础设施即代码:从入门到生产实践

基础设施即代码(IaC)是用代码管理云资源的现代实践。Terraform 是最流行的 IaC 工具,支持多云和声明式配置。

基础概念

Provider

Provider 是 Terraform 与云平台交互的插件。

HCL
# main.tf
terraform {
  required_version = ">= 1.5.0"
  
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = var.aws_region
}

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

Resource

Resource 是要创建的云资源。

HCL
# EC2 实例
resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"
  
  tags = {
    Name        = "web-server"
    Environment = var.environment
  }
  
  user_data = <<-EOF
    #!/bin/bash
    apt-get update
    apt-get install -y nginx
    systemctl start nginx
  EOF
}

# 安全组
resource "aws_security_group" "web" {
  name        = "web-sg"
  description = "Allow HTTP and SSH"
  
  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  
  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["10.0.0.0/8"]
  }
  
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

模块化

模块定义

HCL
# modules/vpc/main.tf
variable "vpc_cidr" {
  type = string
}

variable "environment" {
  type = string
}

resource "aws_vpc" "main" {
  cidr_block           = var.vpc_cidr
  enable_dns_hostnames = true
  enable_dns_support   = true
  
  tags = {
    Name        = "${var.environment}-vpc"
    Environment = var.environment
  }
}

resource "aws_subnet" "public" {
  count             = 2
  vpc_id            = aws_vpc.main.id
  cidr_block        = cidrsubnet(var.vpc_cidr, 8, count.index)
  availability_zone = data.aws_availability_zones.available.names[count.index]
  
  map_public_ip_on_launch = true
  
  tags = {
    Name = "${var.environment}-public-${count.index}"
  }
}

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

resource "aws_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id
}

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

resource "aws_route_table_association" "public" {
  count          = 2
  subnet_id      = aws_subnet.public[count.index].id
  route_table_id = aws_route_table.public.id
}

output "vpc_id" {
  value = aws_vpc.main.id
}

output "public_subnet_ids" {
  value = aws_subnet.public[*].id
}

模块使用

HCL
# main.tf
module "vpc" {
  source = "./modules/vpc"
  
  vpc_cidr    = "10.0.0.0/16"
  environment = var.environment
}

module "ecs_cluster" {
  source = "./modules/ecs"
  
  vpc_id     = module.vpc.vpc_id
  subnet_ids = module.vpc.public_subnet_ids
  environment = var.environment
}

状态管理

远程状态(S3 + DynamoDB)

HCL
terraform {
  backend "s3" {
    bucket         = "terraform-state-prod"
    key            = "infrastructure/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "terraform-locks"
    encrypt        = true
  }
}
BASH
# 创建状态存储
aws s3api create-bucket --bucket terraform-state-prod
aws s3api put-bucket-versioning --bucket terraform-state-prod \
  --versioning-configuration Status=Enabled

aws dynamodb create-table \
  --table-name terraform-locks \
  --attribute-definitions AttributeName=LockID,AttributeType=S \
  --key-schema AttributeName=LockID,KeyType=HASH

工作流

BASH
# 初始化
terraform init

# 预览变更
terraform plan -out=tfplan

# 应用变更
terraform apply tfplan

# 查看状态
terraform show

# 销毁资源
terraform destroy

多环境管理

HCL
# environments/dev/terraform.tfvars
environment    = "dev"
instance_type  = "t3.micro"
instance_count = 1

# environments/prod/terraform.tfvars
environment    = "prod"
instance_type  = "t3.large"
instance_count = 3
BASH
# 部署开发环境
cd environments/dev
terraform init
terraform apply

# 部署生产环境
cd environments/prod
terraform init
terraform apply

最佳实践

1. 状态文件隔离

每个环境使用独立的状态文件,避免误操作影响其他环境。

2. 变量验证

HCL
variable "instance_type" {
  type = string
  
  validation {
    condition     = can(regex("^t3\\.", var.instance_type))
    error_message = "Only t3 instance types are allowed."
  }
}

3. 输出敏感信息保护

HCL
output "db_password" {
  value     = aws_db_instance.main.password
  sensitive = true
}

4. 资源依赖显式声明

HCL
resource "aws_instance" "app" {
  # ...
  
  depends_on = [aws_db_instance.main]
}

Terraform 让基础设施管理变得可预测、可重复、可审计。掌握 IaC 是现代 DevOps 工程师的必备技能。

755
12590 阅读
4 评论
分享
链接已复制
编辑说明

本文由 MakeSense 编辑团队撰写并审核。文中引用的数据和观点均经过交叉验证,如有疏漏欢迎在评论区指正。最后更新:2026年07月11日 08:55

苏晴

资深编辑

科技媒体从业 8 年,曾就职于多家科技媒体。关注 AI 创业和投资赛道,采访过 50+ 位行业从业者。

读者评论 4

张工 3天前
写得很实在,特别是实测对比那部分,跟我自己的使用感受一致。
回复 点赞 (12)
前端工程师 6天前
代码示例很清晰,直接用到项目里了。
回复 点赞 (6)
技术小白 1周前
作为非技术人员也看懂了,感谢作者的通俗讲解。
回复 点赞 (3)
Dev小王 1周前
终于有人把这个说清楚了,收藏了。
回复 点赞 (8)