展平由 terraform 中的嵌套列表构成的对象

flatten object made of nested list in terraform

我尝试解析以下变量:

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.tf变量

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"]
    },

  ]
}

我尝试创建以下资源:

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"
  }
} 

到目前为止,我已经尝试 flatten() 我的列表并使用 forforeach 循环它,但我还没有成功。据我了解,我需要使用 locals{} 来实现我的目标,但我无法获得正确的语法。任何帮助将不胜感激!

首先这是错误的["default, namespace1, namespace2"]。应该是["default", "namespace1", "namespace2"]。一旦你解决了这个问题,你就可以按如下方式展平你的数据结构:

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
                   }
               }
           ]...)
     ]...)
}

给出:

{                                                                                                                                                                                                      
  "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"                             
  }                                                  
}                             

使用 flatten() 方法:

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
  ]  
}