Terraform使用局部变量而不是输入变量

时间:2020-07-28 10:40:55

标签: terraform terraform-provider-aws terraform0.12+

要求:我有一堆EC2。我正在根据标签分组。在此示例中,组总数= 4,每个组具有7个EC2:1个父代-6个子代。在这里,我要分享孩子的代码,这个孩子的命名很重要。

工作代码:在这里,我正在共享子EC2代码,该代码与名为:ws_to_Child_Node_name_map_count的地图类型的输入变量完全兼容。现在,我希望它具有可伸缩性(父子级数),因此我希望使用“在本地人中动态创建的地图”而不是使用输入变量。 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
}

2 个答案:

答案 0 :(得分:1)

我可以使用hack帮助您使用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"
  },
]

如果要检查每个父母和每个孩子(可以使用本地人) 您可以创建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
      }
      ]
    
      }
    }

您的输出将按如下方式由父母分组:

  "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
    },
  ]

答案 1 :(得分:1)

您在此处编写的映射表似乎正在描述modulo operation的变体,该变体从1开始计数而不是从0开始计数。

如果这是您的意图,则可以潜在地使用表达式来动态计算,而不用生成单独的映射表。

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允许您使用基于一的计数而不是基于零的计数。对于从零开始的数字,它将减少为count.index % var.child_count


如果出于某些原因仍要使映射表成为本地值,则可以在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到您的总计数进行计数,然后生成一个映射,该映射在结果的每个元素中包含一个元素,其中值是我在{{ 1}}上方。

从Terraform 0.12开始,永远不需要使用resourcenull_resource作为转换列表的技巧,因为null_data_source表达式语法现在可以满足相同的用例。 / p>