正在加载,请稍候…

生产级 Terraform:模块、远程状态与 Atlantis GitOps

掌握生产环境 Terraform 基础设施管理:可复用模块、S3 远程状态与 DynamoDB 锁定、工作区策略、Terratest 测试及 Atlantis

生产级 Terraform:模块、远程状态与 Atlantis GitOps

Terraform 是基础设施预置的标准。可扩展的 Terraform 代码库与维护噩梦之间的区别在于模块设计和状态管理。

模块结构

infrastructure/
├── modules/
│   ├── vpc/
│   ├── eks-cluster/
│   ├── rds/
│   └── service/
├── environments/
│   ├── staging/
│   │   ├── main.tf
│   │   └── terraform.tfvars
│   └── production/
│       ├── main.tf
│       └── terraform.tfvars
└── global/
    └── iam/

生产级 Terraform:模块、远程状态与 Atlantis GitOps 示意图

生产级 RDS 模块

resource "aws_db_instance" "main" {
  identifier     = var.identifier
  engine         = var.engine
  engine_version = var.engine_version
  instance_class = var.instance_class

  db_name  = var.database_name
  username = var.master_username
  password = var.master_password

  allocated_storage     = var.allocated_storage
  max_allocated_storage = var.max_allocated_storage
  storage_type          = "gp3"
  storage_encrypted     = true

  multi_az            = var.environment == "production"
  deletion_protection = var.environment == "production"
  skip_final_snapshot = var.environment != "production"

  backup_retention_period = var.environment == "production" ? 30 : 7
  performance_insights_enabled = true
  monitoring_interval = 60

  tags = merge(var.tags, {
    Environment = var.environment
    ManagedBy   = "terraform"
  })

  lifecycle {
    ignore_changes = [password]
  }
}

variable "environment" {
  type = string
  validation {
    condition     = contains(["staging", "production"], var.environment)
    error_message = "Environment must be staging or production."
  }
}

生产级 Terraform:模块、远程状态与 Atlantis GitOps 示意图

使用 S3 + DynamoDB 锁定的远程状态

terraform {
  backend "s3" {
    bucket         = "company-terraform-state"
    key            = "production/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    dynamodb_table = "terraform-state-locks"
    role_arn       = "arn:aws:iam::PROD-ACCOUNT:role/TerraformRole"
  }
}

resource "aws_dynamodb_table" "terraform_locks" {
  name         = "terraform-state-locks"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "LockID"

  attribute {
    name = "LockID"
    type = "S"
  }
}

生产级 Terraform:模块、远程状态与 Atlantis GitOps 示意图

使用数据源

data "aws_vpc" "main" {
  tags = { Name = "production-vpc", Environment = "production" }
}

data "aws_secretsmanager_secret_version" "db_pass" {
  secret_id = "production/rds/master-password"
}

module "database" {
  source          = "../../modules/rds"
  identifier      = "production-main"
  environment     = "production"
  vpc_id          = data.aws_vpc.main.id
  master_password = jsondecode(data.aws_secretsmanager_secret_version.db_pass.secret_string)["password"]
}

使用 Terratest 进行集成测试

func TestRDSModule(t *testing.T) {
    t.Parallel()
    opts := &terraform.Options{
        TerraformDir: "../modules/rds",
        Vars: map[string]interface{}{
            "identifier":     "test-rds",
            "environment":    "staging",
            "instance_class": "db.t3.micro",
        },
    }
    defer terraform.Destroy(t, opts)
    terraform.InitAndApply(t, opts)

    endpoint := terraform.Output(t, opts, "endpoint")
    assert.Contains(t, endpoint, "rds.amazonaws.com")
}

Atlantis GitOps

# atlantis.yaml
version: 3
projects:
  - name: staging
    dir: environments/staging
    autoplan:
      enabled: true
      when_modified: ["**/*.tf", "../../modules/**/*.tf"]
    apply_requirements: [approved, mergeable]

  - name: production
    dir: environments/production
    autoplan:
      enabled: false  # Require explicit plan comment
    apply_requirements: [approved, mergeable, undiverged]
    required_approvals: 2

Terraform 的强大之处在于声明式基础设施和提供商生态系统。早期进行模块设计可以节省数月后的重构工作。

→ 使用 Base64 转换器 工具对您的 Terraform 变量文件进行编码。