flatten object made of nested list in terraform

I have the following variable that I try to parse :

variable.tf

variable "rbac_roles" {
  type = object(
    {
      view = list(object({
        group_name = string,
        group_id = string,
        namespaces = list(string)
      })),
      edit = list(object({
        group_name = string,
        group_id = string,
        namespaces = list(string)
      })),
      admin = list(object({
        group_name = string,
        group_id = string,
        namespaces = list(string)
      }))            
    }
  )
}

variable.tfvars

rbac_roles = {
  view = [
    {
      group_name = "group1",
      group_id   = "123",
      namespaces = ["default", "namespace1"]
    },
    {
      group_name = "group2",
      group_id   = "456",
      namespaces = ["namespace2"]
    }
  ],
  edit = [
    {
      group_name = "group1",
      group_id   = "123",
      namespaces = ["namespace2"]
    }
  ],
  admin = [
    {
      group_name = "group3",
      group_id   = "789",
      namespaces = ["default, namespace1, namespace2"]
    },

  ]
}

I try to create the following resources :

resource "kubernetes_role_binding" "view_cluster_role_binding" {
  metadata {
    name = ${group}-${namespace}-viewer-binding
    namespace = ${namespace}
  } 
  role_ref {
    api_group = "rbac.authorization.k8s.io"
    kind      = "Role"
    name      = "view"
  }
  subject {
    kind      = "Group"
    name      = ${group}
    api_group = "rbac.authorization.k8s.io"
  }
}  
resource "kubernetes_role_binding" "edit_cluster_role_binding" {
  metadata {
    name = ${group}-${namespace}-viewer-binding
    namespace = ${namespace}
  } 
  role_ref {
    api_group = "rbac.authorization.k8s.io"
    kind      = "Role"
    name      = "edit"
  }
  subject {
    kind      = "Group"
    name      = ${group}
    api_group = "rbac.authorization.k8s.io"
  }
} 
resource "kubernetes_role_binding" "admin_cluster_role_binding" {
  metadata {
    name = ${group}-${namespace}-viewer-binding
    namespace = ${namespace}
  } 
  role_ref {
    api_group = "rbac.authorization.k8s.io"
    kind      = "Role"
    name      = "admin"
  }
  subject {
    kind      = "Group"
    name      = ${group}
    api_group = "rbac.authorization.k8s.io"
  }
} 

So far I have tried to flatten() my list and to loop over it with for and foreach but I haven't been successful yet. From what I understand I need to use a locals{} to reach my goal, but I can't get the right syntax. Any help will be appreciated !


Solution 1:

First this is wrong ["default, namespace1, namespace2"]. It should be ["default", "namespace1", "namespace2"]. Once you fix that, you can flatten your data structure as follows:

locals {
   flat_rbac_roles = merge([
         for role, groups in var.rbac_roles:
           merge([
             for group_idx, group in groups:
               {
                 for namespace_idx, namespace in group["namespaces"]:                     
                       "${role}-${group_idx}-${namespace_idx}" => {
                       role_name = role
                       group_name = group["group_name"]
                       group_id = group["group_id"]
                       namespace = namespace
                   }
               }
           ]...)
     ]...)
}

which gives:

{                                                                                                                                                                                                      
  "admin-0-0" = {                                                                                                                                                                                             
    "group_id" = "789"                                                                                                                                                                                        
    "group_name" = "group3"                                                                                                                                                                                   
    "namespace" = "default"                                                                                                                                                                                   
    "role_name" = "admin"                                                                                                                                                                                     
  }                                                                                                                                                                                                           
  "admin-0-1" = {                                                                                                                                                                                             
    "group_id" = "789"                                                                                                                                                                                        
    "group_name" = "group3"                                                                                                                                                                                   
    "namespace" = "namespace1"                                                                                                                                                                                
    "role_name" = "admin"                                                                                                                                                                                     
  }                                                                                                                                                                                                           
  "admin-0-2" = {                                                                                                                                                                                             
    "group_id" = "789"                                                                                                                                                                                        
    "group_name" = "group3"                                                                                                                                                                                   
    "namespace" = "namespace2"                                                                                                                                                                                
    "role_name" = "admin"                                                                                                                                                                                     
  }                                                                                                                                                                                                           
  "edit-0-0" = {                                                                                                                                                                                              
    "group_id" = "123"                                                                                                                                                                                        
    "group_name" = "group1"                                                                                                                                                                                   
    "namespace" = "namespace2"                                                                                                                                                                                
    "role_name" = "edit"                                                                                                                                                                                      
  }                                                                                                                                                                                                           
  "view-0-0" = {                                                                                                                                                                                              
    "group_id" = "123"                                                                                                                                                                                        
    "group_name" = "group1"                                                                                                                                                                                   
    "namespace" = "default"                                                                                                                                                                                   
    "role_name" = "view"                                                                                                                                                                                      
  }                                                                                                                                                                                                           
  "view-0-1" = {                                                                                                                                                                                              
    "group_id" = "123"                                                                                                                                                                                        
    "group_name" = "group1"                                                                                                                                                                                   
    "namespace" = "namespace1"                       
    "role_name" = "view"                             
  }                                                  
  "view-1-0" = {                                     
    "group_id" = "456"                               
    "group_name" = "group2"                          
    "namespace" = "namespace2"                       
    "role_name" = "view"                             
  }                                                  
}