【问题标题】:Getting the CIDR block of a set of subnets获取一组子网的 CIDR 块
【发布时间】:2020-04-15 02:07:11
【问题描述】:

我正在尝试获取一组提供参数的子网 ID 的 CIDR 块。

data "aws_subnet" "target" {
  for_each = "${toset(var.subnet_ids)}"
  id       = "${each.value}"
}

resource "aws_security_group" "registry" {
  vpc_id = "${var.vpc_id}"
  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["${data.aws_subnet.target.*.cidr_block}"]
  }
  tags = {
    Name = "${var.name}"
  }
}

我得到的错误是:

cidr_blocks = "${data.aws_subnet.target.*.cidr_block}"

This object does not have an attribute named "cidr_block".

地形配置:

Terraform v0.12.24
+ provider.aws v2.55.0
+ provider.template v2.1.2

感谢任何可以提供帮助的人!

【问题讨论】:

    标签: terraform terraform-provider-aws


    【解决方案1】:

    您应该对地图的值使用 splat 表达式。

    resource "aws_security_group" "registry" {
      vpc_id = "${var.vpc_id}"
      ingress {
        from_port   = 443
        to_port     = 443
        protocol    = "tcp"
        cidr_blocks = values(data.aws_subnet.target).*.cidr_block
      }
      tags = {
        Name = "${var.name}"
      }
    }
    

    【讨论】:

      【解决方案2】:

      我认为这里的问题是for_each 参数使data.aws_subnet.target 显示为映射值,而 splat 运算符.* 被定义为在应用于除列表以外的任何内容时表现为无操作或设置。因此这里的表达式评估采取以下步骤:

      • 首先评估data.aws_subnet.target,生成一个对象映射,其键是来自var.subnet_ids 的字符串,大概看起来像subnet-12345
      • 然后将.* 应用于该地图。因为它是一张地图,所以会再次产生相同的结果。
      • 然后将.cidr_block 应用于该映射,但由于其键是子网ID,而不是子网对象的属性而失败。

      要在此处获得所需的结果,我们可以使用values 忽略键并将映射中的值作为列表:

      cidr_blocks = values(data.aws_subnet.target).*.cidr_block
      

      因为values(...) 的结果是一个列表,所以.* 运算符将按预期运行,并尝试在列表的每个元素中查找cidr_block 属性。

      另一种选择是使用for expression,它是适用于任何集合类型值的 splat 语法的概括:

      cidr_blocks = [for s in data.aws_subnet.target : s.cidr_block]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-05-22
        • 2018-06-29
        • 1970-01-01
        • 2020-05-10
        • 2021-08-01
        • 2017-08-22
        • 2016-08-25
        • 2017-10-29
        相关资源
        最近更新 更多