TerraformInfrastructure terraform-infrastructure

使用Terraform进行基础设施即代码(IaC)管理,支持AWS、Azure、GCP等多云平台,实现自动化部署和资源优化。

DevOps 0 次安装 0 次浏览 更新于 3/4/2026

name: terraform-infrastructure description: 基础设施即代码使用Terraform,包含模块化组件、状态管理和多云部署。用于配置和管理云资源。

Terraform Infrastructure

概览

使用Terraform构建可扩展的基础设施即代码,通过声明式配置、远程状态和自动化配置管理AWS、Azure、GCP和本地资源。

使用场景

  • 云基础设施配置
  • 多环境管理(开发、测试、生产)
  • 基础设施版本控制和代码审查
  • 成本跟踪和资源优化
  • 灾难恢复和环境复制
  • 自动化基础设施测试
  • 跨区域部署

实施示例

1. AWS基础设施模块

# terraform/main.tf
terraform {
  required_version = ">= 1.0"

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

  # 远程状态配置
  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和网络
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_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id

  tags = {
    Name = "${var.project_name}-igw"
  }
}

# 私有子网的NAT网关
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_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_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_security_group" "alb" {
  name        = "${var.project_name}-alb-sg"
  description = "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_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 "aws_availability_zones" "available" {
  state = "available"
}

2. 变量和输出

# terraform/variables.tf
variable "aws_region" {
  description = "AWS区域"
  type        = string
  default     = "us-east-1"
}

variable "environment" {
  description = "环境名称"
  type        = string
  validation {
    condition     = contains(["dev", "staging", "production"], var.environment)
    error_message = "环境必须是开发、测试或生产。"
  }
}

variable "project_name" {
  description = "项目名称,用于资源命名"
  type        = string
}

variable "vpc_cidr" {
  description = "VPC的CIDR块"
  type        = string
  default     = "10.0.0.0/16"
}

variable "public_subnets" {
  description = "公共子网CIDR块"
  type        = list(string)
  default     = ["10.0.1.0/24", "10.0.2.0/24"]
}

variable "private_subnets" {
  description = "私有子网CIDR块"
  type        = list(string)
  default     = ["10.0.10.0/24", "10.0.11.0/24"]
}

# terraform/outputs.tf
output "vpc_id" {
  description = "VPC ID"
  value       = aws_vpc.main.id
}

output "vpc_cidr" {
  description = "VPC CIDR块"
  value       = aws_vpc.main.cidr_block
}

output "public_subnet_ids" {
  description = "公共子网IDs"
  value       = aws_subnet.public[*].id
}

output "private_subnet_ids" {
  description = "私有子网IDs"
  value       = aws_subnet.private[*].id
}

output "alb_dns_name" {
  description = "ALB的DNS名称"
  value       = aws_lb.main.dns_name
}

output "alb_arn" {
  description = "ALB的ARN"
  value       = aws_lb.main.arn
}

3. Terraform部署脚本

#!/bin/bash
# deploy-terraform.sh - Terraform部署自动化

set -euo pipefail

ENVIRONMENT="${1:-dev}"
ACTION="${2:-plan}"
TF_DIR="terraform"

echo "Terraform $ACTION for environment: $ENVIRONMENT"

cd "$TF_DIR"

# 初始化Terraform
echo "Initializing Terraform..."
terraform init -upgrade

# 格式化和验证
echo "Validating Terraform configuration..."
terraform fmt -recursive -check .
terraform validate

# 创建/选择工作区
echo "Creating/selecting workspace: $ENVIRONMENT"
terraform workspace select -or-create "$ENVIRONMENT"

# 计划或应用
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!"

最佳实践

✅ 执行

  • 使用远程状态(S3, Terraform Cloud)
  • 实现状态锁定(DynamoDB)
  • 将代码组织成模块
  • 使用工作区管理环境
  • 一致性地应用标签
  • 使用变量以增加灵活性
  • 在应用前进行代码审查
  • 将敏感数据存储在单独的变量文件中

❌ 不执行

  • 在git中本地存储状态文件
  • 使用硬编码值
  • 在单个状态中混合环境
  • 跳过terraform计划审查
  • 使用根模块处理所有内容
  • 在代码中存储秘密
  • 禁用状态锁定

Terraform命令

terraform init        # 初始化Terraform
terraform validate    # 验证配置
terraform fmt         # 格式化代码
terraform plan        # 预览更改
terraform apply       # 应用更改
terraform destroy     # 移除资源
terraform workspace   # 管理工作区

资源