如何在GitHub Actions中使用Terragrunt和tfcmt来使计划结果更易于阅读
我想做的事情
我在使用GitHub Actions中的Terragrunt时,正在研究如何在pull request中评论plan结果。
虽然我能够直接评论plan结果,但我想知道是否有更好的方法,所以我决定尝试与tfcmt结合使用。
Terragrunt是什么?
Terragrunt是一个轻量级的封装工具,它使得Terraform更加方便。
它能够将设置保持DRY,并且使得管理多个Terraform模块和远程状态变得更加容易。
如果Terraform的状态被分为多个目录,并且存在依赖关系,我认为这是一个非常实用的工具。
由于它拥有许多便利功能,所以我想如果您还没有使用过它,一定要尝试一次。
Tfcmt是什么?
tfcmt 是一个CLI工具,将terraform plan和apply的结果作为评论通知到GitHub的Pull Request(以下简称PR)中。
使用该工具可以在PR页面上直接查看结果,无需查看CI日志。
而且相较于原始日志,结果更加清晰易懂的特点。
如何使用tfcmt
使用以下方式替换terraform plan 和terraform apply.
$ tfcmt plan -- terraform plan [terraform plan の引数...]
$ tfcmt apply -- terraform apply [terraform apply の引数...]
如果将terraform命令直接替换为terragrunt命令,由于无法使用run-all选项,因此需要稍加修改。
使用Terragrunt和tfcmt的组合方法
在terragrunt命令的选项中指定–terragrunt-tfpath。通过这个选项,您可以指定在Terragrunt内部执行的terraform命令所替代的可执行文件。通过指定到像下面的shell脚本的路径,您可以自定义terraform命令的行为。
terragrunt run-all plan --terragrunt-tfpath $GITHUB_WORKSPACE/.github/scripts/tfwrapper.sh
#!/bin/bash
set -euo pipefail
# コマンドの種類を取得(例: apply, plan, fmt...)
type=$(echo "$@" | awk '{print $1}')
# 実行しているディレクトリ名を取得
current_dir=$(pwd | sed 's/.*\///g')
if [ "$type" == "plan" ]; then
# planのときは-patchオプションを付ける
# 実行ディレクトリ名をターゲットとして指定
tfcmt -var "target:${current_dir}" plan -patch -- terraform "$@"
elif [ "$type" == "apply" ]; then
tfcmt -var "target:${current_dir}" apply -- terraform "$@"
else
terraform "$@"
fi
我会根据terraform命令的类型进行条件分支。
在执行plan和apply时,会运行tfcmt命令,但是在执行plan时会加上-patch选项来减少评论的数量。
其他命令将直接执行。
另外,在tfcmt中,可以通过使用“-var”选项来区分每个结果,例如“target:foo”,通过标签的前缀来区分。我们利用此功能将执行目录名称指定为目标。
示例代码
.
├── .github
│ ├── scripts
│ │ └── tfwrapper.sh
│ └── workflows
│ └── plan.yml
└── app
├── envs
│ ├── dev
│ │ ├── app
│ │ │ ├── 〇〇.tf
│ │ │ └── terragrunt.hcl
│ │ ├── cicd
│ │ │ ├── 〇〇.tf
│ │ │ └── terragrunt.hcl
│ │ ├── db
│ │ │ ├── 〇〇.tf
│ │ │ └── terragrunt.hcl
│ │ └── ...
│ └── prod
├── modules
│ ├── acm
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ └── variables.tf
│ ├── cloudfront
│ ├── cognito
│ └── ...
└── shared
├── provider.tf
├── variables.tf
└── version.tf
name: Terraform plan
on:
pull_request:
branches:
- main
- develop
types:
- opened
- synchronize
env:
AWS_REGION: ap-northeast-1
PROJECT: sample
TF_VERSION: 1.3.7
TG_VERSION: 0.43.0
TFCMT_VERSION: 4.0.1
permissions:
id-token: write
contents: read
pull-requests: write
jobs:
plan:
name: Terraform plan
runs-on: ubuntu-latest
steps:
- name: Set env vars for dev
if: github.base_ref == 'develop'
run: |
echo "ENVIRONMENT=dev" >> $GITHUB_ENV
echo "AWS_ACCOUNT_ID=123456789012" >> $GITHUB_ENV
echo "WORK_DIR=app/envs/dev" >> $GITHUB_ENV
- name: Set env vars for prod
if: github.base_ref == 'main'
run: |
echo "ENVIRONMENT=dev" >> $GITHUB_ENV
echo "AWS_ACCOUNT_ID=123456789012" >> $GITHUB_ENV
echo "WORK_DIR=app/envs/prod" >> $GITHUB_ENV
- name: Checkout
uses: actions/checkout@v3
- name: Setup Terraform
uses: hashicorp/setup-Terraform@v1
with:
terraform_version: ${{ env.TF_VERSION }}
terraform_wrapper: false
- name: Setup Terragrunt
run: |
sudo wget -q -O /bin/terragrunt "https://github.com/gruntwork-io/terragrunt/releases/download/v${TG_VERSION}/terragrunt_linux_amd64"
sudo chmod +x /bin/terragrunt
terragrunt --version
- name: Setup tfcmt
run: |
wget "https://github.com/suzuki-shunsuke/tfcmt/releases/download/v${TFCMT_VERSION}/tfcmt_linux_amd64.tar.gz" -O /tmp/tfcmt.tar.gz
tar xzf /tmp/tfcmt.tar.gz -C /tmp
mv /tmp/tfcmt /usr/local/bin
tfcmt --version
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@master
with:
role-to-assume: arn:aws:iam::${{ env.AWS_ACCOUNT_ID }}:role/${{ env.PROJECT }}-${{ env.ENVIRONMENT }}-github-actions-terraform-role
role-session-name: ${{ env.PROJECT }}-${{ env.ENVIRONMENT }}-github-actions-terraform-session
aws-region: ${{ env.AWS_REGION }}
- name: Terragrunt init
working-directory: ${{ env.WORK_DIR }}
run: terragrunt run-all init
- name: Check terraform fmt
working-directory: ${{ env.WORK_DIR }}
run: terraform fmt -check -recursive
- name: Terragrunt validate
working-directory: ${{ env.WORK_DIR }}
run: terragrunt run-all validate
- name: Terragrunt plan
working-directory: ${{ env.WORK_DIR }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
terragrunt run-all plan --terragrunt-tfpath $GITHUB_WORKSPACE/.github/scripts/tfwrapper.sh
请参考