Closed2

[Terraform] "XXX is a map of string, known only after apply" の原因

tharutharu

Terraformにてモジュール間で変数受け渡し時、以下のエラーに遭遇することがある。

│Error: Invalid for_each argument
│
│  on ../xxx.tf line 85, in resource "aws_cloudwatch_metric_alarm" "xxx":
│  85:   for_each            = var.cognito_user_pool_ids
│├────────────────
││var.cognito_user_pool_ids is a map of string, known only after apply
│
│The "for_each" map includes keys 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 define the map
│keys statically in your configuration and place apply-time results only in
│the map values.
│
│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.

こういった依存関係のエラーはTerraform側でよしなに処理してくれるものと思っていたが、考え方を改めさせられたコメントがGitHubで見つかったので備忘録として書き残しておく。

tharutharu

元のリンクはこちら。以下その抜粋。

The key requirement we need to meet is that we must always be able to correlate resource instances declared in the configuration with resource instances already recorded in the state. Today we achieve that by requiring that resource instances have wholly-known, stable identifiers throughout the workflow.
...
For today our recommendation is to generally treat instance keys in a similar way as resource names: they are an identifier unique to this particular module instance, and only need to be unique within that module instance's namespace.

Terraformはリソースを宣言する段階で、ID全体が既知でありステートと一致している必要があるとのこと。そのため、先ほどの map(string) を使用していた var.cognito_user_pool_ids のKeyに、リソース構築中もしくは構築後に出力される値を指定することはできない。

map型で変数の受け渡しを行う際は、Keyには宣言時に決定できる静的な値を指定するよう意識したい。

このスクラップは2022/06/10にクローズされました