实战:使用Terraform在GitHub Actions中自动化配置云资源

8 人参与

在持续交付链路里,基础设施往往被忽视为代码的一环。将 Terraform 融入 GitHub Actions,等于是把云资源的生命周期交给了同一套 CI 引擎,从而实现「提交即部署」的闭环。

为什么在 CI 中使用 Terraform

Terraform 本身具备计划(plan)和应用(apply)的两步安全检查,这正好对应 GitHub Actions 中的「预览」与「实际执行」阶段。利用 GitHub 的事件触发机制,可以在每次 pushpull_request 时自动生成变更预览,审查通过后再由受限的 workflow_dispatch 手动批准,既避免了手动登录云控制台,又把审计日志锁进了 GitHub 的审计记录。

GitHub Actions 工作流结构

典型的 Terraform 工作流包含四个关键步骤:检出代码、设置 Terraform 环境、执行 plan 并上传产物、在受控分支上运行 apply。其中最容易出错的是状态后端的配置——如果使用 S3+DynamoDB 需要提前在安全的 Secrets 中写入 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY,并在工作流里通过 OIDC 动态获取临时凭证。

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

jobs:
  terraform:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write
    steps:
      - uses: actions/checkout@v3
      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v2
        with:
          terraform_version: "1.6.0"
      - name: Authenticate to AWS via OIDC
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsTerraform
          aws-region: us-east-1
      - name: Terraform Init
        run: terraform init -backend-config="bucket=my-terraform-state" -backend-config="key=prod/terraform.tfstate"
      - name: Terraform Plan
        id: plan
        run: terraform plan -out=tfplan
      - name: Upload Plan
        uses: actions/upload-artifact@v3
        with:
          name: tfplan
          path: tfplan
      - name: Apply on Approval
        if: github.event_name == 'workflow_dispatch'
        run: terraform apply tfplan

Terraform 配置要点

后端建议使用远程状态(如 S3 + DynamoDB 锁)避免并发冲突;模块化则是提升可维护性的关键,尤其在多环境(dev、staging、prod)里,只需在根模块里切换变量文件即可。下面示例展示了一个最小化的 backend.tf

# backend.tf
terraform {
  required_version = ">= 1.5.0"
  backend "s3" {
    bucket         = "my-terraform-state"
    key            = "prod/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "terraform-lock"
    encrypt        = true
  }
}

常见陷阱与调试技巧

  • 状态文件泄露:务必在仓库的 .gitignore 中排除 *.tfstate,并在 Secrets 里保存后端凭证。
  • 计划输出过大:使用 terraform plan -no-color 并配合 actions/upload-artifact 分片保存。
  • 并发执行导致锁冲突:在工作流的 concurrency 字段声明唯一键,确保同一分支的运行串行化。

把 Terraform 当作普通代码来对待,配合 GitHub Actions 的审计、分支保护以及 OIDC 的短期凭证,团队可以在数分钟内完成从「代码提交」到「云资源上线」的全链路自动化。只要把这些碎片拼凑进自己的仓库,

参与讨论

8 条评论
  • 刻章冯

    这个配置看起来挺实用的,回头试试看

  • 月光白露

    状态文件用S3确实方便,不过DynamoDB锁有时候会超时

  • 风伴行

    OIDC凭证比直接写AK安全多了,之前用AK总担心泄露

  • 白云悠悠

    有没有更简单的部署方案?感觉步骤有点多

  • 乐于助人

    我们团队用这套流程半年了,确实节省了不少手动操作时间

  • 比翼鸟

    要是能加上多环境自动切换就更完美了🤔

  • The Giggling Giraffe

    这个并发锁的问题我们也遇到过,后来改成串行执行就好了

  • 探春理妆

    terraform plan输出太大咋处理?我们这边经常超限