如何处理Terraform中的可重复项目

时间:2017-03-20 10:37:20

标签: terraform

假设我需要在terraform中配置大量的vpc子网。每个子网都有一个cidr,一个名称和一个可用区。因此,在其他配置管理工具中,我可以执行以下操作:

[  
   {  
      "name":"subnet1",
      "cidr":"10.0.0.1/24",
      "az":"us-west-1a"
   },
   {  
      "name":"subnet2",
      "cidr":"10.0.0.2/24",
      "az":"us-west-1b"
   }
]

然后迭代该数组。

就我所见,Terraform没有数组/对象的概念。因此,对于单个属性的数组,我只使用一个列表项:

subnets: ["10.0.0.1/24","10.0.0.2/24"]

但这并不允许我将子网命名或放置在我想要的位置。 我知道我也可以在Terraform中使用多个列表,例如:

subnet_names: ["subnet1", "subnet2"]
subnets: ["10.0.0.1/24","10.0.0.2/24"]
subnet_az: ["us-west-1a", "us-west-1b"]

但这让我感到慌乱和反直觉。我看到的最后一个选项是将所有内容混合成一个丑陋的字符串列表,然后将它们拆分为Terraform:

things: ["subnet1__10.0.0.1/24__us-west-1a","subnet2__10.0.0.2/24__us-west-2a"]

但那只是丑陋。

如何在Terraform中处理数组/对象类型的重复?现在我只是明确定义了所有的东西,导致一个简单的vpc定义为300行: - (

1 个答案:

答案 0 :(得分:1)

正如您所见,目前Terraform并不支持您尝试在此处创建的结构化数据列表。

如您在问题中显示的那样,有多个平面字符串列表是这个问题的常见解决方案。它有效,但正如您所看到的那样,跟踪哪些值属于那种方式有点违反直觉。

可能产生更具可读性和可维护性的结果的另一种方法是将aws_subnet资源分解为一个模块,该模块负责处理所有子网始终相同的元素。然后,您可以为每个子网实例化一次模块,仅提供不同的值:

module "subnet1" {
  source = "./subnet"

  name = "subnet1"
  cidr = "10.0.0.1/24"
  az   = "us-west-1a"
}

module "subnet2" {
  source = "./subnet"

  name = "subnet2"
  cidr = "10.0.0.2/24"
  az   = "us-west-1b"
}

在许多情况下,AZ和CIDR块之间存在某种系统关系。如果这对您来说是正确的,那么您也可以使用您的模块对这些编号规则进行编码。例如,在subnet模块中:

variable "region_network_numbers" {
  default = {
    "us-west-1" = 0
    "us-east-1" = 1
    "us-west-2" = 2
  }
}

variable "az_network_numbers" {
  default = {
    a = 1
    b = 2
  }
}

variable "base_cidr_block" {
  default = "10.0.0.0/8"
}

variable "az" {
}

data "aws_availability_zone" "selected" {
  name = "${var.az}"
}

resource "aws_subnet" "main" {
  cidr_block = "${cidrsubnet(cidrsubnet(var.base_cidr_block, 8, var.region_network_numbers[data.aws_availability_zone.selected.region]), 4, var.az_network_numbers[data.aws_availability_zone.selected.name_suffix])}"
  # ...
}

使用此功能,只需向模块提供az参数,系统地从AZ名称生成cidrname。这与the aws_availability_zone data source示例中显示的概念相同,Terraform存储库本身也有a more complete, elaborate example of this