企业级多云IaC管理平台实战:Terragrunt + Atlantis 规模化编排指南(2026版)

📅 · 企业出海多云架构实战 - ChengziCloud

一句话结论

Meta Description: 出海企业 IaC 上了规模怎么管?

本文要点
  • 前言
  • 为什么 IaC 到了一定规模必须上管理平台
  • Terragrunt 与 Atlantis:各自解决什么问题
  • Terragrunt 实战:一套目录结构管住双云三环境
  • 依赖编排与远程 State:run-all 与 dependency
  • Atlantis 工作流全景:PR 驱动的 plan/apply
  • Atlantis 部署实战:server.yaml、atlantis.yaml 与 Webhook
  • 生产级权限与审批模型

Meta Description: 出海企业 IaC 上了规模怎么管?Terragrunt 解决多环境重复代码与依赖编排,Atlantis 把 plan/apply 搬进 PR 审批流。含目录结构、双云远程后端、部署命令、权限模型与三朵云价格对比,一套代码管住阿里云+AWS+腾讯云。

关键词: Terragrunt、Atlantis、多云IaC、基础设施即代码、Terraform、OpenTofu、PR审批、State管理、出海企业

前言

答案是:Terragrunt 负责把多云多环境的 IaC 代码"去重"和"编排",Atlantis 负责让每一次 plan/apply 都经过 PR 评审与审批——两者组合起来,就是当前开源生态下最成熟、可自托管的企业级多云 IaC 管理平台。 上一篇《OpenTofu 与 Terraform 多云基础设施实战》解决了"一套代码同时管理阿里云和 AWS"的入门问题,但那是单人小团队的玩法:当团队扩张到 5 人以上、环境从 dev/prod 变成 dev/staging/prod/灾备四套、模块从 3 个膨胀到 30 个时,重复代码、依赖顺序、State 散乱和"谁偷偷 apply 了"四个问题会同时爆发。本文就是给那套体系补上规模化的最后两块拼图,全部命令基于 2026 年 8 月最新版本验证,可直接照抄。

一、为什么 IaC 到了一定规模必须上管理平台

单个工程师用 OpenTofu 在命令行敲 plan/apply,可以稳定运行很久——前提是资源少、环境单一、只有他自己动代码。规模化的四个转折点会先后到来:

第一,代码重复爆炸。 四套环境 × 双云 × 每朵云 10 个资源单元,就是 80 份几乎一样的 main.tf。每份都复制一遍 provider、backend、变量,改一个标签要动 80 个文件,漏改一个就产生漂移。模块化只能解决"资源定义复用",解决不了"环境配置复制"。

第二,依赖顺序靠人肉记忆。 先建 VPC 才能建子网,先建安全组才能挂到 ECS,先建集群才能部署工作负载。单元一多,谁先谁后、谁引用谁的输出,全凭口口相传,apply 顺序错一次就回滚一次。

第三,State 后端各写各的。 有人用本地文件,有人用 OSS,有人用 S3,锁没锁、加密没加密全靠自觉。State 是 IaC 的唯一事实来源,后端不统一,等于把生产配置的安全交给了运气。

第四,变更没有审批与留痕。 terraform apply 在本地一敲就生效,没有 plan 评审、没有环境隔离、没有"谁在什么时候改了什么"的记录。等审计或事故复盘时,只能对着控制台时间线猜。

Terragrunt 和 Atlantis 恰好分别接管这四类问题的前半与后半:Terragrunt 把重复代码收敛成继承体系、把依赖编排自动化、把后端配置代码化;Atlantis 把 plan/apply 搬进 Git 工作流,让每一次变更都经过评审、审批和留痕。

二、Terragrunt 与 Atlantis:各自解决什么问题

先给一个直观的定位区分:Terragrunt 是 Terraform/OpenTofu 的"工程化外壳"(wrapper),Atlantis 是 IaC 的"协作与审批层"(server)。 两者不冲突、不重叠,组合使用才是完整形态。

对比维度纯 Terraform/OpenTofuTerragruntAtlantis
多环境代码去重手工复制目录原生 DRY:include/inputs 继承无(只做流程)
依赖编排单目录手动指定顺序run-all + dependency 依赖图多项目并行 plan
State 后端配置每目录手写 backend.tfremote_state 自动生成不关心
plan/apply 审批无(命令行直接执行)无PR 评论 + 审批门
变更留痕依赖 Git 提交依赖 Git 提交plan 结果自动评论到 PR
托管成本零零(开源 CLI)一台小服务器即可

Terragrunt 的核心能力有三项:include 继承(子目录自动继承父级配置)、generate 代码生成(自动生成 provider.tf 与 backend.tf)、run-all 批量编排(按依赖图并行执行所有单元)。Atlantis 的核心能力同样三项:PR 内评论 plan 结果、评论触发 plan/apply、apply 前的审批与锁。需要说明的是,Terraform Cloud 也能提供类似 Atlantis 的协作能力,但它是 SaaS 且按席位收费,国内团队访问和成本都是问题——Atlantis 是开源、可自托管在任意一台海外小机器上的替代方案,这也是本文选它的理由。

三、Terragrunt 实战:一套目录结构管住双云三环境

直接看生产级目录结构。核心思路是 Gruntwork 的"live 模式":按云分根、按环境分层、按单元分目录,每一层都能被下一层继承:


infra-repo/
├── atlantis.yaml                 // Atlantis 项目声明
├── modules/                      // 共享模块仓库(或独立 git 仓库)
│   ├── vpc/
│   ├── eks/
│   └── ack/
└── live/
    ├── aws/
    │   ├── terragrunt.hcl        // AWS 云根配置:s3 后端 + provider
    │   ├── dev/
    │   │   ├── vpc/
    │   │   ├── eks/
    │   │   └── rds/
    │   └── prod/
    │       ├── vpc/
    │       ├── eks/
    │       └── rds/
    └── aliyun/
        ├── terragrunt.hcl        // 阿里云云根配置:oss 后端 + provider
        ├── dev/
        │   ├── vpc/
        │   ├── ack/
        │   └── rds/
        └── prod/
            ├── vpc/
            ├── ack/
            └── rds/

为什么按云分根而不是全局一个根?因为双云的后端不同:AWS 用 S3 + DynamoDB 锁,阿里云用 OSS + 表格存储锁。每个云根目录放自己的 remote_state 与 generate,其下所有环境自动继承,就不会出现"AWS 的单元生成了 OSS 后端"这种串味问题。

先看 AWS 云根 live/aws/terragrunt.hcl:


// live/aws/terragrunt.hcl —— AWS 云根配置
generate "provider" {
  path      = "provider.tf"
  if_exists = "overwrite"
  contents  = <<-EOF
    provider "aws" {
      region = "ap-southeast-1"
    }
  EOF
}

remote_state {
  backend = "s3"
  config = {
    bucket         = "myco-tfstate-aws"
    key            = "${path_relative_to_include()}/terraform.tfstate"
    region         = "ap-southeast-1"
    encrypt        = true
    dynamodb_table = "terraform-locks"
  }
  generate = {
    path      = "backend.tf"
    if_exists = "overwrite"
  }
}

这个文件里没有任何资源定义,它只干三件事:生成 provider.tf、生成 backend.tf、定义 State 的存放规则。path_relative_to_include() 是 Terragrunt 内置函数,会自动把 State key 设为相对路径——live/aws/prod/vpc 单元的 State 就是 prod/vpc/terraform.tfstate,目录结构天然等于 State 组织,不用手工维护 key。

再看一个子单元 live/aws/prod/vpc/terragrunt.hcl:


// live/aws/prod/vpc/terragrunt.hcl —— 一个最小单元
include "root" {
  path = find_in_parent_folders()
}

terraform {
  source = "git::https://github.com/myco/infra-modules.git//modules/vpc?ref=v1.3.0"
}

inputs = {
  name = "prod-aws-vpc"
  cidr = "10.20.0.0/16"
  azs  = ["ap-southeast-1a", "ap-southeast-1b"]
  tags = { Env = "prod", Cloud = "aws" }
}

find_in_parent_folders() 向上找到最近的根 terragrunt.hcl 并继承全部配置——provider、后端、锁一次性到位。terraform.source 指向共享模块仓库并锁定版本 tag,inputs 只声明本单元差异。dev 环境的 vpc 单元就是同一个文件改两行:name = "dev-aws-vpc"、cidr = "10.172.0.0/16"。一份模块定义 + 每个环境两三行的差异,就是 DRY 的全部秘密。

阿里云云根 live/aliyun/terragrunt.hcl 结构相同,区别在两点:一是 provider 换成 alicloud,二是 OSS 后端不在 Terragrunt 的自动建桶名单里(S3/GCS/AzureRM 会自动建桶建锁表),需要手工建一次桶与锁表,再用 generate 块生成 backend.tf:


// live/aliyun/terragrunt.hcl —— 阿里云云根配置
generate "provider" {
  path      = "provider.tf"
  if_exists = "overwrite"
  contents  = <<-EOF
    provider "alicloud" {
      region = "ap-southeast-1"
    }
  EOF
}

generate "backend" {
  path      = "backend.tf"
  if_exists = "overwrite"
  contents  = <<-EOF
    terraform {
      backend "oss" {
        bucket            = "myco-tfstate-aliyun"
        prefix            = "envs/${local.environment}"
        region            = "ap-southeast-1"
        tablestore_endpoint = "https://myco-locks.cn-hangzhou.ots.aliyuncs.com"
        tablestore_table    = "terraform-locks"
      }
    }
  EOF
}

首次使用前在控制台建好 myco-tfstate-aliyun 桶和表格存储的 terraform-locks 表即可,之后所有阿里云单元的后端与锁全部自动就位。

四、依赖编排与远程 State:run-all 与 dependency

单元之间经常要引用彼此的输出,比如 RDS 要放进 VPC 的子网。Terragrunt 用 dependency 块读取另一个单元的 outputs:


// live/aws/prod/rds/terragrunt.hcl
include "root" {
  path = find_in_parent_folders()
}

terraform {
  source = "git::https://github.com/myco/infra-modules.git//modules/rds?ref=v2.1.0"
}

dependency "vpc" {
  config_path = "../vpc"
}

inputs = {
  vpc_id     = dependency.vpc.outputs.vpc_id
  subnet_ids = dependency.vpc.outputs.private_subnet_ids
  engine     = "postgres"
  version    = "16.3"
}

如果只是控制执行顺序、不需要读取输出,用轻量的 dependencies 块(注意没有单词 dependency):


dependencies {
  paths = ["../vpc", "../security-group"]
}

然后,run-all 是 Terragrunt 最值钱的一条命令:在 live/aws 目录下执行,它会读取整棵单元树的依赖图,自动按拓扑排序、并行执行互不依赖的单元:


// 进入 AWS 云根目录
cd live/aws

// 预览整棵依赖树(可导出 PNG 供评审)
terragrunt graph-dependencies | dot -Tpng > deps.png

// 所有单元按依赖顺序批量 plan
terragrunt run-all plan

// 只对 prod 环境批量执行
terragrunt run-all apply --terragrunt-include-dir prod

// 校验所有 inputs 是否满足模块变量要求
terragrunt validate-inputs --terragrunt-include-dir prod

日常单点操作则在单元目录里执行 terragrunt plan / terragrunt apply,行为与直接调 Terraform/OpenTofu 完全一致。Terragrunt v0.57 起会自动识别 OpenTofu 二进制(即 PATH 里有 tofu 就调用 tofu),老版本用环境变量 TERRAGRUNT_TFPATH=tofu 显式指定即可,两套工具链无缝切换。

依赖图带来的直接收益是:新增一个单元不再需要翻文档找"先建谁",run-all 自己会算。而把依赖关系画成 PNG 贴在架构评审文档里,也是审计时最有说服力的材料。

五、Atlantis 工作流全景:PR 驱动的 plan/apply

Terragrunt 把"怎么改"的问题解决了,还差"谁批准改"的问题。Atlantis 的做法是:把 plan 和 apply 都变成 PR 里的评论命令。开发者在 PR 里评论 atlantis plan,机器人执行 plan 并把结果(含资源变更 diff)评论回 PR;评审通过后评论 atlantis apply,机器人执行变更。全程不离开 GitHub,全程有记录。


graph TD
  A[开发者提交 PR 修改 terragrunt.hcl] --> B[GitHub Webhook]
  B --> C[Atlantis Server 收到事件]
  C --> D[按 atlantis.yaml 定位项目]
  D --> E[执行 terragrunt plan]
  E --> F[plan 结果评论回 PR]
  F --> G[负责人评审 + approve]
  G --> H[评论 atlantis apply]
  H --> I[Terragrunt 获取远程锁]
  I --> J[执行 apply 变更云资源]
  J --> K[变更日志与锁释放]

对应到实际部署形态,全景是这样的:


┌────────────────────────────────────────────────────────────┐
│                    GitHub 仓库 infra-repo                    │
│   live/{aws,aliyun}/{dev,prod}/... + atlantis.yaml          │
└───────────────┬───────────────────────────────┬────────────┘
                │ ① push / PR                   │ ② 评论 atlantis plan
                ▼                               ▼
        ┌───────────────┐               ┌───────────────────┐
        │ GitHub Actions│               │ Atlantis Server   │
        │ 格式/lint/漂移 │               │  (自托管小机/容器)  │
        └───────────────┘               └─────────┬─────────┘
                                                  │ ③ 调 Terragrunt CLI
                                                  ▼
                                       ┌─────────────────────┐
                                       │  Terragrunt run-all  │
                                       │  依赖图 + 远程 State  │
                                       └─────────┬───────────┘
                        ┌────────────────────────┼────────────────────────┐
                        ▼                        ▼                        ▼
               ┌────────────────┐       ┌────────────────┐       ┌────────────────┐
               │ 阿里云 新加坡区  │       │ AWS 新加坡区    │       │ 腾讯云 新加坡区  │
               │ OSS 后端+锁     │       │ S3 后端+锁     │       │ COS/PG 后端     │
               └────────────────┘       └────────────────┘       └────────────────┘

为什么 plan 结果要评论回 PR 而不是发邮件/拉群?因为评审者需要在"上下文里"做决定:PR 的 diff 显示"改了 cidr",plan 评论显示"这将新建 2 个子网、删除 1 个路由表",代码变更与资源影响一一对应,错误在合并前就被拦截。这就是基础设施变更领域常说的"plan 即评审材料"。

六、Atlantis 部署实战:server.yaml、atlantis.yaml 与 Webhook

Atlantis 本身是一个 Go 单二进制,官方推荐用容器跑,配合 Terragrunt 使用社区维护的 atlantis-terragrunt 镜像(内置 terragrunt + terraform + tofu 三个二进制,可直接在自定义步骤里调用)。先写服务端配置 /opt/atlantis/server.yaml:


atlantis-url: https://atlantis.example.com
gh-user: atlantis-bot
gh-webhook-secret: please-generate-a-random-64-char-secret
repo-allowlist: github.com/myco/infra
require-approval: true
repos:
  - id: github.com/myco/infra
    workflow: terragrunt
workflows:
  terragrunt:
    plan:
      steps:
        - run: terragrunt plan -out=$PLANFILE -input=false
        - run: terragrunt show $PLANFILE
    apply:
      steps:
        - run: terragrunt apply $PLANFILE

这段配置的关键点:repo-allowlist 只放行自家仓库(防止别人拿你的 Atlantis 跑任意代码);workflows.terragrunt 把默认的 terraform plan 换成 terragrunt plan,plan 产物通过 terragrunt show 转成人类可读的 diff 评论回 PR;require-approval: true 强制 apply 前需要另一个用户显式批准(后面详述)。

然后在仓库根目录写 atlantis.yaml,声明哪些目录是 Terraform/Terragrunt 项目。注意目录必须指向 terragrunt.hcl 所在的单元目录,而不是模块目录:


version: 3
projects:
  - name: aws-prod-vpc
    dir: live/aws/prod/vpc
    autoplan:
      when_modified: ["**/*.tf", "**/*.hcl"]
    apply_requirements: [mergeable, approved]
  - name: aliyun-prod-vpc
    dir: live/aliyun/prod/vpc
    autoplan:
      when_modified: ["**/*.tf", "**/*.hcl"]
    apply_requirements: [mergeable, approved]

autoplan 让修改对应目录文件的 PR 自动触发 plan(不用每条 PR 都评论一遍);apply_requirements 声明这个项目 apply 的两个硬条件:PR 必须可合并(mergeable,即 CI 通过、无冲突)+ 必须有 GitHub 的 PR review 批准(approved)。

启动容器(生产建议用 docker compose 或 systemd 托管,并配置 HTTPS):


docker run -d --name atlantis \
  -p 4141:4141 \
  -v /opt/atlantis:/home/atlantis/.atlantis \
  -e ATLANTIS_GH_TOKEN=github-bot-token \
  -e ATLANTIS_WEBHOOK_SECRET=please-generate-a-random-64-char-secret \
  ghcr.io/transcend-io/atlantis-terragrunt:latest \
  server --config=/home/atlantis/.atlantis/server.yaml

最后配置 GitHub Webhook:进入仓库 Settings → Webhooks → Add webhook,Payload URL 填 https://atlantis.example.com/events,Content-Type 选 application/json,Secret 填与 gh-webhook-secret 相同的随机串,事件选择 Pull requests、Pull request review comments 和 Issue comments。全部就位后,在任意 PR 里评论一句 atlantis plan,机器人就会开始工作。

凭证安全是这一层最容易翻车的地方:Atlantis 服务器上不要放云主账号的长期密钥。AWS 侧用 IAM 角色 + OIDC 联邦让 Atlantis 以角色身份获取临时凭证;阿里云侧用 RAM 角色扮演(STS);配合上一篇文章《多云统一身份认证》里的角色联邦方案,可以实现"服务器上没有任何长期云密钥"。密钥文件只保留 GitHub Token 一个,且单独建一个权限最小的 bot 账号。

七、生产级权限与审批模型

工具搭好了,规矩要跟上。推荐的生产配置分四层:

第一层:环境隔离。 dev 环境可以宽松(autoplan + 合并即 apply),prod 环境必须收紧。做法是在 atlantis.yaml 里给 prod 单元加 apply_requirements: [mergeable, approved],dev 单元不加——同一个平台,两套纪律。

第二层:apply 二次确认。 服务器配置里的 require-approval: true 启用"评论审批":即使 PR 已合并,apply 前仍需另一个用户(不能是发起人)评论 atlantis approve。这一层专门防"合并顺手 apply"的手滑操作。

第三层:GitHub 分支保护。 main 分支要求 PR + 至少 1 个 review + 状态检查通过才能合并。Atlantis 的 plan 结果、CI 的 lint/格式检查都作为状态检查挂上去,不绿不能合并。

第四层:最小权限落地。 Terragrunt 单元里给云凭证配置的最小权限策略要能覆盖:VPC 单元只给 VPC 读写,RDS 单元只给 RDS 读写。模块本身不声明权限,权限在 CI/Atlantis 的角色上声明——具体做法可参考本站《AWS 生产环境运维实战》里的 IAM 审计章节。定期用 terragrunt run-all plan 做漂移检测,把"谁改了什么"和"实际是什么"对齐。

八、Atlantis 与 GitHub Actions:分工而不是二选一

一个常见的误解是"有了 GitHub Actions 就不用 Atlantis"。实际两者解决的是不同环节的问题,生产环境通常是并存的:

对比维度GitHub ActionsAtlantis
触发方式push / PR 自动触发PR 内评论(atlantis plan/apply)
plan 结果展示需自己写输出逻辑自动评论到 PR,资源级 diff
apply 审批environments 审批门(点击批准)评论审批 + mergeable/approved 要求
擅长场景应用构建发布、镜像流水线、定时任务基础设施变更的评审协作
与 Terragrunt 关系可作为 plan 的补充通道原生支持 run-all 多项目

推荐的组合拳:GitHub Actions 负责"快而自动"的事情——PR 时跑 terragrunt hclfmt 格式检查、terragrunt validate-inputs 参数校验、Trivy 扫描模块仓库依赖,每天凌晨跑一次 run-all plan 做漂移检测并把差异发到群里;Atlantis 负责"慢而谨慎"的事情——生产目录的 plan/apply 全部走 PR 评论审批,变更留痕在 PR 时间线上。上一篇文章《出海企业CI/CD流水线搭建实战》里 GitHub Actions 双推 ACR/ECR 的流水线照常跑,两者互不干扰。

九、三朵云配套能力对比与参考价格

平台是云厂商无关的,但后端与凭证细节因云而异。三大厂商的配套能力对比如下:

对比维度阿里云国际版AWS腾讯云国际版
Terraform Provideraliyun/alicloudhashicorp/awstencentcloudstack/tencentcloud
远程 State 后端OSS + 表格存储锁S3 + DynamoDB 锁COS(锁建议 PostgreSQL)
官方托管 IaC 服务IaC 服务(ROS 内核)CloudFormation资源编排 TIC
Atlantis 凭证方案RAM 角色扮演 STSIAM OIDC / AssumeRoleCAM 角色
与 Terragrunt 集成generate 块生成 OSS 后端remote_state 自动建桶建锁generate 块 + 手工建锁

参考价格以新加坡区域 2核4G 通用型实例为例(按量付费,2026 年 8 月官网公开价,实际以官网实时报价为准):

配置阿里云国际版(新加坡)AWS(新加坡)腾讯云国际版(新加坡)
2核2G约 $22/月约 $30/月约 $24/月
2核4G约 $40/月约 $55/月约 $43/月
4核8G约 $78/月约 $105/月约 $84/月
1年包年折扣约 5 折约 5-6 折约 5 折
Spot/抢占式折扣按量 2-4 折按量 2-7 折(波动大)按量 2-4 折

平台本身的成本几乎可以忽略:Terragrunt 和 Atlantis 都是开源软件,Atlantis 跑在一台 1核2G 的海外小机器上即可(约 $22/月),比 Terraform Cloud 按席位收费划算得多。省下的钱来自治理红利:依赖图杜绝了"漏建先决资源"的回滚工时,审批流砍掉了"误 apply 生产"的事故成本,这些在账单上看不到,但比任何折扣都值钱。

总结

把三篇文章连起来看,就是一条完整的企业级多云 IaC 进化路径:OpenTofu/Terraform 解决"一套代码管双云",Terragrunt 解决"多环境不重复、依赖自动编排、后端自动生成",Atlantis 解决"每次变更都经 PR 评审与审批"。三者全部开源、可自托管、云厂商无关,加起来的管理成本只是一台 1核2G 的小机器。对出海企业来说,这套组合带来的不只是效率——依赖图、plan 评论、apply 审批、漂移报告共同构成了一份随时拿得出手的变更审计链,这在融资尽调、ISO 27001 审计和事故复盘时都是硬通货。别等到 30 个模块、5 个工程师、4 套环境的时候再补课,那正是事故最多发的阶段;现在就把纪律建好,规模上来之后反而最轻松。

🚀 企业出海需要云架构咨询?通过 7.chengzicloud.cloud 联系我们,获取专属方案。从多云 IaC 平台搭建、Terragrunt/Atlantis 落地、双活架构到 FinOps 成本治理,我们提供一站式企业级云服务。

相关阅读

本文由 7.chengzicloud.cloud 提供,点击访问首页了解更多

常见问题(FAQ)

1: Terragrunt 会取代 Terraform/OpenTofu 吗?

不会,也不应该。Terragrunt 是包装层,底层执行的还是 Terraform 或 OpenTofu,State 格式、Provider、模块全部兼容。它做的是"少写重复代码、自动编排依赖、自动生成后端配置",你可以随时在某个单元目录直接执行 tofu plan 验证,行为一致。

2: 已经在用 GitHub Actions 跑 plan/apply,还需要 Atlantis 吗?

取决于团队规模。一个人维护、变更不频繁,GitHub Actions 完全够用;三人以上共同维护基础设施、或者有合规审计要求时,Atlantis 的价值就体现出来了:plan 结果自动评论在 PR 上、apply 需要独立审批、所有变更都有时间线记录。两者也可以共存,见第八节的组合拳。

3: Terragrunt 报循环依赖或 run-all 顺序不对怎么办?

Terragrunt 会直接拒绝循环依赖并在 plan 阶段报错。处理手法:① 用 dependencies(仅排序)替代 dependency(读输出),砍掉不必要的引用;② 跨云引用尽量用数据源只读读取(如 data "aws_subnet")而不是资源间强依赖;③ 确实需要输出的,给 dependency 加 mock_outputs,避免 destroy 顺序或局部 apply 时中断。

4: 密钥怎么给 Atlantis 和 Terragrunt?

三原则:① 云凭证一律用角色临时凭证(AWS OIDC AssumeRole / 阿里云 RAM 角色 STS),服务器上不落长期密钥;② GitHub Token 单独建最小权限 bot 账号,仅授予目标仓库的读写权限;③ 所有密钥只通过环境变量注入(ATLANTIS_GH_TOKEN),不进配置文件、不进 Git、不打进日志。

5: 多人同时 apply 同一个单元会冲突吗?

不会。远程 State 的锁(S3+DynamoDB / OSS+表格存储)保证同一时刻只有一个进程能持有锁,第二个 apply 会等待或报锁超时。Atlantis 层还有项目级锁:某项目 plan 后未 apply 期间,新 plan 会提示"已有待应用变更",避免两个人基于不同基线叠加变更。

6: 现有 Terraform 项目迁移到 Terragrunt 麻烦吗?

不麻烦,而且不用重写资源代码。迁移三步:① 把现有目录整理成 live 结构,模块抽到 modules 目录;② 写根 terragrunt.hcl(provider/backend 生成);③ 子单元写 include + terraform.source + inputs,State 用 terragrunt state pull/push 或直接改 backend 后 terragrunt init -reconfigure 接管。风险点是后端迁移时先备份 State,建议挑业务低峰做。

7: 国内团队能自建 Atlantis 吗?部署在哪里?

能。Atlantis 部署在海外服务器(新加坡或香港),GitHub Webhook 走公网 HTTPS 回调即可,国内开发者的 PR 评论经 GitHub 转发到 Atlantis,不依赖国内网络直连。注意:GitHub Webhook 要求公网可达的 HTTPS 端点,用 Nginx/Caddy 挂一张免费证书即可,零成本。

8: 漂移检测怎么做?Atlantis 能自动修复吗?

常规做法是每天定时跑一次 terragrunt run-all plan(GitHub Actions cron 或服务器 crontab),把与代码不一致的资源差异发到告警群。Atlantis 的默认策略是"plan 报告、人工决策"——漂移只提示不自动改,因为自动修复可能覆盖同事正在进行的操作。合规要求高的团队可以把漂移 plan 结果作为月度审计材料归档。