使用[Terraform]GithubActions执行Terraform存储库的CI
简而言之
我会通过GitHub操作来记录使用Terraform仓库的连续集成的设置步骤,以便能够手把手地进行操作。这不适用于那些不想将机密信息存放在GitHub上的人。
前提 tí) – premise / assumption / prerequisite
-
- Githubでtfファイルを管理している
- AWSアカウントを保持している
用中文对以下内容进行修改:
检查内容通过CI.
请参阅这篇文章。
Github Actions的设置
请查看此链接以获取完成形。
特点
以下是与CodeBuild配置相比的特点。
○ 設定的方式很容易
○ 可以并行执行
△ 需要将AWS或Terraform Cloud的凭据记录到Github中
如果您对在Github上管理Credentials有疑虑,我们建议您使用CodeBuild进行CI。由于它在AWS上运行,不需要AWS的Credentials,而其他Credentials可以使用SSM Parameter-Store和KMS来存储机密数据。
目录结构
仓库的目录结构如下所示。
├── .github/
│ └── workflows/
│ └── terraform_ci.yml # Actionsの設定ファイル
├── environments/ # CIの対象ファイル群
│ └── aws/
│ ├── development/
│ └── practice/
└── scripts/
└── ci/ # スクリプト群
设定文件的描述设定文件的描述

模板设置概述
在这里创建的模板是根据以下假设进行设计的。
masterブランチへのpushおよびPR作成・更新時にワークフローが実行される
リポジトリのルートディレクトリに対象のtfファイルが存在する
ステートファイルをTerraform Cloudで管理している、またplan等のコマンドをTerraform Cloud上で実行する
fmtとplanを実行する
masterブランチへのpushを契機に、applyを実行する
我打算对与本次前提不同的部分进行定制。也就是说,我会进行定制。
-
- AWSのcredentialsを読み込む
-
- コマンドはGithub上で実行する
applyは実行しない
validate tflintも実行する
environmentsディレクトリ以下の各環境別にCIを実行する
我会逐步进行更改。
加载AWS凭证
首先,在存储库中注册AWS和TerraformCloud(如果在状态管理中使用)的凭据。
在存储库的 Settings → Secrets 页面中,使用以下环境变量名进行注册。
由于当前情况下,AWS认证信息无法加载,因此我们需要在checkoutstep之后添加一个设置credentials的步骤。
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-1
执行命令在Github上进行
如果您在Terraform Cloud中进行状态管理,则只适用于此。(如果您在S3或GCS中进行状态管理,则命令会在Github Actions上必然执行,因此不需要担心。)
在设置→常规中,将执行模式设置为本地(默认为远程)。

不执行申请。
这意味着将重点放在CI上。 只需删除或注释掉以下apply行即可。
- name: Terraform Apply
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
run: terraform apply -auto-approve
验证并执行tflint
由于validate可以在terraform validate命令中执行,因此只需要将其作为步骤添加(在init之后),即可完成。
- name: Terraform Validate
id: validate
run: terraform validate -no-color

由于该命令是基于init的前提条件,因此我们会在init之后添加step。
- name: TFLint
uses: reviewdog/action-tflint@master
with:
github_token: ${{ secrets.github_token }}
reporter: github-pr-review # PRにコメントする
fail_on_error: true
在environments文件夹中,按照每个环境执行CI操作。
使用Github Actions中提供的strategy.matrix来实现多个目录的CI。
请注意,在这种情况下,工作流将按照设置的矩阵数量(并行地)执行。
由于矩阵部分是直接编辑的,如果增加了目标环境,则需要添加相应的设置。我想不出一个有效解决这个问题的方法。
如果只想执行特定目录,则不需要使用strategy.matrix,只需将working-directory设置为目标目录即可。
terraform-ci:
name: Terraform
strategy:
matrix:
env: [practice, development] # ここに対象環境名を羅列
runs-on: ubuntu-latest
defaults:
run:
shell: bash
working-directory: ./environments/aws/${{ matrix.env }} # このディレクトリでこれ以下のコマンドを実行していく
推送更改
到目前为止,定制工作已经完成。让我们提交配置文件的更改吧。
在“操作”选项卡中,确认工作流正在执行,说明它正常运行!
1. 将CI的结果作为PR的评论
通过上述设置,CI现在已经开始执行,但是结果需要查看Actions选项卡的执行结果→目标步骤。然而,在PR上可能会有一些情况,我们希望能够完成这个确认。因此,我们将尝试添加一个设置来将CI执行结果作为PR的评论进行记录。此外,一次工作流可以完成所有的检查也是很有吸引力的。
但是,请注意,即使在fmt等方面失败,CI的执行状态仍然是Complete(如果能够采取适当的执行结果检查机制,这可能是可能的)请在权衡中选择是否引入。
即使在每个命令中都失败了,也不会中断工作流程。
为了一次性查看所有结果,需要运行工作流程直到结束。因此,我们在fmtvalidateplan中追加了在错误情况下继续进行的设置。同时,我们也应该给每个步骤分配一个id。
- name: Terraform Validate
id: validate # ここを追記
run: terraform validate -no-color
continue-on-error: true # ここを追記
实现评论通知
你可以使用公式Readme中的输出在后续步骤中对拉取请求进行评论。steps..outcome表示该步骤的执行结果(成功、失败、取消、跳过),steps..outputs.stdout表示该命令的执行结果标准输出。
# 一番最後のstepとして定義
- uses: actions/github-script@0.9.0
if: github.event_name == 'pull_request' # PR作成・更新時だけ実行する
env:
PLAN: "terraform\n${{ steps.plan.outputs.stdout }}"
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const output = `## \`${{ matrix.env }}\`
#### Terraform Format and Style ?\`${{ steps.fmt.outcome }}\`
#### Terraform Initialization ⚙️\`${{ steps.init.outcome }}\`
#### Terraform Validation ?${{ steps.validate.outputs.stdout }}
#### Terraform Plan ?\`${{ steps.plan.outcome }}\`
<details><summary>Show Plan</summary>
\`\`\`${process.env.PLAN}\`\`\`
</details>
*Pusher: @${{ github.actor }}, Action: \`${{ github.event_name }}\`, Workflow: \`${{ github.workflow }}\`*`;
github.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: output
})

用下述的选项在中文中重新表述:
选项2. 不使用strategy.matrix,对多个目录进行CI。
这与CodeBuild运行时使用的方法相同,需创建包装脚本,在其中列举目标目录并执行命令。它具有以下特点。
-
- ワークフローは単一のものとなる
-
- 対象ディレクトリが増えた場合も、CI設定の変更は不要
-
- ラッパースクリプトを作成する必要がある
tfnotifyを利用する場合、pull_requestイベントではうまく発火されない(これは設定が悪いのかもしれません)
另外,请参考本文中的链接,此处的包装器脚本几乎与那篇文章中创建的脚本相同。本文中仅记录差异部分。
创建GithubActions的配置文件
基本的流程不会改变,只会有以下方面的变化。
strategy.matrixは使用しない
各stepではラッパースクリプトを実行する
runs-on: ubuntu-latest
defaults:
run:
shell: bash
working-directory: .
############## 中略 ##############
- name: Install Dependent Packages
run: ./scripts/ci/install_packages.sh
- name: Terraform Format Check
run: ./scripts/ci/format.sh
############## 以下同様 ##############
将tfnotify适配Github Actions。
只需要修改第一行中的ci描述。其他部分可以保持不变并进行重用。
ci: github-actions
另外,目前尚不清楚是tfnotify的问题还是我们的设置有问题,但在执行pull_request时无法成功在PR上添加评论。同时,标签设置也无法正常运行。若有相关信息,请提供给我们。
on:
push:
# どうもGithub-Actions上でtfnotifyはpushでないと動かない様子
# branches:
# - master
# - development
# pull_request:

参考文献
-
- GitHub Actionsのワークフロー構文
- setup-terraform