使用 ‘for_each’ 或 ‘for’ 创建动态资源

80次阅读
没有评论

问题描述

想要使用以下代码创建多个资源:

resource "group" "list" {
  g_name      = group_name
  p_name      = project_name
}

输入的本地变量是嵌套的:

local.input{
  "group" = [
    {
      "name" = "group1"
      "projects" = [
        "project1",
        "project3",
      ]
    },
    {
      "name" = "group2"
      "projects" = [
        "project18",
        "project31",
      ]
    },
  ]
}

用户已经成功将其转换为更好的形式:

flatten([for grp_key, group in local.input.group: [for project in group.projects: { group_name=group.name, project_name=project} ]])[
  {
    "group_name" = "group1"
    "project_name" = "project1"
  },
  {
    "group_name" = "group1"
    "project_name" = "project3"
  },
  {
    "group_name" = "group2"
    "project_name" = "project18"
  },
  {
    "group_name" = "group2"
    "project_name" = "project31"
  },
]

但是,由于这不是一个mapset,用户无法使用for_each
用户想知道如何使用for来创建多个资源,类似于以下代码:

resource "group" "list" {
  for item in ... :
    g_name=item.group_name
    p_name=item.project_name
}

解决方案

请注意以下操作注意版本差异及修改前做好备份。
用户可以使用count来解决这个问题,并通过索引访问每个项目。具体步骤如下:
1. 在resource块中使用count属性来指定要创建的资源数量。
2. 在resource块内部,使用element函数来访问每个项目。
以下是一个示例代码:

resource "group" "list" {
  count = length(flatten([for grp_key, group in local.input.group: [for project in group.projects: { group_name=group.name, project_name=project} ]]))
  g_name = element(flatten([for grp_key, group in local.input.group: [for project in group.projects: { group_name=group.name, project_name=project} ]]), count.index)["group_name"]
  p_name = element(flatten([for grp_key, group in local.input.group: [for project in group.projects: { group_name=group.name, project_name=project} ]]), count.index)["project_name"]
}

在上面的示例中,我们使用count属性来指定要创建的资源数量,该数量等于转换后的项目列表的长度。然后,我们使用element函数来访问每个项目的group_nameproject_name属性,并将其分配给g_namep_name变量。
请注意,这种方法需要确保local.input.group的结构与示例中的结构一致。如果结构不同,你需要相应地调整代码。

正文完