tfaction - GitHub Actions で良い感じの Terraform Workflow を構築
tfaction という、 GitHub Actions で良い感じの Terraform Workflow を構築するための Action を開発しているので紹介します。
まだ開発中という感じで未成熟(個人の AWS, GCP アカウントを使って検証しているくらい)ですが、既にそれなりに動くはずです。
tfaction とは
GitHub Actions で良い感じの Terraform Workflow を構築するための Action です。
単一の Action ではなく、複数の Action で構成されています。
ここで言う Terraform Workflow
とは、 terraform plan や apply を実行する一連の流れのことを指しています。
この Workflow に求める要件は組織・チームによっても異なるでしょう。
そもそも apply の自動実行は危険だから手動で実行するというふうにしているチームもあるでしょうし、
ブランチ戦略も違ったりするでしょう。
tfaction は Opinionated
なツールであり、それら全てのニーズを満たすことは目指していません。
むしろ tfaction で定める要件を満たす場合に少ないコードで良い感じの workflow を実現することを目指しています。
要件に合わなければ無理に tfaction を導入する必要はないでしょう。ただ、部分的に参考になる部分はあるかもしれません。
単に terraform plan, apply を実行するだけなら比較的簡単に実現できるでしょうが、 tfaction を使うとよりリッチな workflow を実現できます。
これを自分で 0 から実装するとなると中々大変なはずです。
tfaction の要件
- GitHub Flow
- branch は default branch と feature branch だけ
- default branch から feature branch を作成し、 feature branch から default branch に PR を作成
- Pull Request の CI で terraform plan などを実行
- Pull Request を default branch にマージしたら terraform apply が実行される
- Monorepo
- 一つのリポジトリで複数の Terraform Working Directory (State) を管理
- GitHub Actions
- GitHub Actions で Terraform を実行する
- AWS Account
- S3 に plan file や tfmigrate の history を保存
- 依存するツールは aqua で管理
- tfaction は tflint や tfsec, Conftest など様々なツールに依存しているが、それらは aqua でバージョン管理する
- Renovate による継続的 update
Feature
- 簡単に使える
- 色々準備は必要だったりする (AWS IAM Role や S3 Bucket 作ったり Identity Provider の設定をしたり) ので簡単というと語弊があるが、簡潔に記述できるようにしている
- Monorepo サポート
- Pull Request でコードを変更した working directory に対してのみ CI が実行される
- Pull Request Label で、コードが変更されていない特定の working directory を対象にすることもできる
- GitHub Actions の build matrix によって並列実行される
- tfmigrate サポート
- Pull Request label によって tfmigrate の実行を制御
- plan file を用いた安全な apply
- Pull Request の CI で実行した terraform plan の Plan File を S3 (あるいは Google Cloud Storage) に保存し、 terraform apply 実行時にそれをダウンロードして指定することで、予期せぬ apply が適用されないようにする
- tfcmt を使い、 terraform plan, apply をわかりやすく通知
- Linter のサポート(tfsec, tflint, Conftest, terraform validate)
- tfsec, tflint などは reviewdog によってわかりやすく通知される
- Pull Request がマージされて default branch が更新された際に、同じ working directory に関する Pull Request を自動更新
- working directory A に関する PR がマージされたら、 A に関する既存の PR に default branch をマージして更新
- CI の結果が最新になる & Plan file が更新されて stale じゃなくなる
- Renovate による安全な update
- Renovate の Pull Request の terraform plan の結果が No change じゃなかったら CI を fail させることで、 automerge されて予期せぬ変更が apply されるのを防ぐ
- .terraform.lock.hcl の自動生成・自動更新
- Pull Request の CI で更新されたら自動でコミットを Pull Request に push する
- terraform fmt による自動フォーマット
- Pull Request の CI で更新されたら自動でコミットを Pull Request に push する
- terraform apply が失敗したら自動で Pull Request を作成し、修正をサポートする
- 失敗した CI のリトライはせずに、新たに Pull Request を作成して対応する
- Pull Request は empty commit によって作成され、 Pull Request Label によって対象の working directory の CI が実行されるようにする
- 失敗した CI をリトライする方式だと、複数の working directory を変更している場合に、 GitHub Actions の build matrix の制約上、失敗した working directory の apply だけリトライができなくて困る
- なので失敗した working directory ごとに個別に Pull Request を作成して対応を促す
- GitHub Actions の workflow_dispatch event による working directory の雛形の作成のサポート
- workflow を実行すると working directory を追加する Pull Request が自動で作成される
- GitHub Actions で実行することで、開発環境の環境差異によるトラブルをなくす・トラブルシューティングしやすくなる(ローカルでコマンド実行してもらうとかだとトラブル対応が大変)
Set up
- https://github.com/suzuki-shunsuke/tfaction/blob/main/docs/setup.md
- https://github.com/suzuki-shunsuke/tfaction/blob/main/docs/add-working-directory.md
- https://github.com/suzuki-shunsuke/tfaction/blob/main/docs/config.md
Example
サンプルの workflow のコードを見れば、使い方がだいたい分かるかなと思います。
さいごに
以上、簡単ではありますが、 tfaction を紹介しました。
まだ実装できていない機能がある & ガッツリ使えてないので、実運用に乗せながら今後も改良を加えていきたいと思います。
Discussion