Terraform多云资源编排实战:基础设施即代码与状态管理方案

Terraform是HashiCorp开源的基础设施即代码(IaC)工具,通过声明式配置文件管理云资源生命周期。DevOps实践中,Terraform已成为多云资源编排的标准方案。相比手动控制台操作,IaC方式可实现版本管理、代码审查和自动化部署,显著降低配置漂移风险。

Terraform核心概念与工作流

Terraform的执行流程分四个阶段:init(初始化后端和Provider插件)、plan(生成执行计划)、apply(执行变更)、destroy(销毁资源)。配置文件使用HCL(HashiCorp Configuration Language)语法,以resource块定义资源。

# main.tf - 基础配置结构
terraform {
  required_version = ">= 1.5.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
    alibaba = {
      source  = "aliyun/alicloud"
      version = "~> 1.220"
    }
  }
  backend "s3" {
    bucket         = "terraform-state-prod"
    key            = "infra/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    dynamodb_table = "terraform-locks"
  }
}

provider "aws" {
  region = "us-east-1"
}

provider "alicloud" {
  region = "cn-hangzhou"
}

backend配置决定状态文件存储位置。S3后端配合DynamoDB表实现状态锁,防止多人同时执行apply导致状态冲突。生产环境务必启用encrypt=true,状态文件中可能包含敏感信息。

多云资源编排实战

多云场景下,Terraform通过不同Provider管理各云厂商资源。以下示例在AWS和阿里云分别部署VPC和ECS实例,实现多云容灾架构。

# AWS VPC与EC2
resource "aws_vpc" "main" {
  cidr_block           = "10.10.0.0/16"
  enable_dns_support   = true
  enable_dns_hostnames = true
  tags = { Name = "prod-vpc", Env = "production" }
}

resource "aws_subnet" "web" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = "10.10.1.0/24"
  availability_zone       = "us-east-1a"
  map_public_ip_on_launch = true
  tags = { Name = "web-subnet" }
}

resource "aws_instance" "web_server" {
  ami                    = "ami-0c7217cdde87094e3"
  instance_type          = "t3.large"
  subnet_id              = aws_subnet.web.id
  vpc_security_group_ids = [aws_security_group.web.id]
  user_data              = file("init.sh")
  tags = { Name = "web-server-01", Env = "production" }
}

# 阿里云ECS
resource "alicloud_instance" "backup" {
  instance_type        = "ecs.g6.large"
  image_id             = "ubuntu_22_04_x64"
  security_groups      = [alicloud_security_group.default.id]
  instance_name        = "backup-server-01"
  internet_charge_type = "PayByTraffic"
  system_disk_category = "cloud_essd"
  system_disk_size     = 100
  tags = { Name = "backup-server", Env = "production" }
}

多云编排的关键是资源依赖管理。Terraform自动解析资源间依赖关系(如ECS引用Security Group),必要时可用depends_on显式声明依赖。跨云资源的引用需要通过variable和output传递数据。

状态文件管理与远程后端

状态文件(terraform.tfstate)记录所有资源的当前状态,是Terraform的核心数据。本地状态文件存在团队协作冲突和数据丢失风险,生产环境必须使用远程后端。

# 状态文件隔离方案 - 使用workspaces
terraform workspace new dev
terraform workspace select dev
terraform apply -var-file="dev.tfvars"

terraform workspace new prod
terraform workspace select prod
terraform apply -var-file="prod.tfvars"

terraform workspace show

Workspace实现同一配置文件管理多套环境,状态文件自动隔离。但Workspace隔离不等于安全隔离——有prod权限的人也能切换到dev workspace。更严格的隔离方案是使用独立的backend key,每个环境一个独立的state文件路径。

模块化配置与代码复用

将通用资源组合封装为Module,提高配置复用性。Module结构示例:

# modules/vpc/main.tf
variable "cidr_block" {
  type    = string
  default = "10.0.0.0/16"
}

variable "environment" {
  type    = string
  default = "dev"
}

variable "az_count" {
  type    = number
  default = 2
}

resource "aws_vpc" "this" {
  cidr_block = var.cidr_block
  tags       = { Environment = var.environment }
}

resource "aws_subnet" "public" {
  count             = var.az_count
  vpc_id            = aws_vpc.this.id
  cidr_block        = cidrsubnet(var.cidr_block, 8, count.index)
  availability_zone = data.aws_availability_zones.available.names[count.index]
  tags              = { Tier = "public" }
}

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

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

# 调用Module
module "prod_vpc" {
  source      = "./modules/vpc"
  cidr_block  = "10.20.0.0/16"
  environment = "production"
  az_count    = 3
}

Module版本管理推荐使用Git tag。私有Module可通过Terraform Registry或直接引用Git仓库:source = “git::https://github.com/company/tf-modules.git//vpc?ref=v1.2.0”

CI/CD集成与自动化流水线

Terraform与CI/CD流水线集成实现自动化基础设施变更。GitHub Actions或GitLab CI中,每次Pull Request自动运行terraform plan并将结果评论到PR页面,人工审核通过后合并触发apply。

# .github/workflows/terraform.yml
name: Terraform CI/CD
on:
  pull_request:
    branches: [main]
  push:
    branches: [main]

jobs:
  terraform:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: hashicorp/setup-terraform@v3
        with:
          terraform_version: "1.5.7"
      - name: Terraform Init
        run: terraform init
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_KEY }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET }}
      - name: Terraform Plan
        if: github.event_name == 'pull_request'
        run: terraform plan -no-color
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_KEY }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET }}
      - name: Terraform Apply
        if: github.event_name == 'push' && github.ref == 'refs/heads/main'
        run: terraform apply -auto-approve
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_KEY }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET }}

安全要点:云平台密钥通过CI/CD Secrets注入,不出现在代码仓库中。Apply操作仅限main分支push触发,Plan可在PR阶段运行。建议配合Terraform Cloud或Atlantis实现更完善的审批流程。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/terraform-duo-yun-zi-yuan-bian-pai-shi-zhan-ji-chu-she-shi/

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

相关推荐