I’ve seen some questions about this elsewhere but they do not seem to answer my issue (or I don’t understand the answer?)
Here’s the complete error.
│ Error: Invalid for_each argument
│
│ on longhorn_manifests.tf line 34, in resource "kubectl_manifest" "longhorn_manifests":
│ 34: for_each = { for k, v in data.kubectl_path_documents.longhorn_directory.manifests : k => v if var.install_longhorn }
│ ├────────────────
│ │ data.kubectl_path_documents.longhorn_directory.manifests is a map of string, known only after apply
│ │ var.install_longhorn is true
│
│ 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.
and here is the code
resource "random_password" "salt" {
length = 8
}
resource "htpasswd_password" "hash" {
password = var.longhorn_ui_password
salt = random_password.salt.result
}
data "kubectl_path_documents" "longhorn_directory" {
pattern = "./manifests/longhorn/*.yaml"
vars = {
cluster_fqdn = var.cluster_fqdn
longhorn_s3_endpoint = base64encode(var.longhorn_s3_endpoint)
longhorn_s3_access_key = base64encode(var.longhorn_s3_access_key)
longhorn_s3_secret_key = base64encode(var.longhorn_s3_secret_key)
auth = base64encode("${var.longhorn_ui_user}:${htpasswd_password.hash.apr1}")
}
}
resource "kubectl_manifest" "longhorn_manifests" {
for_each = { for k, v in data.kubectl_path_documents.longhorn_directory.manifests : k => v if var.install_longhorn }
yaml_body = each.value
depends_on = [
kubectl_manifest.infoblox_issuers_manifests,
kubernetes_namespace.longhorn,
helm_release.longhorn
]
}
I think I understand the issue, I just don’t know how to fix it.
The auth = base64encode("${var.longhorn_ui_user}:${htpasswd_password.hash.apr1}")
line is the problem, specifically the {htpasswd_password.hash.apr1}
element.
I need to create the password hash using a resource
, then use that in the vars
section of the data
item, then use that data
item in a for_each
of the kubectl_manifest.longhorn_manifests
resource. From the error it sounds like the data item needs the resource to run first and it can’t
I get the second option for a fix, perform two applies, but that seems really hacky and not ideal.
I don’t get the first option, it's better to define the map keys statically
. I’ve searched for examples but have come up with nothing.
Notes:
htpasswd_password
is from loafoe/htpasswd
kubectl_path_documents
is from alekc/kubectl
Any ideas?