【问题标题】:flatten object made of nested list in terraform在 terraform 中展平由嵌套列表组成的对象
【发布时间】:2022-01-11 15:20:05
【问题描述】:

我尝试解析以下变量:

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

  ]
}

我尝试创建以下资源:

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{} 来达到我的目标,但我无法获得正确的语法。任何帮助将不胜感激!

【问题讨论】:

  • 为什么需要flatten?根据问题中提供的信息,您可以使用快速简单的for_each = var.rbac_roles["view"] 来完成此操作。这里还有其他细微差别或微妙之处吗?
  • 是的,正如@MattSchuchard 所说,您以错误的方式引用变量及其值。
  • 但是之后我应该如何遍历我的命名空间呢?我可能迷路了,因为我被困了几个小时>>
  • 进展如何?仍然不清楚你能做什么?
  • 如果代码有效,您可以接受答案。如果你愿意,你可以接受你自己的答案。如果不接受,问题似乎就无法解决。

标签: list object kubernetes terraform flatten


【解决方案1】:

首先这是错误的["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"                             
  }                                                  
}                             

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2021-03-22
      • 2013-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-24
      • 1970-01-01
      • 2021-06-01
      • 1970-01-01
      相关资源
      最近更新 更多