Home > Net >  obtaining a list of objects from a complex nested object in terraform
obtaining a list of objects from a complex nested object in terraform

Time:09-19

I am trying to create a local variable "secret_list" in terraform based on a variable "secrets" that is defined in a tfvars.json file.

The "secrets" variable looks like this:

{
"secrets" : {
        "datacore": {
            "secrets" : [
                {"secret_scope": "datacore", "secret_key": "serviceaccount-databricks-deploy", "secret_value": "dummy"},
                {"secret_scope": "datacore", "secret_key": "serviceaccount-datacore", "secret_value": "dummy"}
            ],
            "acls" : [
                {"secret_scope": "datacore", "principal": "admins", "permission": "MANAGE"},
                {"secret_scope": "datacore", "principal": "Datacore Power Users", "permission": "READ"}
            ]
        },
        "ai" : {
            "secrets" : [
                {"secret_scope": "ai", "secret_key": "serviceaccount-ai", "secret_value": "dummy"},
                {"secret_scope": "ai", "secret_key": "serviceaccount-ai-private-key", "secret_value": "dummy"}
            ],
            "acls" : [
                {"secret_scope": "ai", "principal": "admins", "permission": "MANAGE"},
                {"secret_scope": "ai", "principal": "AI Power Users", "permission": "READ"}
            ]
        }
   }
}

its structure is described as:

variable "secrets" {
    type = map(object({
            secrets = list(
                object({
                    secret_scope = string,
                    secret_key = string,
                    secret_value =string
                })),
            acls = list(
                object({
                    secret_scope = string,
                    principal = string,
                    permission = string
            }))}))
}

I want to create a new local variable "secret_list" which outputs this:

secret_list =  [
{"secret_scope": "datacore", "secret_key": "serviceaccount-databricks-deploy", "secret_value": "dummy"},
{"secret_scope": "datacore", "secret_key": "serviceaccount-databricks-deploy", "secret_value": "dummy"},
{"secret_scope": "ai", "secret_key": "serviceaccount-ai", "secret_value": "dummy"},
{"secret_scope": "ai", "secret_key": "serviceaccount-ai-private-key", "secret_value": "dummy"}
]

This is a list of objects that contains all the secrets that are inside the "secrets" variable.

I have tried to create a local variable "secret_list" using a for loop like this:

locals {
    secret_list = {
        value = flatten([
            for secrets in var.secrets : [
                for secret_attributes in secrets.secrets : secret_attributes
            ]
        ])
    }
}

and created a new output object to view the result in the console:

output "secret_list" {
  value = local.secret_list
}

I cannot seem to get the desired output. In the console it looks like:

 secret_list              = {
        value = [
            {
                secret_key   = "serviceaccount-databricks-deploy"
                secret_scope = "datacore"
                secret_value = "dummy"
            },
            {
                secret_key   = "serviceaccount-datacore"
                secret_scope = "datacore"
                secret_value = "dummy"
            },
            {
                secret_key   = "serviceaccount-ai"
                secret_scope = "ai"
                secret_value = "dummy"
            },
            {
                secret_key   = "serviceaccount-ai-private-key"
                secret_scope = "ai"
                secret_value = "dummy"
            }
       ]
}

How can I get to:

secret_list =  [
{"secret_scope": "datacore", "secret_key": "serviceaccount-databricks-deploy", "secret_value": "dummy"},
{"secret_scope": "datacore", "secret_key": "serviceaccount-databricks-deploy", "secret_value": "dummy"},
{"secret_scope": "ai", "secret_key": "serviceaccount-ai", "secret_value": "dummy"},
{"secret_scope": "ai", "secret_key": "serviceaccount-ai-private-key", "secret_value": "dummy"}
]

CodePudding user response:

To remove the delta between the observed and desired structures, your locals block with the for expressions:

locals {
  secret_list = {
    value = flatten([
      for secrets in var.secrets : [
        for secret_attributes in secrets.secrets : secret_attributes
      ]
    ])
  }
}

needs to not specify an outer map constructor with a key of value. The value of that map should be the entire structure:

locals {
  secret_list = flatten([
    for secrets in var.secrets : [
      for secret_attributes in secrets.secrets : secret_attributes
    ]
  ])
}
  • Related