使用 atlantis 做 terraform automation,Terraform Remote Plan & Remote Apply
课程内容与代码会放在 Github 上: https://github.com/chechiachang/terraform-30-days
赛後文章会整理放到个人的部落格上 http://chechia.net/
如果使用 github.com,完全可以使用 Github Action,来执行 terraform automation,除了本课程内有提供范例外,网路上已经有更多的范例可以参考
然而有些 version control system 是不方便使用 Github Action
这时可以考虑使用公司的 CI / CD 系统,自行写 terraform 的 pipeline,然後整理前述课程使用到的 command 写成 shell script 执行。只要是知名的 CI / CD 工具,都能找到许多 terraform 的 pipeline 范例,而这些范例多半是共通的。
如果不希望自己维护 terraform pipeline,现在已经有开源版本的整合工具,帮你做自动化,就是这张要介绍的 Atlantis: Pull Request Automation
参考 terraform-30-days 上 实际执行的 PR 范例
Atlantis 是一款开源免费的自动化 terraform 工具。基本工作流程很单纯
Features
官方说明文件试跑 Atlantis Local Run,主要步骤为
Install atlantis
wget https://github.com/runatlantis/atlantis/releases/download/v0.17.2/atlantis_darwin_amd64.zip
unzip atlantis_darwin_amd64.zip
sudo mv atlantis /usr/local/bin/atlantis
atlantis -h
Install ngrok and run
wget https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-darwin-amd64.zip
unzip ngrok-stable-darwin-amd64.zip
sudo mv ngrok /usr/local/bin/ngrok
./ngrok http 4141
...
Forwarding http://41eb-123-194-159-122.ngrok.io -> http://localhost:4141
...
Config Github Webhook
Create Github Personal Access token
Local Run atlantis server
export URL="https://...................ngrok.io"
export SECRET="ep.................quh"
export TOKEN="ghp_..........................."
export USERNAME="chechiachang"
export REPO_ALLOWLIST="github.com/chechiachang/terraform-30-days"
atlantis server \
--atlantis-url="${URL}" \
--gh-user="${USERNAME}" \
--gh-token="${TOKEN}" \
--gh-webhook-secret="${SECRET}" \
--repo-allowlist="$REPO_ALLOWLIST"
...
{"level":"info","ts":"2021-08-31T23:03:31.616+0800","caller":"server/server.go:680","msg":"Atlantis started - listening on port 4141","json":{}}
在 Github terraform-30-days 的范例
comment atlantis help
atlantis
Terraform Pull Request Automation
...
comment atlantis plan -d azure/_poc/compute/
# atlantis log
# parse comment as command
{"level":"info","ts":"2021-08-31T23:47:23.483+0800","caller":"events/events_controller.go:417","msg":"parsed comment as command=\"plan\" verbose=false dir=\"azure/_poc/compute\" workspace=\"\" project=\"\" flags=\"\"","json":{}}
# acquired lock with id
{"level":"info","ts":"2021-08-31T23:47:24.378+0800","caller":"events/project_locker.go:80","msg":"acquired lock with id \"chechiachang/terraform-30-days/azure/_poc/compute/default\"","json":{"repo":"chechiachang/terraform-30-days","pull":"6"}}
# terraform init
{"level":"info","ts":"2021-08-31T23:47:31.435+0800","caller":"terraform/terraform_client.go:280","msg":"successfully ran \"/Users/che-chia/.asdf/shims/terraform init -input=false -no-color\" in \"/Users/che-chia/.atlantis/repos/chechiachang/terraform-30-days/6/default/azure/_poc/compute\"","json":{"repo":"chechiachang/terraform-30-days","pull":"6"}}
# terraform workspace
{"level":"info","ts":"2021-08-31T23:47:31.959+0800","caller":"terraform/terraform_client.go:280","msg":"successfully ran \"/Users/che-chia/.asdf/shims/terraform workspace show\" in \"/Users/che-chia/.atlantis/repos/chechiachang/terraform-30-days/6/default/azure/_poc/compute\"","json":{"repo":"chechiachang/terraform-30-days","pull":"6"}}
# terraform plan
{"level":"info","ts":"2021-08-31T23:47:48.746+0800","caller":"terraform/terraform_client.go:280","msg":"successfully ran \"/Users/che-chia/.asdf/shims/terraform plan -input=false -refresh -no-color -out \\\"/Users/che-chia/.atlantis/repos/chechiachang/terraform-30-days/6/default/azure/_poc/compute/default.tfplan\\\"\" in \"/Users/che-chia/.atlantis/repos/chechiachang/terraform-30-days/6/default/azure/_poc/compute\"","json":{"repo":"chechiachang/terraform-30-days","pull":"6"}}
# policy check
{"level":"info","ts":"2021-08-31T23:47:50.017+0800","caller":"events/plan_command_runner.go:214","msg":"Running policy check for command=\"plan\" verbose=false dir=\"azure/_poc/compute\" workspace=\"\" project=\"\" flags=\"\"","json":{"repo":"chechiachang/terraform-30-days","pull":"6"}}
{"level":"info","ts":"2021-08-31T23:47:50.017+0800","caller":"events/policy_check_command_runner.go:36","msg":"no projects to run policy_check in","json":{"repo":"chechiachang/terraform-30-days","pull":"6"}}
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+ create
<= read (data resources)
Terraform will perform the following actions:
# module.linuxservers.data.azurerm_public_ip.vm[0] will be read during apply
# (config refers to values not yet known)
<= data "azurerm_public_ip" "vm" {
...
}
Plan: 9 to add, 0 to change, 0 to destroy.
Apply 也很单纯,就是 apply
atlantis apply -d azure/_poc/compute/
注意:这边 apply 下去就会自动 apply,没有 double comfirm yes or no 了
{"level":"info","ts":"2021-08-31T23:38:43.963+0800","caller":"events/events_controller.go:417","msg":"parsed comment as command=\"apply\" verbose=false dir=\"azure/_poc/compute\" workspace=\"\" project=\"\" flags=\"\"","json":{}}
{"level":"info","ts":"2021-08-31T23:38:45.151+0800","caller":"events/apply_command_runner.go:110","msg":"pull request mergeable status: true","json":{"repo":"chechiachang/terraform-30-days","pull":"6"}}
{"level":"info","ts":"2021-08-31T23:38:45.157+0800","caller":"runtime/apply_step_runner.go:38","msg":"starting apply","json":{"repo":"chechiachang/terraform-30-days","pull":"6"}}
{"level":"info","ts":"2021-08-31T23:40:05.868+0800","caller":"terraform/terraform_client.go:280","msg":"successfully ran \"/Users/che-chia/.asdf/shims/terraform apply -input=false -no-color \\\"/Users/che-chia/.atlantis/repos/chechiachang/terraform-30-days/6/default/azure/_poc/compute/default.tfplan\\\"\" in \"/Users/che-chia/.atlantis/repos/chechiachang/terraform-30-days/6/default/azure/_poc/compute\"","json":{"repo":"chechiachang/terraform-30-days","pull":"6"}}
{"level":"info","ts":"2021-08-31T23:40:05.868+0800","caller":"runtime/apply_step_runner.go:57","msg":"apply successful, deleting planfile","json":{"repo":"chechiachang/terraform-30-days","pull":"6"}}
实际运作的 gitflow,大约是这样
使用 atlnatis 有底下优缺点
缺点是要多养一台或多台 atlantis server,然而 atlantis server 基本上是 stateless server,如果有 k8s 的话非常好养
上面只是在本地电脑测试一下 atlantis 的功能,实际上如果要让 production 环境使用,还有以下代办事项要处理
atlantis default 使用 terraform cmd,然而本课程有许多范例使用 terragrunt,atlantis 也支援,需要底下额外设定
(大家先自己研究,我有时间会来补的(汗))
Terraform Cloud 是 terraform 官方提供的 Terraform automation Saas 服务
需要收费,请见 terraform cloud pricing。然而也提供更多强大的功能,除了 atlantis 的 remote plan 与 remote apply 外,还有私有 module registry,state file 版本控管...等功能
目前不是本课程推荐的解决方案,但 terraform cloud 不断推陈出新许多新功能,未来值得期待。本课程会依据後续参赛进度调整,有机会再分享 terraform cloud 内容。
<<: 从零开始的8-bit迷宫探险【Level 3】Swift 基础语法 (一)
>>: EP 3: Use Shell to layout TopStore App
前言 这是 Obsidian 使用教学 — 基础篇的第 4 篇文章。 上一篇文章 我详细介绍了「Th...
大家好,我是韦恩,今天是第二十八天,让我们会练习获取extension的api,为专案的重点功能做准...
「鲑鱼均,因为一场鲑鱼之乱被主管称为鲑鱼世代,广义来说以年龄和脸蛋分类的话这应该算是一种 KNN 的...
承接上篇,抓日成交资讯时,我们得知道股票代码,那如果我想要有一个可以定时更新的股票代码清单,要去哪里...
以前我们在写Vue时data都是这样写 但是到了元件这可能就会出现错误,前面我们的data属性总是以...