在terraform中遍历多级地图

问题描述 投票:0回答:1

我有一个多级地图变量。我需要为每个级别的每个条目创建一个项目资源。将其视为文件夹结构。目前我正在按如下方式执行此操作,想知道是否有更好的方法来执行此操作?如果需要,我可以更新变量数据类型。 L1 项目应该在 L2 之前创建,依此类推。 L1 是 L2 的父级,依此类推。

l1_projects_list = flatten([
    for l1_project, l2_project in var.blueprint_contents :
      {
        project_name   = l1_project
        parent = "top_level"
      }
  ])

  l2_projects_list = flatten([
    for l1_project_name, l2_project in var.blueprint_contents : [
      for l2_project_name, l3_project in l2_project : {
        project_name   = l2_project_name
        parent = l1_project_name
      }
    ]
  ])

  l3_projects_list = flatten([
    for l1_project_name, l2_project in var.blueprint_contents : [
      for l2_project_name, l3_project in l2_project : [
        for l3_project_name, l4_project in l3_project : {
          project_name = l3_project_name
          parent = l2_project_name
        }
      ]
    ]
  ])

  l4_projects_list = flatten([
    for l1_project_name, l2_project in var.blueprint_contents : [
      for l2_project_name, l3_project in l2_project : [
        for l3_project_name, l4_project in l3_project : [
          for l4_project_name, l5_project in l4_project : {
            project_name = l4_project_name
            parent = l3_project_name
          }
        ]
      ]
    ]
  ])

创建文件夹结构:

resource "cloud_project" "l1_projects" {
  for_each = { for project in local.l1_projects_list : project.project_name => project }
  name                = each.key
  
}

resource "cloud_project" "l2_projects" {
  for_each = { for project in local.l2_projects_list : project.project_name => project }
  name                = each.key
  parent_project_id = cloud_project.l1_projects[each.value.parent].id

  depends_on = [cloud_project.l1_projects]
  
}

resource "cloud_project" "l3_projects" {
  for_each = { for project in local.l3_projects_list : project.project_name => project }
  name                = each.key
  parent_project_id = cloud_project.l2_projects[each.value.parent].id

  depends_on = [cloud_project.l2_projects]
  
}

resource "cloud_project" "l4_projects" {
  for_each = { for project in local.l4_projects_list : project.project_name => project }
  name                = each.key
  parent_project_id = cloud_project.l3_projects[each.value.parent].id

  depends_on = [cloud_project.l3_projects]
  
}

变量blueprint_contents的定义如下:

variable "blueprint_contents" {
  type = map(any)
  default = {
    "0. Templates" = {}

    "1. Highway" = {
      "Data" = {
        "External" = {
          "One" = {}
          "TWO"  = {}
          "Three" = {}
          "Four"  = {}
          "Five" = {}
          "Six"  = {}
        }

        "Internal" = {}
      }
      "Color" = {
        "Red" = {}
      }

      "Shape"           = {}
      "Dimensions" = {}
    }

    "2. Adhoc"      = {}
    "3. Archive"    = {}
    "4. Quarantine" = {}
  }
}
dictionary terraform
1个回答
0
投票

在 Terraform 中遍历多级地图以高效创建分层资源需要一种能够概括任何深度级别逻辑的方法。

使用递归辅助模块简化遍历:

  1. 重组
    blueprint_contents
    。理想的做法是标准化
    blueprint_contents
    变量,以便它更好地表示层次结构。
    variable "blueprint_contents" {
      type = map(any)
      default = {
        "0. Templates" = {}
        "1. Highway" = {
          "Data" = {
            "External" = {
              "One" = {}
              "TWO" = {}
            }
          }
          "Color" = {}
        }
        "2. Adhoc" = {}
      }
    }
  1. 使用模块(递归助手)动态处理资源创建。将当前地图(任何级别)、父级名称和深度传递到此模块中。该模块可以递归地创建项目。
    modules/project/
    - 用于项目创建的模块。

    variable "project_map" {
      type = map(any)
    }
    variable "parent" {
      type = string
      default = "top_level"
    }
    
    resource "cloud_project" "projects" {
      for_each = var.project_map
      name     = each.key
      parent_project_id = var.parent != "top_level" ? cloud_project.projects[var.parent].id : null
    }
    
    # Dynamically call the module for sub-projects
    module "sub_projects" {
      for_each = var.project_map
      source   = "../project"
      project_map = each.value
      parent      = each.key
    }

  1. 在顶层,用顶层地图调用模块。

    module "root_projects" {
      source      = "./modules/project"
      project_map = var.blueprint_contents
      parent      = "top_level"
    }

  1. Terraform 根据实际资源引用来管理依赖关系。父子依赖关系是通过
    parent_project_id
    字段的填充方式自动推断的。
© www.soinside.com 2019 - 2024. All rights reserved.