Search code examples
terraform

Can I get the name of a terraform resource's property?


I'm wondering if I can do some reflection here. Consider this:

  extraEnvs = [{
    name = BLAH_BLAH
    valueFrom= {
      secretKeyRef= {
        name = kubernetes_secret.my_secret.id
        # The value I need here is the _name_ of this property
        # key = kubernetes_secret.my_secret.data.secret
        key = "secret"
      }
    }
  }]

Instead of hard coding the value "secret" I can directly reference the key like this: kubernetes_secret.my_secret.data.secret, but that returns the value. How do I just get the key name?

I tried this, but I get an error:

keys(kubernetes_secret.my_secret.data.secret)[0]

Error:

│ Error: Invalid function argument
│ 
│   on blah.tf line 45, in locals:
│   45:             key = keys(kubernetes_secret.my_secret.data.secret)[0]
│     ├────────────────
│     │ kubernetes_secret.my_secret.data.secret has a sensitive value
│ 
│ Invalid value for "inputMap" parameter: must have map or object type.

I should probably just make my kubernetes_secret from a map var and use that same var as input here, but curious if this kind of reflection is possible.


Solution

  • I should start with a big WARNING these are sensitive values!!
    You could end up with sensitive data stored in the terraform plan in plain text!!!


    How about something like this:

    resource "kubernetes_secret" "example" {
      metadata {
        name = "basic-auth"
      }
    
      data = {
        username = "admin"
        password = "foobar"
        secret   = "abc"
      }
    
      type = "kubernetes.io/basic-auth"
    }
    
    locals {
      data = nonsensitive(kubernetes_secret.example.data)
    }
    
    resource "null_resource" "test" {
      for_each = local.data
      triggers = {
        k = each.key
        v = each.value
      }
    }
    

    that local variable will contain:

    {
        password = "foobar"
        secret   = "abc"
        username = "admin"
    }
    

    If we do a terraform plan on that we get

    Terraform will perform the following actions:
    
      # kubernetes_secret.example will be created
      + resource "kubernetes_secret" "example" {
          + data                           = (sensitive value)
          + id                             = (known after apply)
          + type                           = "kubernetes.io/basic-auth"
          ...
        }
    
      # null_resource.test["password"] will be created
      + resource "null_resource" "test" {
          + id       = (known after apply)
          + triggers = {
              + "k" = "password"
              + "v" = "foobar"
            }
        }
    
      # null_resource.test["secret"] will be created
      + resource "null_resource" "test" {
          + id       = (known after apply)
          + triggers = {
              + "k" = "secret"
              + "v" = "abc"
            }
        }
    
      # null_resource.test["username"] will be created
      + resource "null_resource" "test" {
          + id       = (known after apply)
          + triggers = {
              + "k" = "username"
              + "v" = "admin"
            }
        }
    
    Plan: 4 to add, 0 to change, 0 to destroy.