Terraform是HashiCorp推出的基础设施即代码(IaC)工具,通过声明式配置文件管理云资源的生命周期。与手动在控制台创建资源不同,Terraform将基础设施定义为代码,支持版本管理、代码审查和自动化部署。在多云环境和DevOps实践中,Terraform已成为基础设施管理的标准工具之一。
Terraform核心工作流与状态管理
Terraform的工作流包含四个核心命令:init初始化工作目录、plan生成执行计划、apply执行变更、destroy销毁资源。所有操作基于一个核心概念——State(状态文件),它记录了当前基础设施与配置文件的映射关系。
# main.tf - 基础配置
terraform {
required_version = ">= 1.6.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.40"
}
}
backend "s3" {
bucket = "tf-state-prod"
key = "infra/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "tf-locks"
encrypt = true
}
}
provider "aws" {
region = var.aws_region
default_tags {
tags = {
Project = "production"
Environment = "prod"
ManagedBy = "terraform"
}
}
}
# 初始化
terraform init
# 查看执行计划(不执行)
terraform plan -out=tfplan
# 执行变更
terraform apply tfplan
# 销毁所有资源
terraform destroy
远程State存储是团队协作的必要配置。S3后端配合DynamoDB锁表实现状态文件的并发控制——同一时刻只有一个Terraform进程能修改State,防止并发apply导致状态冲突。State文件包含敏感信息(如数据库密码、密钥),必须加密存储并限制访问权限。
资源声明与依赖管理
Terraform使用HCL(HashiCorp Configuration Language)声明资源。资源间的依赖关系通过引用自动推断,也可通过depends_on显式声明:
# variables.tf
variable "aws_region" {
type = string
default = "us-east-1"
}
variable "vpc_cidr" {
type = string
default = "10.0.0.0/16"
}
variable "instance_type" {
type = string
default = "t3.medium"
}
# main.tf - 网络基础设施
resource "aws_vpc" "main" {
cidr_block = var.vpc_cidr
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "production-vpc"
}
}
resource "aws_subnet" "private" {
count = 3
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]
tags = {
Name = "private-subnet-${count.index + 1}"
Tier = "private"
}
}
resource "aws_subnet" "public" {
count = 3
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(var.vpc_cidr, 8, count.index + 10)
availability_zone = data.aws_availability_zones.available.names[count.index]
map_public_ip_on_launch = true
tags = {
Name = "public-subnet-${count.index + 1}"
Tier = "public"
}
}
# NAT Gateway(依赖EIP和公网子网)
resource "aws_eip" "nat" {
count = 3
domain = "vpc"
}
resource "aws_nat_gateway" "main" {
count = 3
allocation_id = aws_eip.nat[count.index].id
subnet_id = aws_subnet.public[count.index].id
depends_on = [aws_internet_gateway.main]
tags = {
Name = "nat-gw-${count.index + 1}"
}
}
cidrsubnet函数是Terraform内置的IP地址计算工具,从父CIDR中切分子网。上面的配置从10.0.0.0/16中切分出3个私有子网(10.0.0.0/24, 10.0.1.0/24, 10.0.2.0/24)和3个公有子网(10.0.10.0/24, 10.0.11.0/24, 10.0.12.0/24),分布在3个可用区实现高可用。
模块化设计与可复用组件
当基础设施复杂度增长时,将资源组织为模块是保持代码可维护性的关键。模块是包含一组资源定义的目录,通过输入变量参数化,通过输出变量暴露结果:
# modules/eks-cluster/main.tf
resource "aws_eks_cluster" "main" {
name = var.cluster_name
role_arn = aws_iam_role.eks_cluster.arn
version = var.kubernetes_version
vpc_config {
subnet_ids = var.subnet_ids
endpoint_private_access = true
endpoint_public_access = var.endpoint_public_access
public_access_cidrs = var.public_access_cidrs
}
enabled_cluster_log_types = ["api", "audit", "authenticator", "controllerManager", "scheduler"]
depends_on = [
aws_iam_role_policy_attachment.eks_cluster_policy
]
}
resource "aws_eks_node_group" "main" {
cluster_name = aws_eks_cluster.main.name
node_group_name = "${var.cluster_name}-nodes"
node_role_arn = aws_iam_role.eks_nodes.arn
subnet_ids = var.private_subnet_ids
instance_types = var.instance_types
disk_size = var.disk_size
scaling_config {
desired_size = var.desired_nodes
max_size = var.max_nodes
min_size = var.min_nodes
}
update_config {
max_unavailable = 1
}
}
# modules/eks-cluster/variables.tf
variable "cluster_name" { type = string }
variable "kubernetes_version" { type = string, default = "1.30" }
variable "subnet_ids" { type = list(string) }
variable "private_subnet_ids" { type = list(string) }
variable "instance_types" { type = list(string), default = ["t3.large"] }
variable "disk_size" { type = number, default = 100 }
variable "desired_nodes" { type = number, default = 3 }
variable "max_nodes" { type = number, default = 10 }
variable "min_nodes" { type = number, default = 1 }
variable "endpoint_public_access" { type = bool, default = false }
variable "public_access_cidrs" { type = list(string), default = [] }
# modules/eks-cluster/outputs.tf
output "cluster_endpoint" {
value = aws_eks_cluster.main.endpoint
}
output "cluster_name" {
value = aws_eks_cluster.main.name
}
output "cluster_ca" {
value = aws_eks_cluster.main.certificate_authority[0].data
}
在根配置中引用模块:
# environments/prod/main.tf
module "eks" {
source = "../../modules/eks-cluster"
cluster_name = "prod-cluster"
kubernetes_version = "1.30"
subnet_ids = aws_subnet.private[*].id
private_subnet_ids = aws_subnet.private[*].id
instance_types = ["m5.2xlarge"]
desired_nodes = 5
max_nodes = 20
endpoint_public_access = false
}
# 引用模块输出
output "eks_endpoint" {
value = module.eks.cluster_endpoint
}
CI/CD流水线中的Terraform集成
将Terraform纳入CI/CD流水线实现基础设施变更的自动化审批和部署。以下GitHub Actions配置实现了plan-approve-apply工作流:
# .github/workflows/terraform.yml
name: Terraform CI/CD
on:
push:
paths:
- 'environments/**'
- 'modules/**'
pull_request:
paths:
- 'environments/**'
jobs:
terraform-plan:
runs-on: ubuntu-latest
permissions:
id-token: write
pull-requests: write
contents: read
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/github-actions
aws-region: us-east-1
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: "1.7.0"
- name: Terraform Init
run: terraform -chdir=environments/prod init
- name: Terraform Format
run: terraform -chdir=environments/prod fmt -check -recursive
- name: Terraform Plan
run: terraform -chdir=environments/prod plan -no-color -out=tfplan
- name: Upload plan
uses: actions/upload-artifact@v4
with:
name: tfplan
path: environments/prod/tfplan
terraform-apply:
needs: terraform-plan
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
environment: production
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: tfplan
path: environments/prod
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/github-actions
aws-region: us-east-1
- name: Terraform Apply
run: terraform -chdir=environments/prod apply -auto-approve tfplan
故障应急响应场景中,Terraform的state是一个风险点。State文件损坏或意外删除会导致资源失控——云上资源仍然存在但Terraform无法管理。定期备份State到多个位置(S3版本控制+异地复制),并使用terraform import命令将手动创建的资源导入State进行统一管理。Docker自动化部署与Kubernetes容器编排的环境中,Terraform负责云基础设施层(VPC、EKS、RDS),Helm/Kustomize负责Kubernetes应用层,两者分工明确、协同工作。混沌工程实践中,可通过Terraform快速重建被销毁的基础设施,验证系统的恢复能力。日志分析方面,Terraform的apply日志应接入集中式日志系统,审计所有基础设施变更操作。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/terraforminfrastructureascode-duo-yun-zi-yuan-bian-pai-yu/