🐧

tfaction - GitHub Actions で良い感じの Terraform Workflow を構築

2022/01/24に公開

tfaction という、 GitHub Actions で良い感じの Terraform Workflow を構築するための Action を開発しているので紹介します。

まだ開発中という感じで未成熟(個人の AWS, GCP アカウントを使って検証しているくらい)ですが、既にそれなりに動くはずです。

https://github.com/suzuki-shunsuke/tfaction

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

Example

https://github.com/suzuki-shunsuke/tfaction-example

サンプルの workflow のコードを見れば、使い方がだいたい分かるかなと思います。

さいごに

以上、簡単ではありますが、 tfaction を紹介しました。

まだ実装できていない機能がある & ガッツリ使えてないので、実運用に乗せながら今後も改良を加えていきたいと思います。

Discussion