- DevOps
- CI/CD
- 基础设施
【免费下载链接】atlantis
Terraform Pull Request Automation
本文以 Atlantis(Terraform Pull Request Automation)官方 Requirements 文档为骨架,结合仓库源码逐项验证,系统梳理 Atlantis 对 Git 托管平台、Terraform 状态后端、仓库目录结构、Workspace 与.tfvars文件、Terraform 版本兼容性的要求与最佳实践。读完本文,你将能够对照自己的基础设施仓库逐条核对是否满足 Atlantis 的接入条件,并掌握通过atlantis.yaml与env/目录组织多项目、多工作区、多版本 Terraform 仓库的完整方案。
一、总体要求:Atlantis 兼容大多数 Git 托管与 Terraform 配置
Atlantis 的核心职责是:监听 Webhook 事件 → 检出 PR 代码 → 在隔离的工作目录中执行 Terraform 命令 → 将计划与结果回写到 PR 评论与状态检查。因此,它能否正常工作,取决于 Git 托管平台、Terraform 状态后端、仓库目录结构、Terraform 版本这四类前提是否满足。官方 Requirements 文档 给出了完整的兼容性清单,下文逐一展开,并引用仓库源码与配置作为佐证。
二、Git 托管平台支持矩阵
Atlantis 通过统一的 VCS 客户端抽象与各平台对接,目前官方支持以下 Git 托管:
| Git 托管平台 | 公有云 | 自托管 | 备注 |
|---|---|---|---|
| GitHub | ✔ | ✔ | public、private、GitHub Enterprise |
| GitLab | ✔ | ✔ | public、private、GitLab Enterprise |
| Gitea | ✔ | ✔ | 兼容 Forgejo 等 fork |
| Bitbucket Cloud | ✔ | ✔ | 即 bitbucket.org |
| Bitbucket Server | ✔ | ✔ | 即 Stash |
| Azure DevOps | ✔ | ✔ | — |
在仓库源码中,每个平台都有独立的客户端实现,分别位于 server/events/vcs/github、server/events/vcs/gitlab、server/events/vcs/gitea、server/events/vcs/bitbucketcloud、server/events/vcs/bitbucketserver 与 server/events/vcs/azuredevops。这些实现通过 client.go 中的统一接口(如PullIsMergeable、PullIsApproved、UpdateStatus)被上层调度,因此新增平台可以插件式接入。
三、GitLab 版本要求:detailed_merge_status的取舍
Atlantis 支持 GitLab 当前仍处于积极维护期的版本,但有一个关键细节值得注意:
- GitLab15.6 开始提供
detailed_merge_status字段,Atlantis 使用它进行更精确的 mergeable apply requirement 判定; - 在更早的 GitLab 版本上,Atlantis 会回退到旧的
merge_status字段。该字段可能在一个 MR 分支需要 rebase 时仍报告为 "can_be_merged",从而导致 mergeable 判定不准确。
源码中的佐证非常直观:server/events/vcs/gitlab/client.go 定义了legacyMergeRequest结构体,仅包含MergeStatus(对应旧字段),而 PullIsMergeable 逻辑的注释明确写道:“In GitLab, there isn't a single field that tells us if the pull request is mergeable so for now we check the merge_status and approvals_before_merge fields”;client_test.go 中的测试用例也专门覆盖了“旧版本没有 detailed_merge_status、只能看到 deprecated 的 merge_status=can_be_merged”的场景,测试数据文件如 testdata/detailed-merge-status-need-rebase.json 展示了"merge_status": "can_be_merged"与"detailed_merge_status": "need_rebase"并存的真实响应。
实战建议:如果计划启用mergeable这一 apply/plan 前置条件(详见 Command Requirements),应尽量将 GitLab 升级到 15.6+,以获得准确的 mergeable 判定;无法升级时,需要接受旧的merge_status可能把“需要 rebase 的分支”误判为可合并的已知限制。
四、Terraform 状态后端要求:不支持 local state
Atlantis 支持除本地状态(local state)之外的所有 Terraform 后端类型。原因有两方面:
- Atlantis 没有持久化存储:它按需检出代码、执行命令、清理目录,不维护跨运行持久存在的状态文件存储层;
- 它不会把新生成的 statefile 提交回版本控制:状态文件如果保存在本地工作目录,命令执行完目录即被回收,状态会丢失。
因此,接入 Atlantis 的前提是使用远程状态后端,例如 S3 + DynamoDB Lock、GCS、Azure Storage、Terraform Cloud/Enterprise 等。仓库的测试仓库中也大量使用远程后端,例如 server/events/testdata/test-repos 与 server/controllers/events/testdata/test-repos 下的配置均以远程后端为基线。
官方文档同时推荐:如果需要一个零配置的远程状态方案,可以直接使用 Terraform Cloud 提供的免费远程状态存储,Atlantis 对其完整支持(相关集成还涉及cloud { workspaces { ... } }块的工作区探测,见 Terraform Versions 文档)。
提示:因为支持“所有非本地后端”,你现有的后端配置(如
backend "s3")无需为接入 Atlantis 做任何迁移,只需确认 Atlantis 运行环境具备访问该后端所需的云凭据即可(见 Provider Credentials)。
五、仓库目录结构支持:从单项目到多项目、多模块
Atlantis 支持任意 Terraform 仓库结构,不强制要求特定目录布局。官方文档给出了三类典型结构:
5.1 单项目位于仓库根目录
. ├── main.tf └── ...这种最简单的情形下,仓库根目录即唯一项目,默认配置即可工作,甚至不需要atlantis.yaml。
5.2 多项目目录
. ├── project1 │ ├── main.tf │ └── ... └── project2 ├── main.tf └── ...每个目录是一个独立项目(对应一份独立的 Terraform 状态),PR 修改哪个目录,Atlantis 就计划/应用哪个目录。
5.3 项目 + 共享模块
. ├── project1 │ ├── main.tf │ └── ... └── modules └── module1 ├── main.tf └── ...这里有一个关键点:如果你希望“module1 被修改时自动触发 project1 的计划”,仅靠默认的自动发现是不够的——因为默认按“被修改文件所在目录”定位项目,修改modules/module1/不会映射回project1。此时必须创建atlantis.yaml,并通过autoplan.when_modified显式声明模块路径与项目之间的依赖:
version: 3 projects: - dir: project1 autoplan: when_modified: ["../modules/**/*.tf", "*.tf*", ".terraform.lock.hcl"]注意when_modified的路径是相对于项目目录的,且采用 .dockerignore 语法 中有完整示例)。默认的when_modified为["**/*.tf*", "**/*.tofu", "**/*.tofu.json", "**/terragrunt.hcl", "**/.terraform.lock.hcl"],自定义值会整体覆盖默认值。
从源码看,该机制的实现位于 server/events/project_finder.go:DetermineProjectsViaConfig会先把when_modified模式前拼接项目目录(源码注释 "Prepend project dir to when modified patterns because the patterns are relative to the project dirs"),再用 doublestar 风格的模式匹配modifiedFiles列表,任一文件命中即视为该项目被修改。
六、Terraform Workspaces 支持
Terraform>= 0.9.0起,Atlantis 原生支持 Workspaces(若对 Workspaces 不熟悉,可参考 Terraform 官方 Workspaces 文档)。支持方式是在atlantis.yaml中显式列出同名目录下的多个 Workspace:
version: 3 projects: - dir: project1 workspace: staging - dir: project1 workspace: production当project1目录的配置发生变更时,Atlantis 会同时为staging与production两个 Workspace 运行 plan。针对单个 Workspace 操作时使用:
atlantis plan -w staging -d project1 atlantis apply -w staging -d project1需要留意的是,Workspace 名称的合法性约束(不允许/、\、..、$、空白与控制字符,也不能以-或~开头)在 repo-level-atlantis-yaml.md 的 Project 参数表中有明确说明——该约束来自 Terraform 自身对 Workspace 命名的限制,Atlantis 会直接透传给 Terraform。
七、.tfvars文件的两种使用方式
.tfvars变量文件是区分环境的常见手段。Atlantis 提供两种支持路径:
7.1 自动的env/{workspace}.tfvars文件(零配置)
只要你的仓库按如下结构组织:
. ├── main.tf ├── variables.tf └── env/ ├── default.tfvars ├── staging.tfvars └── production.tfvarsAtlantis 会根据目标 Workspace自动追加-var-file参数,无需任何配置:
atlantis plan→ 自动包含env/default.tfvarsatlantis plan -w staging→ 自动包含env/staging.tfvarsatlantis plan -w production→ 自动包含env/production.tfvars
该特性的源码实现位于 server/core/runtime/plan_step_runner.go:buildPlanCmd会拼接env/<workspace>.tfvars路径并检测其是否存在,存在则追加-var-file <path>参数。源码注释还透露了一个有趣的背景:这一特性源自 Atlantis 最早诞生的公司 Hootsuite 的仓库结构,被保留下来“作为一个致敬,同时也是一个减少重复的好组织方式”。对应测试见 plan_step_runner_test.go(测试名为 "Test that if env/workspace.tfvars file exists we use -var-file option")与 project_finder_test.go(覆盖env/staging.tfvars、env/production.tfvars的发现)。
7.2 自定义.tfvars路径:通过atlantis.yaml指定
如果你的.tfvars文件不在env/目录下(例如放在仓库根目录,或按vars/staging.tfvars组织),就需要在atlantis.yaml中通过自定义工作流显式传入-var-file。以仓库根目录存放staging.tfvars、production.tfvars为例:
version: 3 projects: - dir: . workflow: custom workflows: custom: plan: steps: - init - plan: extra_args: ["-var-file", "staging.tfvars"]更完整的多环境示例可参考 custom-workflows.md(其中还包含用-backend-config区分各环境后端配置的写法)。
选择建议:能使用env/{workspace}.tfvars结构的,优先使用自动方案(零维护);结构更复杂时再引入自定义 workflow。
八、多仓库支持
Atlantis 天然支持多个仓库,唯一硬性前提是为每个仓库都配置好指向 Atlantis 的 Webhook。也就是说,仓库本身的数量没有上限限制,但每个仓库都必须独立完成 Webhook 注册与事件推送(GitHub App 模式下由 App 统一授权多个仓库,见 Configuring Webhooks)。
九、Terraform 版本支持:全版本 + 按项目/仓库差异化
Atlantis 支持所有 Terraform 版本(含 0.12),并允许不同仓库、不同项目使用不同版本,有四种配置途径:
- 服务端默认版本:通过启动参数
--default-tf-version(例如--default-tf-version=v1.3.7)设定全局默认 Terraform 版本; atlantis.yaml按项目指定:
version: 3 projects: - dir: . terraform_version: v1.1.5- Terraform
required_version约束:Atlantis 会读取terraform块中的required_version并自动下载满足约束的最新版本。支持的写法包括:
terraform { required_version = "= 1.2.9" # 精确版本 }terraform { required_version = "~> 1.2.0" # 1.2.x 任意 patch 版本 }terraform { required_version = "~> 1.2" # 1.y.z 任意 minor 版本 }terraform { required_version = ">= 1.2.0" # 至少 1.2.0 }- Terraform 发行版选择:通过
terraform_distribution键切换 OpenTofu:
version: 3 projects: - dir: project1 terraform_distribution: opentofuAtlantis 会自动下载并使用对应发行版。若省略terraform_version,则按所选发行版解析required_version约束(OpenTofu 项目解析到 OpenTofu 版本而非 Terraform 版本)。
优先级规则(官方明确):atlantis.yaml中的terraform_version>--default-tf-version启动参数 > Terraform HCL 中的required_version。完整细节参见 terraform-versions.md。
十、使用atlantis.yaml的边界与安全注意
上文多处出现atlantis.yaml,这里补充三点使用边界(详细配置参考 repo-level-atlantis-yaml.md):
- 并非必须:默认配置(无
atlantis.yaml)已能覆盖“单目录默认 Workspace + 自动发现修改”的主流场景; - 一旦配置
projects,自动发现即被接管:存在projects配置后,Atlantis 不再自行猜测项目位置,每个目录都需显式定义;可通过autodiscover.mode: enabled恢复对未配置目录的自动发现(手动配置的目录优先); - 安全红线:
atlantis.yaml取自 PR 分支,如果允许仓库自定义 workflow(workflows属于受限键,需服务端repos.yaml的allowed_overrides放行),任何能发起 PR 的人都可能在 Atlantis 服务器上执行任意代码。默认情况下这是不允许的,请谨慎评估后再放行。
十一、动手核对清单(Checklist)
按官方文档思路,接入前可对照以下清单逐项确认:
- Git 托管平台在支持矩阵内,且已正确配置 Webhook(每个仓库);
- 使用 GitLab 且依赖
mergeable判定时,版本 ≥ 15.6(否则接受旧merge_status的已知误判); - 所有项目均使用远程状态后端,杜绝 local state;
- 仓库结构明确:单项目根目录 / 多项目目录 / 项目+模块(模块联动记得配
when_modified); - Workspace 项目在
atlantis.yaml中显式列出(Terraform ≥ 0.9.0); .tfvars优先走env/{workspace}.tfvars自动注入,否则用自定义 workflow 传-var-file;- Terraform 版本可统一走
--default-tf-version,特殊项目用terraform_version/required_version覆盖。
以上全部满足后,即可进入下一步:配置 Git Host Access Credentials 并按 Installation Guide 完成安装部署。
- DevOps
- CI/CD
- 基础设施
【免费下载链接】atlantis
Terraform Pull Request Automation
相关推荐
CodeIgniter 3 服务器环境要求全解:PHP 版本与数据库驱动兼容性指南
CodeIgniter 3 服务器环境要求全解:PHP 版本与数据库驱动兼容性指南 导读 本文基于 CodeIgniter 3 官方用户指南的 Server R
后端Web框架Atlantis版本控制:管理Terraform版本兼容性的最佳实践
Atlantis版本控制:管理Terraform版本兼容性的最佳实践 Terraform作为基础设施即代码 IaC 的主流工具,其版本迭代频繁,不同版本间可能存
DevOpsCI/CD基础设施Hyperf环境要求:Linux、PHP、Swoole版本兼容性
Hyperf环境要求:Linux、PHP、Swoole版本兼容性 前言:为什么环境要求如此重要? 还在为Hyperf项目部署时的环境兼容性问题头疼吗?每次升级P
后端Web框架微服务RPC框架异步编程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考