[2019-05-07-1] に紹介した『Pragmatic Terraform on AWS 』に沿って設計すると、terraform のディレクトリは複数出来ると思います。

依存を分けることと、まとめて実行することはやや矛盾します。とは言え terraform や terraform provider がアップデートした時の terraform init/plan/apply はまとめてやりたいものです。

少し前に作って使っていますが、なかなか良い感じです。

使っている Makefile たち

.
├── Makefile # (1)
└── terraform
    ├── aws
    │   ├── Makefile # (2)
    │ └── main.tf
    └── heroku
    ├── Makefile # (3)
    └── main.tf
view raw 00tree.txt hosted with ❤ by GitHub
MAKE := make
TARGETS := aws heroku
define make-r
@for i in $(TARGETS); do \
$(MAKE) -w -C terraform/$$i $(1) || exit $$?; \
done
endef
# Recursive terraform init
.PHONY: init-r
init-r:
$(call make-r, init)
# Recursive terraform plan
.PHONY: plan-r
plan-r:
$(call make-r, plan)
# Recursive terraform apply
.PHONY: apply-r
apply-r:
$(call make-r, apply)
view raw Makefile # (1) hosted with ❤ by GitHub
TERRAFORM := terraform
.PHONY: init
init:
$(TERRAFORM) init
.PHONY: plan
plan:
$(TERRAFORM) plan
.PHONY: apply
apply:
$(TERRAFORM) apply
view raw Makefile # (2) hosted with ❤ by GitHub
TERRAFORM := terraform
.PHONY: init
init:
$(TERRAFORM) init
.PHONY: plan
plan:
$(TERRAFORM) plan
.PHONY: apply
apply:
$(TERRAFORM) apply
view raw Makefile # (3) hosted with ❤ by GitHub

この辺りを工夫しました。

・terraform init/plan/apply に失敗すると、即座に停止する
・make の -C オプションを使って、cd せずに make を実行できている。つまり cd .. とかで戻る必要がない。そういう理由で下位ディレクトリに Makefile 置いてる
・make の -w オプションを使って、以下のようなそれっぽいログを出している

$ make init-r
make[1]: Entering directory `/Users/masutaka/src/github.com/masutaka/masutaka.net/terraform/aws'
(snip)
make[1]: Leaving directory `/Users/masutaka/src/github.com/masutaka/masutaka.net/terraform/aws'
make[1]: Entering directory `/Users/masutaka/src/github.com/masutaka/masutaka.net/terraform/heroku'
(snip)
make[1]: Leaving directory `/Users/masutaka/src/github.com/masutaka/masutaka.net/terraform/heroku'

direnv 使う場合

terraform では credential を注入するケースも多いので、direnv も使うことは多いのではないでしょうか。ルートに .envrc があるだけなら別ですが、各ディレクトリにもある場合はこのパッチが必要になると思います。

--- Makefile.orig 2020-03-26 22:38:05.000000000 +0900
+++ Makefile 2020-03-26 22:39:57.000000000 +0900
@@ -1,9 +1,10 @@
+DIRENV := direnv
MAKE := make
TARGETS := aws heroku
define make-r
@for i in $(TARGETS); do \
- $(MAKE) -w -C terraform/$$i $(1) || exit $$?; \
+ $(DIRENV) exec $$i $(MAKE) -w -C terraform/$$i $(1) || exit $$?; \
done
endef
view raw direnv.patch hosted with ❤ by GitHub

今回 direnv の exec サブコマンドを知りました。

$ direnv --help
direnv v2.21.2
Usage: direnv COMMAND [...ARGS]
(snip)
exec DIR COMMAND [...ARGS]:
  Executes a command after loading the first .envrc found in DIR

make の -C オプションに似ていて、DIR に cd した体で COMMAND を実行してくれます。もちろん各ディレクトリの .envrc は load されます。

まとめ

普段使っている terraform 用の Makefile を紹介しました。他にもあるので、いつか紹介するかもしれません。