具有嵌入式功能的Terraform格式列表插值及其执行顺序

时间:2019-01-17 04:37:01

标签: terraform

我有这个:

formatlist( "cidrhost( cidrsubnet(%s, 1, 0), -3)", list("10.70.32.0/21"))

输出:

[
  "cidrhost( cidrsubnet(10.70.32.0/21, 1, 0), -3)",
]

但是我希望执行该命令,并将结果存储在formatlist返回列表中。我是否可以让Terraform推迟执行cidr函数,直到用列表项替换了格式列表%s之后?

此刻,如果我删除引号并尝试它只会失败,例如

formatlist( cidrhost( cidrsubnet("%s", 1, 0), -3), list("10.70.32.0/21"))

  cidrsubnet: invalid CIDR expression: invalid CIDR address: %s in:

${formatlist( cidrhost( cidrsubnet("%s", 1, 0), -3), list("10.70.32.0/21"))}

这使我相信cidrsubnetformatlist有机会做任何事情之前就已经开始运行了。

更新示例:

例如,我有一个很长的class-c子网列表,我们将其分成两半,从第一个子网开始,我们为每个子网mgmt服务器使用倒数第二个可用(非广播)地址。

例如列表(实际上更长)

10.70.30.0/24
10.70.31.0/24
10.70.32.0/24

cidrsubnet("10.70.30.0/24", 1, 0)将一分为二并返回第一个子网,即10.70.30.0/25。然后cidrhost(10.70.30.0/25, -3)将给我倒数第三个地址,即10.70.30.124

所以我想要的上述列表的输出是:

10.70.30.124/25
10.70.31.124/25
10.70.32.124/25

鉴于Terraform中缺乏迭代功能,我想将上述逻辑与formatlist结合使用以遍历源列表,做cidr/subnet魔术并输出所需的列表。

非常感谢。

1 个答案:

答案 0 :(得分:0)

variable "ipcidr" {
  default = "10.70.32.0/24"
}

output "new_ipcidr" {
  value = "${join("/", list(cidrhost(cidrsubnet(var.ipcidr, 1, 0), -4), element(split("/", cidrsubnet(var.ipcidr, 1, 0)), 1)))}"
}
$ terraform init && terraform apply
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

new_ipcidr = 10.70.32.124/25

要使此功能适用于列表,应使用countcount.index循环方法将输出值输入资源。例如。

resource "aws_subnet" "main" {
  count      = "${length(var.ipcidrs)}"
  vpc_id     = "${aws_vpc.main.id}"
  cidr_block = "${join("/", list(cidrhost(cidrsubnet(var.ipcidrs[count.index], 1, 0), -4), element(split("/", cidrsubnet(var.ipcidrs[count.index], 1, 0)), 1)))}"
}