【问题标题】:Terraform Creating map dynamically using local variable instead of input variableTerraform 使用局部变量而不是输入变量动态创建地图
【发布时间】:2020-07-28 10:40:55
【问题描述】:

要求:我有一堆 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)}"
  }
}

变量.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 terraform-provider-aws terraform0.12+


    【解决方案1】:

    您在此处编写的映射表似乎描述了modulo operation 的一种变体,它从一开始计数,而不是从零开始计数。

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

    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 到总计数,然后生成一个映射,该结果的每个元素一个元素,其中值是我在 resource 块中显示的相同模计算的结果以上。

    从 Terraform 0.12 开始,不再需要使用 null_resource 或 null_data_source 来转换列表,因为 for 表达式语法现在可以满足相同的用例。

    【讨论】:

      【解决方案2】:

      我可以使用 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
          },
        ]
      

      【讨论】:

      • 谢谢,它对我有用,以防孩子。但是,所有 6 个孩子的父母都是相同的。 Child1-parent1、Child2-parent1、child3-parent1、child4-parent1、child5-parent1、child6-parent1 然后是 child1-parent2。我可以请相同的元素语法吗?很好的帮助!
      • 谢谢 Montassar,对不起,我的示例列表可能造成了混乱。实际上我使用两个分开的父母和孩子。再次道歉。所有 6 个孩子的父母都是相同的。
      • 你好@kamlendra 谢谢,我会在答案中添加格式
      猜你喜欢
      • 1970-01-01
      • 2021-06-11
      • 2018-04-10
      • 2013-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-10
      相关资源
      最近更新 更多