2

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 !

9
  • 2
    Why would you need flatten? From the information provided in the question, you could do this with a quick and easy for_each = var.rbac_roles["view"]. Is there some other nuance or subtlety here? Commented Jan 11, 2022 at 15:42
  • Yup, as @MattSchuchard said, you are referencing the variable and its values in a wrong way. Commented Jan 11, 2022 at 15:44
  • But how am I supposed to loop over my namespaces afterward ? I might have gotten lost as it's been a few hours I'm stuck >> Commented Jan 11, 2022 at 15:52
  • How did it go? Still unclear what you can do? Commented Jan 13, 2022 at 6:00
  • 1
    If code works, you can accept the answer. You can accept your own answer if you want. Without acceptance the issues appears unresolved. Commented Jan 15, 2022 at 7:58

2 Answers 2

6

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"                             
  }                                                  
}                             
Sign up to request clarification or add additional context in comments.

Comments

3

Using the flatten() approach :

resource "kubernetes_role_binding" "default_roles_binding" {

  for_each = {
    for binding in flatten([
      for role_name, groups in var.rbac_roles : [
        for group in groups : [
          for ns in group.namespaces : [
            {
              binding_name = lower("${ns}-${group.group_name}-${role_name}")
              role         = role_name
              group_id     = group.group_id
              group_name   = group.group_name
              ns           = ns
            }
          ]
        ]
  ]]) : binding.binding_name => binding }


  metadata {
    namespace = each.value.ns
    name      = each.value.binding_name
    annotations = { "group_name" : each.value.group_name }
  }
  role_ref {
    api_group = "rbac.authorization.k8s.io"
    kind      = "Role"
    name      = each.value.role
  }
  subject {
    kind = "Group"
    name = each.value.group_id
  }

  depends_on = [
    azurerm_kubernetes_cluster.aks
  ]  
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.