背景
- Terraformでリソースをコード管理をしている場合、大抵gitでバージョン管理している
terraform apply
したものがまずかった場合、どの差分によるものか、いつから発生していたものなのか、誰の実行によるものかといった情報が欲しくなる- backendをgcsなどにしている場合、オブジェクトのバージョニングを有効にしていれば、いつオペレーションが実行されたかなどを追える
- 事故ってたケースの調査などで特に欲しい
- revisionの情報や実行者の情報は素のTerraformでは分からないので、何かしらの形で情報を埋め込みたい
やってみたこと: makeで情報を外から与える
var
で外から情報を与えてみる形を考えてみました。こんな感じで変数とoutputを定義しておきます。
variable "current_revision" { description = "terraform applyを実行した際のgitのrevision" type = string } variable "username" { description = "terraform applyを実行した人のusername" type = string } output "current_revision" { value = var.current_revision } output "username" { value = var.username }
実際のrevisionや実行者の情報はMakefileの中でvar
の引数で与えます。
CURRENT_REVISION := $(shell git rev-parse --short HEAD) USERNAME := $(shell whoami) plan: terraform plan \ -var="current_revision=${CURRENT_REVISION}" \ -var="username=${USERNAME}" apply: terraform apply \ -var="current_revision=${CURRENT_REVISION}" \ -var="username=${USERNAME}"
そうするとtfstateのoutputs
の項目にterraform apply
した際のrevisionの情報やusernameが埋め込まれるようになります。調査が捗りそうですね。
% terraform state pull | jq .outputs { "current_revision": { "value": "abcdefg", "type": "string" }, "username": { "value": "syou6162", "type": "string" } }
validationを強化する
先程までのやり方はちょっと穴があります。git diff
で差分が出ている状態でapplyされてしまうと、revisionと実際のTerraformのコードが一致しないという問題点です。こういったケースは避けたいので、差分がある状態ではそもそもmake apply
が失敗するようにpre-conditionに入れておきます。これで安心ですね。
GIT_DIFF_VALIDATE_MESSAGE="gitの差分がある状態でapplyしようとしています。差分をcommitした状態でapplyしましょう" validate-apply: git diff --diff-filter=ad --quiet || \ (echo "${GIT_DIFF_VALIDATE_MESSAGE}" && exit 1) apply: validate-apply terraform apply \ -var="current_revision=${CURRENT_REVISION}" \ -var="username=${USERNAME}"
その他調べたこと
- Terraform v0.8.0-rc3から任意の言語でプロバイダ/データソースを記述できる「external」という機能が導入されます | DevelopersIO
- externalを使うという手もあったが、wrap用のコマンドが面倒そうだったし、Makefileの中でやるほうが簡単かなと思った
- null_data_source | Data Sources | hashicorp/null | Terraform Registry
- こっちも試してみたが、ちょっと思っていたのと違った。あと、deprecatedっぽいので...