Terraform 適用順に依存しがち集
一発で走らないのが多々あるので、どういうときに起きるか記録しておく
モジュールとして切り出したつもりでも、実は実行パスによっては使えないとかも見る
再利用可能です!! と言うには空の環境に一発で適用できるようになっていてほしいが、要求が高い
そもそもそういうものではない、単に最新の状態を書き下したものです、と思って暮らす
(一方で冪等だぜ適用順なんか無いぜステートレスだぜという顔をしているのがムカつく)
for_each
for_each の対象コレクションに、known only after apply のリソースが入っていたら動かない
既に作成済みのリソースを参照している場合はよい、ので順序への依存を作りがち
code:Error: Invalid for_each argument
The "for_each" set includes values derived from resource attributes that cannot be determined until apply, and so Terraform cannot determine the full set of keys that will identify the instances of this resource.
When working with unknown values in for_each, it's better to use a map value where the keys are defined statically in your configuration and where only the values contain apply-time results.
Alternatively, you could use the -target planning option to first apply only the resources that the for_each value depends on, and then apply a second time to fully converge.
暗黙の依存
たとえば Google Cloud のサービスエージェント
Cloud Scheduler は cloudscheduler.googleapis.com を有効にした段階で service-*****@gcp-sa-cloudscheduler.iam.gserviceaccount.com が生えるが Dataform は API を有効にした時ではなく Dataform リポジトリを作った段階で生える なのでサービスエージェントへのロールの設定は Dataform リポジトリのリソースに depends_on しているのだが、こんなのに気を使って書ける人間は居るのか? (僕はできますが...)
depends_on の指定を諦めがち
GCP なら API を有効にするあたり、手で有効にする運用があったりもよくある
$ gcloud services list で有効な API を一覧化できるが、API の有効化がユーザに提供されていないものものある。デフォルトで有効になっているものや、別の API を有効にしたら間接的に有効になるものなどもある。
有効にしたあと GCP 側がバックグラウンドでリソース作ったりしていて正確な完了が分からないものなどもある(はず)
リソース定義上の参照関係があれば勝手に考慮されるわけで、依存を指定するのは実装者の知識に依る
リソース同士のデッドロック
なので backend service の replace (destroy が挟まる) が発生するオペレーションは実質実行できない
url map 外す更新があっても backend service を外してから削除、というふうにならない
これは参照してる側の問題だから backend service の lifecycle でもなんとかならない
state を消して apply してコンソールからリソースを消したり、
別名でリソースを定義して紐づけ直してから destroy が発生するように工夫しないといけない
backend service の定義から url map を生成していたり、そういう module を使ったり作ると詰む
(url map に手を入れて回避できないので。体験済み)
状況や権限によっては作成はできるけど削除できなくなって、すぐ非公開にしたり短時間の復旧も難しい可能性ある