Search code examples
terraformterraform-provider-awsamazon-eks

Encode specific attribute in a nested map


I am trying to use the Terraform EKS module but have difficulty passing configuration values for my addons.

In my variable files, I have a map for all of my clusters and their configurations, it looks like this:

    clusters = {
      cluster1 = {
          cluster_addons = {
            first_addon = {
              addon_version = "1.2.3"
              configuration_value = {...} # to be encoded at runtime
            },
            second_addon = {
              addon_version = "1.5.2"
              configuration_value = {...} # to be encoded at runtime too
            }
          }
      }
      cluster2 = {
        ...
      }
    }

The output I want, is a map with addons for each cluster, including the JSON encoded configurations, for example:

    addons = {
      cluster1 = {
            first_addon = {
              addon_version = "1.2.3"
              configuration_value = {...} # This is now JSON encoded
            },
            second_addon = {
              addon_version = "1.5.2"
              configuration_value = {...} # This is now JSON encoded
            }
      }
      cluster2 = {
          ... # Another cluster configuration
      }
    }

I came up with the following code, that almost does what I want:


  eks_addons = merge(flatten([
    for cluster_name, cluster in var.eks_clusters : [
      for addon_name, addon in cluster.cluster_addons : {
        "${cluster_name}" = { # Here is the problem, I override the addons and only keeps the last one
          "${addon_name}" = {
            addon_version        = lookup(addon, "addon_version", "")
            configuration_values = jsonencode(lookup(addon, "configuration_values", {}))
          }
        }
      }
    ]
  ])...)

The problem with this snippet is that I override the addons and only keep the last addon, instead of just appending the objects with the encoded configurations to the same map.


Solution

  • You were very close! The changes are mainly just swapping two of your lines, and then tidying up some of the overcomplication of making a list then flattening and merging. Here's a self-contained, fully working version that you should be able to tweak to fit your purpose:

    locals {
      clusters = {
        cluster1 = {
          cluster_addons = {
            first_addon = {
              addon_version = "1.2.3"
              configuration_value = {
                v1 = 12
                v2 = "34"
              }
            },
            second_addon = {
              addon_version = "1.5.2"
              configuration_value = {
                v1 = "45"
                v3 = 19
              }
            }
          }
        }
        cluster2 = {
          cluster_addons = {
            third_addon = {
              addon_version       = "2.3.4"
              configuration_value = {}
            }
          }
        }
      }
    }
    
    locals {
      eks_addons = {
        for cluster_name, cluster in local.clusters :
        cluster_name => {
          for addon_name, addon in cluster.cluster_addons :
          addon_name => {
            addon_version        = lookup(addon, "addon_version", "")
            configuration_values = jsonencode(lookup(addon, "configuration_value", {}))
          }
        }
      }
    }
    
    output "out" {
      value = local.eks_addons
    }
    

    When I run this, I get

    Changes to Outputs:
      + out = {
          + cluster1 = {
              + first_addon  = {
                  + addon_version        = "1.2.3"
                  + configuration_values = jsonencode(
                        {
                          + v1 = 12
                          + v2 = "34"
                        }
                    )
                }
              + second_addon = {
                  + addon_version        = "1.5.2"
                  + configuration_values = jsonencode(
                        {
                          + v1 = "45"
                          + v3 = 19
                        }
                    )
                }
            }
          + cluster2 = {
              + third_addon = {
                  + addon_version        = "2.3.4"
                  + configuration_values = jsonencode({})
                }
            }
        }