【问题标题】:Terraform creating a list out of a dictTerraform 从字典中创建列表
【发布时间】:2020-08-28 15:33:16
【问题描述】:

我遇到了以下问题。我创建了一个局部变量,例如:

variable vpcs {
  type = map
  default = {
    "tftest" = {
      "cidr" = "10.1.0.0/16",
      "tags" = {
        "cost"    = "shared",
        "service" = "TEST"
      }
    }
  }
}

data "aws_availability_zones" "azs" {
  state = "available"
}

variable subnets {
  type = map
  default = {
    "pub1"  = { "subnet" = 0, "rttable" = "public" },
    "pub2"  = { "subnet" = 1, "rttable" = "public" },
    "priv1" = { "subnet" = 2, "rttable" = "default" },
    "priv2" = { "subnet" = 3, "rttable" = "default" }
  }
}

locals {
  vpc_subnet_var = flatten([
    for v in keys(var.vpcs) : [
      for s in keys(var.subnets) : {
        network_name   = v
        tags           = var.vpcs[v]["tags"]
        subnet_name    = format("%v_%s", v, s)
        subnet_cidr    = cidrsubnet(var.vpcs[v]["cidr"], 8, var.subnets[s]["subnet"])
        subnet_az      = element(local.my_azs, var.subnets[s]["subnet"] % 2)
        subnet_rttable = var.subnets[s]["rttable"]
      }
    ]
  ])
  prefix = "${var.prefix}-${terraform.workspace}-tf"
  common_tags = {
    Environment = terraform.workspace
    Project     = var.project
    ManagedBy   = "Terraform"
  }
  my_azs = slice(data.aws_availability_zones.azs.names, 0, 2)
}

resource "aws_vpc" "test" {
  for_each   = var.vpcs
  cidr_block = each.value["cidr"]
  tags = merge(each.value["tags"],
    {
      Name = each.key
  })
}

resource "aws_subnet" "test" {
  for_each = {
    for s in local.vpc_subnet_var : s.subnet_name => s
  }
  vpc_id            = aws_vpc.test[each.value.network_name].id
  availability_zone = each.value.subnet_az
  cidr_block        = each.value.subnet_cidr
  tags = merge(each.value.tags,
    {
      Name = each.value.subnet_name
  })
}

一个示例测试输出是:

test                = [
      + {
          + tftest_priv1 = {
              + arn                             = (known after apply)
              + assign_ipv6_address_on_creation = false
              + availability_zone               = "eu-west-1a"
              + availability_zone_id            = (known after apply)
              + cidr_block                      = "10.1.2.0/24"
              + id                              = (known after apply)
              + ipv6_cidr_block                 = (known after apply)
              + ipv6_cidr_block_association_id  = (known after apply)
              + map_public_ip_on_launch         = false
              + owner_id                        = (known after apply)
              + tags                            = {
                  + "Name"    = "tftest_priv1"
                  + "cost"    = "shared"
                  + "service" = "TEST"
                }
              + timeouts                        = null
              + vpc_id                          = (known after apply)
            }
          + tftest_priv2 = {
              + arn                             = (known after apply)
              + assign_ipv6_address_on_creation = false
              + availability_zone               = "eu-west-1b"
              + availability_zone_id            = (known after apply)
              + cidr_block                      = "10.1.3.0/24"
              + id                              = (known after apply)
              + ipv6_cidr_block                 = (known after apply)
              + ipv6_cidr_block_association_id  = (known after apply)
              + map_public_ip_on_launch         = false
              + owner_id                        = (known after apply)
              + tags                            = {
                  + "Name"    = "tftest_priv2"
                  + "cost"    = "shared"
                  + "service" = "TEST"
                }
              + timeouts                        = null
              + vpc_id                          = (known after apply)
            }
          + tftest_pub1  = {
              + arn                             = (known after apply)
              + assign_ipv6_address_on_creation = false
              + availability_zone               = "eu-west-1a"
              + availability_zone_id            = (known after apply)
              + cidr_block                      = "10.1.0.0/24"
              + id                              = (known after apply)
              + ipv6_cidr_block                 = (known after apply)
              + ipv6_cidr_block_association_id  = (known after apply)
              + map_public_ip_on_launch         = false
              + owner_id                        = (known after apply)
              + tags                            = {
                  + "Name"    = "tftest_pub1"
                  + "cost"    = "shared"
                  + "service" = "TEST"
                }
              + timeouts                        = null
              + vpc_id                          = (known after apply)
            }
          + tftest_pub2  = {
              + arn                             = (known after apply)
              + assign_ipv6_address_on_creation = false
              + availability_zone               = "eu-west-1b"
              + availability_zone_id            = (known after apply)
              + cidr_block                      = "10.1.1.0/24"
              + id                              = (known after apply)
              + ipv6_cidr_block                 = (known after apply)
              + ipv6_cidr_block_association_id  = (known after apply)
              + map_public_ip_on_launch         = false
              + owner_id                        = (known after apply)
              + tags                            = {
                  + "Name"    = "tftest_pub2"
                  + "cost"    = "shared"
                  + "service" = "TEST"
                }
              + timeouts                        = null
              + vpc_id                          = (known after apply)
            }
        },
    ]

现在我想使用创建的子网在私有子网中创建 db_subnet_group,例如:

resource "aws_db_subnet_group" "main" {
  name = "${local.prefix}-main"
 subnet_ids = [ 
    aws_subnet.test["tftest_priv1"].id,
    aws_subnet.test["tftest_priv2"].id
  ]
}

但当然不是固定值 :) 我想过使用动态块,但这不起作用:/

resource "aws_db_subnet_group" "main" {
  name = "${local.prefix}-main"
  dynamic "subnet_ids" {
      for_each = {
            for s in local.vpc_subnet_var : s.subnet_az => s... if s.subnet_rttable == "public"
        }
  content {
      subnet_ids = aws_subnet.test[s.subnet_name].id
  }
  }

我可以像在我的输出示例中那样获得所需的 id:

output "test" {
    value = [for s in local.vpc_subnet_var : {
        subnet_ids = aws_subnet.test[s.subnet_name].id
    } if s.subnet_rttable == "default"
    ]
}
------------------------ OUTPUT ------------------------
  + test                = [
      + {
          + subnet_ids = (known after apply)
        },
      + {
          + subnet_ids = (known after apply)
        },
    ]

但是我如何只获取 ID 以将其放入 ["priv_subnet_id1", "priv_subnet_id2"] 之类的列表中...使用它,例如在 aws_db_subnet_group 资源中?可能创建另一个本地?

我希望你理解这个问题:D 我现在尝试了很多东西,但没有让它起作用。如果您需要更多输入,请告诉我(这是我在 stackoverflow 上的第一个问题)

谢谢, 丹尼尔

【问题讨论】:

  • 什么是var.vpcsvar.subnets?您能否提供任何适合复制和粘贴的可重现示例?
  • 我在上面的代码中添加了两个变量和子网的创建。这个例子很大,我不确定我是否可以在这里提交完整的项目。
  • 不需要完整的项目。 local.my_azs 是什么?您可以为local.my_azs 提供一些虚拟示例值,以显示其结构。
  • 添加了每个本地 :) 现在它应该是创建子网的工作项目
  • 谢谢。有用。在尝试找到问题的解决方案时非常有用。

标签: terraform terraform-provider-aws


【解决方案1】:

根据可用的数据,我认为(假设我没有误解问题)您非常接近。

我没有aws_subnet.test,因此我无法完全重现也无法验证结果,但我认为以下应该会生成子网 ID 列表。我设置了一个private_subnets_list 局部变量:

locals {

  private_subnets_list = [
      for s in local.vpc_subnet_var:
        aws_subnet.test[s.subnet_name].id if s.subnet_rttable == "default"]

}

以上假设aws_subnet.test[s.subnet_name].id 是正确的并且aws_subnet.tests.subnet_name 索引。

然后要创建子网组,可以尝试以下方法:

resource "aws_db_subnet_group" "main" {
  name = "${local.prefix}-main"
  subnet_ids = local.private_subnets_list
}

【讨论】:

  • 谢谢,我刚刚做了几乎相同的 :D,它似乎工作! private_sub_ids = flatten([ for s in local.vpc_subnet_var : { subnet_ids = aws_subnet.test[s.subnet_name].id } if s.subnet_rttable == "default" ]) 和资源 "aws_db_subnet_group" "main" { name = " ${local.prefix}-main" subnet_ids = [for i in local.private_sub_ids: i["subnet_ids"]] }
  • 非常感谢您的快速帮助,我认为它是正确的并且有效!完美
猜你喜欢
  • 1970-01-01
  • 2018-11-06
  • 1970-01-01
  • 2018-12-17
  • 1970-01-01
  • 2017-05-05
  • 2013-10-26
  • 1970-01-01
  • 2019-02-13
相关资源
最近更新 更多