Terraform动态循环列表中的元素并基于值展开

Terraform动态循环列表中的元素并基于值展开,terraform,Terraform,这有点难以描述。为了清晰起见,我简化了一张地图,它看起来像这样: server_ip_configs = { mgmt = { ct = "1" } applicationgateway = { ct = "1" } monitor = { ct = "1" } app = { ct = "3" } } 我想做的是迭代映射以创建一个平面列表,其中元素乘以

这有点难以描述。为了清晰起见,我简化了一张地图,它看起来像这样:

server_ip_configs = {
mgmt        = {
    ct      = "1"
    }
applicationgateway    = {
    ct      = "1"
    }
monitor     = {
    ct      = "1"
    }
app      = {
    ct      = "3"
    }
}
我想做的是迭代映射以创建一个平面列表,其中元素乘以ct属性的数量,形成一个新的平面列表。 因此,我们最终得到的列表有点像这样:

server_ip_configs_mapped = [
       {
        name      = "mgmt-1"
        }
       {
        name      = "applicationgateway-1"
        }
       {
        name      = "monitor-1"
        }
       {
        name      = "app-1"
        }
       {
        name      = "app-2"
        }
       {
        name      = "app-3"
        }

    ]
通过设置变量为每行显式创建元素列表非常简单:

data "null_data_source" "server_list_ip_configs" {
  count = lookup(var.server_ip_configs[var.server_role], "ct", 0)

  inputs = {
    name    =   "${var.server_role}-${count.index +1}"
  }
}
我可以将其放在一个模块中,并调用该模块的多个实例,然后计算结果。但这不是一个很好的方法,而且一点也不干燥。我认为在地形中没有其他方法可以做到这一点,对吗?这是因为terraform本质上是声明性的,也许我应该声明一个包含多个实例的列表,而不是尝试生成一个? 使用for循环不会起作用,因为根据我所看到的,您不能使用整数显式地迭代。因此,没有:

for i in 5 

欢迎你的回答。谢谢。

Terraform 0.12为循环引入,您可以执行以下操作:

variable "server_ip_configs" {
  default = {
    mgmt               = { ct = "1" }
    applicationgateway = { ct = "1" }
    monitor            = { ct = "1" }
    app                = { ct = "3" }
  }
}

output "myout" {
  value = [for k, v in var.server_ip_configs : { "name" = join("-", [k, v.ct]) }]
}

这里是它的地形输出


terraform apply

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

myout = [
  {
    "name" = "app-3"
  },
  {
    "name" = "applicationgateway-1"
  },
  {
    "name" = "mgmt-1"
  },
  {
    "name" = "monitor-1"
  },
]

@赫尔德很接近,但我对请求的解释略有不同。您的意图是基于ct值构建列表,它看起来像一个计数。这应该是你要找的。请注意,使用
range()
来执行您在5语句中查找的
for i

variable "server_ip_configs" {
  default = {
    mgmt               = { ct = "1" }
    applicationgateway = { ct = "1" }
    monitor            = { ct = "1" }
    app                = { ct = "3" }
  }
}

locals {
  server_ip_configs_mapped = flatten([
    for server, count in var.server_ip_configs : [
      for i in range(count.ct) : {
        "name" = join("-", [server, i+1])
      }
    ]
  ])
}

output server_ip_configs_mapped { value = local.server_ip_configs_mapped }
输出:

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

server_ip_configs_mapped = [
  {
    "name" = "app-1"
  },
  {
    "name" = "app-2"
  },
  {
    "name" = "app-3"
  },
  {
    "name" = "applicationgateway-1"
  },
  {
    "name" = "mgmt-1"
  },
  {
    "name" = "monitor-1"
  },
]

对不起,赫尔德,但这只是我的一部分,我为没有解释我自己而道歉。我知道我可以使用for循环遍历列表。但是在您的示例中,您没有迭代ct所暗示的内部循环。我需要应用程序的三个项目,应用程序1,应用程序2和应用程序3在该平面列表中。你的例子只显示了一个(app-3)。@user1451104是的,我错过了那个部分。。。但对于将来的问题,如果你知道如何使用循环,请始终展示一个例子,说明你在代码中尝试了什么,哪些不起作用。谢谢泰勒!我将对此进行测试,但它看起来正是我试图实现的目标。