I’ve found many great answers on this forum, thank you!
Here, I’m trying to create resources based on data retrieved from Vault.
The first data source retrieves a list of secrets from Vault with a scope name and the second one retrieves the content (key/value) of each secret.
data "vault_kv_secrets_list_v2" "scope_secrets_list" {
mount = "kv2"
name = local.vault_scope_path
}
data "vault_kv_secret_v2" "scope_secrets" {
for_each = nonsensitive(toset(data.vault_kv_secrets_list_v2.scope_secrets_list.names))
mount = "kv2"
name = "${local.vault_scope_path}/${each.key}"
}
When doing so in a child module, I get the following Error:
Error: Invalid for_each argument
on ../../modules/vault_databricks_secret_scope/main.tf line 26, in data "vault_kv_secret_v2" "scope_secrets":
26: for_each = nonsensitive(toset(data.vault_kv_secrets_list_v2.scope_secrets_list.names))
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.
If I include the data sources in the root module, the planning phase manages to retrieve the data sources properly without any error and builds the resources with the result.
Would you know what’s wrong here please?
Thank you!
This error suggests that something is preventing Terraform from reading data.vault_kv_secrets_list_v2.scope_secrets_list during the planning phase.
There are a number of different reasons why that would be and if you are using a new enough version of Terraform it would hopefully have shown you a partial plan as more context about what was blocking that, but with just the information you shared I can only make some guesses about what the cause might be:
local.vault_scope_path has an unknown value during the planning phase, and therefore Terraform must wait until the apply phase to be able to provide that value to the vault_kv_secrets_list_v2 data source.
In your root module your module block is somehow declaring that it’s dependent on another resource in the configuration which has changes pending, and so Terraform must wait until the apply phase (after those changes have been completed) to preserve the dependencies you declared.
The most straightforward way this could happen is if you literally wrote depends_on = in the module block. A less direct variant would be for that module to have a count or for_each argument that refers to the result of another resource. In both cases the trigger would be that Terraform is expecting to change whatever resource the module depends on during the planning phase and must therefore postpone everything inside the module (including this data block) until those changes have been completed.
The fact that something similar to this worked in the root module but not when you factored it out into a separate shared module makes me suspect that the second explanation is more likely here, but I can’t be sure.
If the ideas above don’t seem plausible, then it would help if you could respond with the full output from terraform plan (this error message and everything else Terraform said) and then I can hopefully help interpret any contextual hints Terraform has included in its output.
This is a great answer, thanks for replying so quickly!
You were right, I had a depends_on on the module containing my child module. (option 2)
That’s an expected depends_on as this module requires another module named infrastructure to be completed before moving forward on the other module. (without infrastructure we can’t create resources related to it)
To fix it, I’ve moved the Vault data source retrievals outside of my child module in a dedicated module called from the root and without any explicit dependency. Once completed, this new Vault module sends the outcome as an output variable to the root module and I share it from there to the child module in charge of creating resources.
It works like a charm, thank you so much!
Best Regards