Terraform 使用局部变量而不是输入变量动态创建地图
Terraform Creating map dynamically using local variable instead of input variable
要求:我有一堆EC2。我根据标签对其进行分组。在此示例中,组总数 =4,每个组有 7 个 EC2:1 parent-6 Child。我在这里分享 child 的代码,其命名很重要。
工作 code:Here 我正在分享 child EC2 代码,它与名为 :ws_to_Child_Node_name_map_count 的地图类型的输入变量一起工作得很好。现在我希望它是可扩展的(parent-child 的数量),我希望使用 'dynamically created map in locals' 而不是使用输入变量。
main.tf
resource "aws_instance" "ec2_instance_child" {
count = var.ec2_instance_child_count
tags = {
NodeName = "${lookup(var.ws_to_Child_Node_name_map_count, count.index+1, 99)}"
}
}
variable.tf
variable "ws_to_Child_Node_name_map_count" {
type = map
default = {
"1"="1"
"2"="2"
"3"="3"
"4"="4"
"5"="5"
"6"="6"
"7"="1"
"8"="2"
"9"="3"
"10"="4"
"11"="5"
"12"="6"
"13"="1"
"14"="2"
"15"="3"
"16"="4"
"17"="5"
"18"="6"
"19"="1"
"20"="2"
"21"="3"
"22"="4"
"23"="5"
"24"="6"
}
}
variable "ec2_instance_child_count" {
description = "Number of instances to run"
default = "24" #number of group *6
}
上面显示的地图我想使用两个变量动态创建,以后我不会是常量。
variable "child_count" {
default = 6
}
variable "group_count" {
default = 4
}
我可以帮助您使用 terraform 创建动态地图列表,这里是一个示例:
locals {
childs = 24
group = [1,2,3,4,5,6]
}
# Here's the hack! The null_resource has a map called triggers that we can set to arbitrary values.
# We can also use count to create a list of null_resources. By accessing the triggers map inside of
# that list, we get our list of maps! See the output variable below.
resource "null_resource" "res" {
count = local.childs+1
triggers = {
parent = "${count.index}"
child = "${element(local.group, count.index)}"
}
}
# And here's the result! We have a dynamic list of maps. I'm just outputting it here
output "map" {
value = "${null_resource.res.*.triggers}"
}
你可以尝试创建一个 main.tf 和 运行 terraform init
terraform apply
结果应该是这样的:
map = [
{
"child" = "1"
"parent" = "0"
},
{
"child" = "2"
"parent" = "1"
},
{
"child" = "3"
"parent" = "2"
},
{
"child" = "4"
"parent" = "3"
},
{
"child" = "5"
"parent" = "4"
},
{
"child" = "6"
"parent" = "5"
},
{
"child" = "1"
"parent" = "6"
},
{
"child" = "2"
"parent" = "7"
},
{
"child" = "3"
"parent" = "8"
},
{
"child" = "4"
"parent" = "9"
},
{
"child" = "5"
"parent" = "10"
},
{
"child" = "6"
"parent" = "11"
},
{
"child" = "1"
"parent" = "12"
},
{
"child" = "2"
"parent" = "13"
},
{
"child" = "3"
"parent" = "14"
},
{
"child" = "4"
"parent" = "15"
},
{
"child" = "5"
"parent" = "16"
},
{
"child" = "6"
"parent" = "17"
},
{
"child" = "1"
"parent" = "18"
},
{
"child" = "2"
"parent" = "19"
},
{
"child" = "3"
"parent" = "20"
},
{
"child" = "4"
"parent" = "21"
},
{
"child" = "5"
"parent" = "22"
},
{
"child" = "6"
"parent" = "23"
},
{
"child" = "1"
"parent" = "24"
},
]
如果你想检查每个 parent 和每个 child (你可以使用 locals)
你可以像这样创建 2 个循环:
locals {
childs = 24
group = 6
result = {
for j in range(1, local.childs + 1) : j => [
for i in range(1, local.group + 1) : {
child = i,
parent = j
}
]
}
}
您的输出将按 parent 分组,如下所示:
"1" = [
{
"child" = 1
"parent" = 1
},
{
"child" = 2
"parent" = 1
},
{
"child" = 3
"parent" = 1
},
{
"child" = 4
"parent" = 1
},
{
"child" = 5
"parent" = 1
},
{
"child" = 6
"parent" = 1
},
]
"2" = [
{
"child" = 1
"parent" = 2
},
{
"child" = 2
"parent" = 2
},
{
"child" = 3
"parent" = 2
},
{
"child" = 4
"parent" = 2
},
{
"child" = 5
"parent" = 2
},
{
"child" = 6
"parent" = 2
},
]
您在此处编写的映射 table 似乎描述了 modulo operation 的变体,它从 1 而不是 0 开始计数。
如果这是您的意图,您可以使用表达式动态计算,而不是生成单独的映射 table。
variable "child_count" {
default = 6
}
variable "group_count" {
default = 4
}
resource "aws_instance" "example" {
count = var.child_count * var.group_count
tags = {
# The % symbol is Terraform's modulo operator
NodeName = ((count.index - 1) % var.child_count) + 1
}
}
上面表达式中的 - 1
和 + 1
允许您使用基于 1 的计数而不是基于 0 的计数。对于从零开始,这将减少到 count.index % var.child_count
.
如果您出于某种原因仍想在本地值中进行映射 table,您可以在 for
expression 中执行上述计算:
locals {
lookup_table = {
for n in range(1, (var.child_count * var.group_count) + 1) :
n => ((n - 1) % var.child_count) + 1
}
}
这使用 the range
function 从 1 计数到您的总计数,然后生成一个映射,该结果的每个元素一个元素,其中值是我在resource
块以上。
从 Terraform 0.12 开始,不再需要使用 null_resource
或 null_data_source
作为转换列表的 hack,因为 for
表达式语法现在可以满足相同的用例.
要求:我有一堆EC2。我根据标签对其进行分组。在此示例中,组总数 =4,每个组有 7 个 EC2:1 parent-6 Child。我在这里分享 child 的代码,其命名很重要。
工作 code:Here 我正在分享 child EC2 代码,它与名为 :ws_to_Child_Node_name_map_count 的地图类型的输入变量一起工作得很好。现在我希望它是可扩展的(parent-child 的数量),我希望使用 'dynamically created map in locals' 而不是使用输入变量。 main.tf
resource "aws_instance" "ec2_instance_child" {
count = var.ec2_instance_child_count
tags = {
NodeName = "${lookup(var.ws_to_Child_Node_name_map_count, count.index+1, 99)}"
}
}
variable.tf
variable "ws_to_Child_Node_name_map_count" {
type = map
default = {
"1"="1"
"2"="2"
"3"="3"
"4"="4"
"5"="5"
"6"="6"
"7"="1"
"8"="2"
"9"="3"
"10"="4"
"11"="5"
"12"="6"
"13"="1"
"14"="2"
"15"="3"
"16"="4"
"17"="5"
"18"="6"
"19"="1"
"20"="2"
"21"="3"
"22"="4"
"23"="5"
"24"="6"
}
}
variable "ec2_instance_child_count" {
description = "Number of instances to run"
default = "24" #number of group *6
}
上面显示的地图我想使用两个变量动态创建,以后我不会是常量。
variable "child_count" {
default = 6
}
variable "group_count" {
default = 4
}
我可以帮助您使用 terraform 创建动态地图列表,这里是一个示例:
locals {
childs = 24
group = [1,2,3,4,5,6]
}
# Here's the hack! The null_resource has a map called triggers that we can set to arbitrary values.
# We can also use count to create a list of null_resources. By accessing the triggers map inside of
# that list, we get our list of maps! See the output variable below.
resource "null_resource" "res" {
count = local.childs+1
triggers = {
parent = "${count.index}"
child = "${element(local.group, count.index)}"
}
}
# And here's the result! We have a dynamic list of maps. I'm just outputting it here
output "map" {
value = "${null_resource.res.*.triggers}"
}
你可以尝试创建一个 main.tf 和 运行 terraform init
terraform apply
结果应该是这样的:
map = [
{
"child" = "1"
"parent" = "0"
},
{
"child" = "2"
"parent" = "1"
},
{
"child" = "3"
"parent" = "2"
},
{
"child" = "4"
"parent" = "3"
},
{
"child" = "5"
"parent" = "4"
},
{
"child" = "6"
"parent" = "5"
},
{
"child" = "1"
"parent" = "6"
},
{
"child" = "2"
"parent" = "7"
},
{
"child" = "3"
"parent" = "8"
},
{
"child" = "4"
"parent" = "9"
},
{
"child" = "5"
"parent" = "10"
},
{
"child" = "6"
"parent" = "11"
},
{
"child" = "1"
"parent" = "12"
},
{
"child" = "2"
"parent" = "13"
},
{
"child" = "3"
"parent" = "14"
},
{
"child" = "4"
"parent" = "15"
},
{
"child" = "5"
"parent" = "16"
},
{
"child" = "6"
"parent" = "17"
},
{
"child" = "1"
"parent" = "18"
},
{
"child" = "2"
"parent" = "19"
},
{
"child" = "3"
"parent" = "20"
},
{
"child" = "4"
"parent" = "21"
},
{
"child" = "5"
"parent" = "22"
},
{
"child" = "6"
"parent" = "23"
},
{
"child" = "1"
"parent" = "24"
},
]
如果你想检查每个 parent 和每个 child (你可以使用 locals) 你可以像这样创建 2 个循环:
locals {
childs = 24
group = 6
result = {
for j in range(1, local.childs + 1) : j => [
for i in range(1, local.group + 1) : {
child = i,
parent = j
}
]
}
}
您的输出将按 parent 分组,如下所示:
"1" = [
{
"child" = 1
"parent" = 1
},
{
"child" = 2
"parent" = 1
},
{
"child" = 3
"parent" = 1
},
{
"child" = 4
"parent" = 1
},
{
"child" = 5
"parent" = 1
},
{
"child" = 6
"parent" = 1
},
]
"2" = [
{
"child" = 1
"parent" = 2
},
{
"child" = 2
"parent" = 2
},
{
"child" = 3
"parent" = 2
},
{
"child" = 4
"parent" = 2
},
{
"child" = 5
"parent" = 2
},
{
"child" = 6
"parent" = 2
},
]
您在此处编写的映射 table 似乎描述了 modulo operation 的变体,它从 1 而不是 0 开始计数。
如果这是您的意图,您可以使用表达式动态计算,而不是生成单独的映射 table。
variable "child_count" {
default = 6
}
variable "group_count" {
default = 4
}
resource "aws_instance" "example" {
count = var.child_count * var.group_count
tags = {
# The % symbol is Terraform's modulo operator
NodeName = ((count.index - 1) % var.child_count) + 1
}
}
上面表达式中的 - 1
和 + 1
允许您使用基于 1 的计数而不是基于 0 的计数。对于从零开始,这将减少到 count.index % var.child_count
.
如果您出于某种原因仍想在本地值中进行映射 table,您可以在 for
expression 中执行上述计算:
locals {
lookup_table = {
for n in range(1, (var.child_count * var.group_count) + 1) :
n => ((n - 1) % var.child_count) + 1
}
}
这使用 the range
function 从 1 计数到您的总计数,然后生成一个映射,该结果的每个元素一个元素,其中值是我在resource
块以上。
从 Terraform 0.12 开始,不再需要使用 null_resource
或 null_data_source
作为转换列表的 hack,因为 for
表达式语法现在可以满足相同的用例.