Map key from resource data

Hello,

I have following code:

resource "vault_pki_secret_backend_cert" "elasticsearch_master_node" {
  count = 1

  backend = "intermediate-ca"
  name    = "admin-role"

  common_name = "es-master-1.company.internal"
  ttl         = "1h"
}

output "test" {
  value = {
    for k, v in vault_pki_secret_backend_cert.elasticsearch_master_node :
    k => ({ "ca_chain" = v.ca_chain, "certificate" = v.certificate, "private_key" = v.private_key })
  }
}

Current output produce following structure:

test = {
  0 = {
    "ca_chain" = <<-EOT
    -----BEGIN CERTIFICATE-----
    -----END CERTIFICATE-----
    EOT
    "certificate" = <<-EOT
    -----BEGIN CERTIFICATE-----
    -----END CERTIFICATE-----
    EOT
    "private_key" = <<-EOT
    -----BEGIN RSA PRIVATE KEY-----
    -----END RSA PRIVATE KEY-----
    EOT
  }
}

I want to map k to common_name field from resource so I tried following:

Does not work:

output "test" {
  value = {
    for k, v in vault_pki_secret_backend_cert.elasticsearch_master_node :
    k.common_name => ({ "ca_chain" = v.ca_chain, "certificate" = v.certificate, "private_key" = v.private_key })
  }
}

Dose not work as well:

output "test" {
  value = {
    for k, v in vault_pki_secret_backend_cert.elasticsearch_master_node :
    "common_name" = k.common_name => ({ "ca_chain" = v.ca_chain, "certificate" = v.certificate, "private_key" = v.private_key })
  }
}

What I’m doing wrong?

Hi @igor-nikiforov,

Can you share a bit more detail about what happened when you tried your new example? You said that it didn’t work so well, but it would be helpful to see the actual result Terraform returned in that case, and for you to describe how that result differed from the result you wanted.

Thanks!

Hi @apparentlymart ,

I meant that both of my tries didn’t worked. Have no idea why same syntax work for values but not for key.

First example:

output "test" {
  value = {
    for k, v in vault_pki_secret_backend_cert.elasticsearch_master_node :
    k.common_name => ({ "ca_chain" = v.ca_chain, "certificate" = v.certificate, "private_key" = v.private_key })
  }
}

Error:

Error: Unsupported attribute

  on main.tf line 23, in output "test":
  23:     k.common_name => ({ "ca_chain" = v.ca_chain, "certificate" = v.certificate, "private_key" = v.private_key })

This value does not have any attributes.

Second example:

output "test" {
  value = {
    for k, v in vault_pki_secret_backend_cert.elasticsearch_master_node :
    "common_name" = k.common_name => ({ "ca_chain" = v.ca_chain, "certificate" = v.certificate, "private_key" = v.private_key })
  }
}

Error:

Error: Invalid 'for' expression

  on main.tf line 23, in output "test":
  21:   value = {
  22:     for k, v in vault_pki_secret_backend_cert.elasticsearch_master_node :
  23:     "common_name" = k.common_name => ({ "ca_chain" = v.ca_chain, "certificate" = v.certificate, "private_key" = v.private_key })
  24:   }

Key expression is required when building an object.


Error: Invalid 'for' expression

  on main.tf line 23, in output "test":
  21:   value = {
  22:     for k, v in vault_pki_secret_backend_cert.elasticsearch_master_node :
  23:     "common_name" = k.common_name => ({ "ca_chain" = v.ca_chain, "certificate" = v.certificate, "private_key" = v.private_key })

Extra characters after the end of the 'for' expression.

Hi @igor-nikiforov,

I think your first try failed because you wrote k.common_name as the key expression. k in this context is the numeric index of the current element – the value 0 – and so Terraform is correct to say that it doesn’t have an attribute named common_name.

common_name is an attribute of v though, because in this expression v is the current resource instance object. Therefore I think you don’t actually need the k symbol here at all (you don’t care about the indexes) and can derive everything you need only from v:

output "test" {
  value = {
    for v in vault_pki_secret_backend_cert.elasticsearch_master_node :
    v.common_name => {
      ca_chain    = v.ca_chain
      certificate = v.certificate
      private_key = v.private_key
    }
  }
}

(I reformatted it into a more idiomatic shape just so I could read it more easily to understand what you were intending, but the important things here are that I wrote v.common_name instead of k.common_name and then I removed the k symbol from the for clause altogether, because there were no longer any references to it.

1 Like

Hi @apparentlymart ,

Thank you for explanation!