Terraform Infrastructure as Code多云资源编排与模块化设计实战

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/

(0)
小编小编
上一篇 6小时前
下一篇 6小时前

相关推荐