😀
pre-commitでシンボリックリンク作成し、Terraformで環境ごとの構成を共通化する方法
Terraformを利用してインフラ構築をする際に、異なる環境間(本番環境や開発環境)で構成を同じにしたいケースがあると思います。
しかし、環境ごとにコードを個別に記述してしまうと、重複コードが発生しやすく、保守性や一貫性の面で問題になります。
そこで、shareディレクトリ配下に共通のリソースを格納して、devとprod配下に環境固有のリソースや変数を配置するという構成が有効です。
この際に、devとprod配下にshareの共通リソースのシンボリックリンクを作成し、terraformコマンドを実行する際に、ファイルを認識させる必要があります。
ディレクトリ構成
terraform/
├── dev/
│ ├── terraform.tfvars # dev 環境固有の変数
│ └── (share への symlink がここに作成される)
├── prod/
│ ├── terraform.tfvars # prod 環境固有の変数
│ └── (share への symlink がここに作成される)
└── share/
├── network.tf # 共通リソース
└── variables.tf # 共通変数
シンボリックリンクの作成
share配下にファイルを追加、削除した際に、都度シンボリックリンクを貼り直すのは面倒なので、
Gitのpre-commitフックを利用して、コミットの際に自動的にシンボリックリンク貼り直します。
.git/hooks/pre-commit
下記を.git/hooks/pre-commitに下記のカスタムスクリプトを配置します。
# リポジトリのルートのディレクトリを定数として定義
REPO_ROOT=$(git rev-parse --show-toplevel)
# Symlinkの削除
find "$REPO_ROOT/terraform/prod" -type l -exec rm -f {} \;
find "$REPO_ROOT/terraform/dev" -type l -exec rm -f {} \;
# share配下のファイルでSymlinkを作成する
for file in $REPO_ROOT/terraform/share/*; do
echo $file
ln -sf "../share/$(basename "$file")" "./terraform/dev/$(basename "$file")"
ln -sf "../share/$(basename "$file")" "./terraform/prod/$(basename "$file")"
done
# 作成されたSymlinkのステージング
git add -u $REPO_ROOT/terraform/
git add $REPO_ROOT/terraform/prod/
git add $REPO_ROOT/terraform/dev/
Discussion
terraform には module って便利な機能があるので。。。
Windows host なユーザもコレじゃ困るのでは?
コメントありがとうございます!
今回の構成は個人用途で、ディレクトリを整理するためにシムリンクを使っていました。ただ、ご指摘の通り、Windows環境ではシムリンクの扱いが難しい場合もあり、他のユーザにとって不便になることもあると思います。
チーム開発やクロスプラットフォーム対応を考えるなら、Terraformのmodule機能を使って明示的に構成を分けたほうが良さそうですね。学習も兼ねて改善していきたいと思います!