Terraform + GitHub ActionsでInfra CI/CDを試す (2022年版)
去年、「Terraform + GitHub Actions で Infra CI/CD を試す」という題名で記事を書きました。
この記事では、いくつかアップデートを加えて再実装してみたものを記事としてまとめています。
実装サンプルは下記にあります (null resource を定義したサンプルコードを載せています)
Workflowの概要
下記のような構成で workflow を定義しています。
- A:
terraform-ci-{stg, prod}.yaml
: xx.tf のファイル変更を Trigger に workflow を実行する- tflint
terraform validate
terraform plan
- B:
terraform-cd-{stg, prod}.yaml
: staging / main branch への PR merge を Trigger に workflow を実行する- tflint
terraform validate
terraform apply
リソース追加を想定した一連の開発フローは下記の通りです
- feature branch を切って、xxx.tf にリソース定義を追加して修正を commit + push する(A)
- 1 の変更を staging branch に merge する(B)
- PR review を行い、Approve されたら PR を merge する(B)
google-github-actions/auth (for keyless CI/CD)
下記の記事で基本的な内容はまとまっていますが、理解のために一部重複しますがまとめておきます。
2021 年 10 月のアップデートで、GitHub Actions の workflow から OIDC token を発行できるようになりました。
この機能と GCP のWorkload Identity Federationを組み合わせることで、short-lived (default: 3600sec) の credentials を取得できるようになりました。
これまでは、workflow で gcloud コマンドを実行する場合は、Service Account Key を base64 encode した状態で GitHub secret として渡すのが一般的でした。
今回の例では、google-github-actions/authを利用することで、発行された OIDC token を Security Token Service に渡して credential を取得しています。
GitHub Actions の Workflow 側では、jobs.<job_id>.permissions
に id-token: 'write'
と定義することで、token の発行に必要な権限が付与されます。
permissions:
contents: 'write'
id-token: 'write'
google-github-actions/auth
では、Workload Identity Provider と Credential に紐づく Service Account 名を指定しておきます。
これにより、任意の Service Account に紐づいた Credential の発行ができるようになります。
- uses: 'actions/checkout@v3'
- id: 'auth'
name: 'Authenticate to Google Cloud'
uses: 'google-github-actions/auth@v0' # https://github.com/google-github-actions/auth
with:
create_credentials_file: 'true'
workload_identity_provider: ${{ secrets.workload_identity_provider }}
service_account: ${{ secrets.service_account }}
access_token_lifetime: 1200s
また、Terraform 関連の Workflow で、事前に gcloud auth login
が必要なので、create_credentials_file: true
を設定して、後続の step で Credential を利用するように設定します。
(自動でexportされる環境変数経由でも path を取得できるようです)
- id: 'gcloud-auth-login'
name: gcloud auth login by workload identity
run: |-
gcloud auth login --cred-file="${{ steps.auth.outputs.credentials_file_path }}"
一連の token 発行の流れは、下記 Issue の図がわかりやすいかと思います。
tfcmt
去年の段階では、mercari/tfnotifyを利用していましたが、直近ではメンテナンスも行われているtfcmtを利用しています。
GitHub Actions は組み込みの環境変数から必要なパラメータがセットされるので、tfcmt plan -- terraform plan
のように定義するだけで Pull request のコメントに terraform plan の結果を投稿できます。
- id: 'setup-tfcmt'
name: Install tfcmt
run: |
sudo curl -fL -o tfcmt.tar.gz https://github.com/suzuki-shunsuke/tfcmt/releases/download/$TFCMT_VERSION/tfcmt_linux_amd64.tar.gz
sudo tar -C /usr/bin -xzf ./tfcmt.tar.gz
env:
TFCMT_VERSION: "v3.2.1"
- id: 'tfcmt'
name: Terraform plan
run: |
tfcmt plan -- terraform plan -no-color
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
PR_NUMBER: ${{ github.event.number }}
コメントのフォーマットもテンプレートファイルで定義できるようですが、default の状態でも特に不自由ありません。
tflint
tflint-ruleset-google (GCP)
tflint の GCP 用の ruleset に関しては、下記で開発が進んでいます。
2021 年初旬よりもある程度充実している印象です。
reviewdog/action-tflint
tflint のセットアップ処理は、reviewdog/action-tflintに任せています。
action-tflint の設定で、commit の度に tflint を走らせたいので reporter: github-check
として設定しています。
- name: tflint
uses: reviewdog/action-tflint@master
with:
github_token: ${{ secrets.github_token }}
reporter: github-check # https://github.com/reviewdog/reviewdog/issues/889
fail_on_error: true
filter_mode: "nofilter"
tflint_version: "v0.36.0"
tflint_rulesets: "google"
最後に
基本的な構成自体は変わっていませんが、google-github-actions/auth
を利用した keyless CI/CD の登場や tfcmt, tflint などの関連ツールの開発によってある程度機能面では充実してきている印象です。
tfmigrate など CI/CD に組み込んでみたいツールは他にもあるので、機会があればアップデートした内容を記事にしてみようと思います。
Discussion