Получение блока CIDR из набора подсетей - PullRequest
0 голосов
/ 14 апреля 2020

Я пытаюсь получить блок 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:

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

Спасибо всем, кто может помочь!

Ответы [ 2 ]

0 голосов
/ 14 апреля 2020

Я думаю, что проблема здесь в том, что аргумент for_each заставляет data.aws_subnet.target отображаться в качестве значения карты, а оператор splat .* определяется как неактивный, если он применяется к чему-либо, кроме списка или установить. Поэтому для вычисления выражения здесь предпринимаются следующие шаги:

  • Сначала оцените data.aws_subnet.target, создавая карту объектов, ключами которых являются строки из var.subnet_ids, которые предположительно выглядят как subnet-12345.
  • Затем примените .* к этой карте. Потому что это карта, которая снова дает тот же результат.
  • Затем примените .cidr_block к этой карте, которая не работает, потому что ее ключами являются идентификаторы su bnet, а не атрибуты объектов su bnet .

Чтобы получить желаемый результат, мы можем использовать values, чтобы игнорировать ключи и взять значения из карты в виде списка:

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

Поскольку результат из values(...) - это список, оператор .* будет вести себя как положено и попытаться найти атрибут cidr_block в каждом из элементов списка.

Другой вариант - использовать for выражение , которое является обобщением синтаксиса splat, который работает для любого значения типа коллекции:

cidr_blocks = [for s in data.aws_subnet.target : s.cidr_block]
0 голосов
/ 14 апреля 2020

Вы должны использовать выражение 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}"
  }
}
...