はじめに
Terraformにおいて大きな課題の一つにソースコードの管理をどう扱うか、という課題に直面した。
具体的にはAWSのLambdaなどはクラウドリソースであり、
今回は以下ののような構成をベースに考える。
/
└ terraform
├ module
│ └ lambda
├ production
├ stagin
└ develop
その中で対策は大きく2つあると考える。
Terraformと同じリポジトリに埋め込む(ボツ案)
/
├ app
│ ├ func1
│ └ func2
└ terraform
├ module
│ └ lambda
├ production
├ stagin
└ develop
Terraformのリポジトリと同一のリポジトリにソースコードを含めてしまう。
Terraformの環境差分をBranchを切らずに、main一本で管理していた。
つまるところGitの機能はほぼ使わずに、ある意味ファイルサーバ的な使い方をしていた。
リポジトリ=現在のシステム構成、と等価になるように維持していきたいからだ。
Terraformのディレクトリパターン集
こうなると、appディレクトリはソースなので、もちろんバージョン管理したくBranchもどんどん切っていきたい。
Terraformと別リポジトリで管理する
/
└ terraform
├ module
│ └ lambda
├ production
├ stagin
└ develop
/
└func1
こうすると、Terraformの単一のBranchを維持したい思想と従来のソースコードのGit戦略を切り離せる。
しかし、問題が一つ出てくる。
どのようにソースとTerraformを紐付けるかだ。
今回はこのように対処した。
スクリーンショット 2021-04-18 15.16.11.png
具体的には、terraform側では関数の設定(IAMとの結びづけなど)自体はTerraform内で定義するが、
実際のソースコードはクラウド上のストレージ(S3やGCS)のFunc1バケットを指定。
バケット内でバージョンごとにディレクトリを切っており、デプロイ時のバージョンごとに切られていく仕組みになる。
これにより、明示的にTerraform側でバージョンを上げてやらない限り勝手にバージョンが上がることを防げる。
またソースコードも従来どおりの管理が可能で、Terraformに反映させたいバージョンができると、GitにタグをつけてCI/CDを流す。
さいごに
正直Terraformに関してはGitと相性が悪すぎてベストプラクティスはないと思います。