Неверный аргумент for_each во время aws_lb_target_group_attachment - PullRequest
0 голосов
/ 20 февраля 2020

У меня есть две target_groups - одна для порта 80 и другая для 443. Также есть два экземпляра в качестве членов (этого NLB), и мне нужно присоединить обе целевые группы к каждому экземпляру. Так вот, как я настроил, чтобы прикрепить:

// Creates the target-group
resource "aws_lb_target_group" "nlb_target_groups" {
  for_each = {
    for lx in var.nlb_listeners : "${lx.protocol}:${lx.target_port}" => lx
  }
  name                 = "${var.vpc_names[var.idx]}-tgr-${each.value.target_port}"
  deregistration_delay = var.deregistration_delay
  port                 = each.value.target_port
  protocol             = each.value.protocol
  vpc_id               = var.vpc_ids[var.idx]
  proxy_protocol_v2    = true

  health_check {
    port                = each.value.health_port
    protocol            = each.value.protocol
    interval            = var.health_check_interval
    healthy_threshold   = var.healthy_threshold
    unhealthy_threshold = var.unhealthy_threshold
  }
}

// Attach the target groups to the instance(s)
resource "aws_lb_target_group_attachment" "tgr_attachment" {
  for_each = {
    for pair in setproduct(keys(aws_lb_target_group.nlb_target_groups), var.nlb_members.ids) : "${pair[0]}:${pair[1]}" => {
      target_group = aws_lb_target_group.nlb_target_groups[pair[0]]
      instance_id  = pair[1]
    }
  }
  target_group_arn = each.value.target_group.arn
  target_id        = each.value.instance_id
  port             = each.value.target_group.port
  #target_id       = [for tid in range(var.inst_count) : data.aws_instances.nlb_insts.ids[tid]]
}

, где var.nlb_listeners определяется следующим образом:

nlb_listeners = [
  {
    protocol    = "TCP"
    target_port = "80"
    health_port = "1936"
  },
  {
    protocol    = "TCP"
    target_port = "443"
    health_port = "1936"
  }
]

и var.elb_members.ids выглядит так:

"ids" = [
    "i-015604f88xxxxxx42",
    "i-0e4defceexxxxxxe5",
  ]

но я получаю Недопустимая ошибка аргумента for_each:

Ошибка: недопустимый аргумент for_each

в строке ../../modules/elb/balencer.tf 46, в ресурсе "aws_lb_target_group_attachment" "tgr_attachment": 46: for_each = {47: для пары в setproduct (ключи (aws_lb_target_group.nlb_target_groups), var.elb_members.ids): "{$ [pair]] 1]} "=> {48:
target_group = aws_lb_target_group.nlb_target_groups [pair [0]] 49:
instance_id = pair [1] 50:} 51:}

« for_each » значение зависит от атрибутов ресурса, которые нельзя определить до применения, поэтому Terraform не может предсказать, сколько экземпляров будет создано. Чтобы обойти это, используйте аргумент -target, чтобы сначала применить только ресурсы, от которых зависит for_each.

Я не могу понять, почему он либо недействителен, либо как for_each не может определить значения. Есть идеи, что я тут делаю не так? Серьезно застрял в середине и был бы очень признателен за любую помощь, чтобы направить меня в правильном направлении.

-S

=== Обновление: 02/23 ===== =====

@ martin-atkins, я думаю, я понимаю, что вы сказали, но, похоже, выдает мне ту же ошибку даже для уже существующих случаев. В любом случае, это мой aws_instance ресурс:

resource "aws_instance" "inst" {
  count         = var.inst_count
  instance_type = var.inst_type
  depends_on    = [aws_subnet.snets]
  ami           = data.aws_ami.ubuntu.id

  # the VPC subnet
  subnet_id              = element(aws_subnet.snets.*.id, count.index)
  vpc_security_group_ids = [var.sg_default[var.idx], aws_security_group.secg.id]

  user_data = <<-EOF
          #!/bin/bash
          hostnamectl set-hostname ${var.vpc_names[var.idx]}${var.inst_role}0${count.index + 1}

          # Disable apt-daily.service & wait until `apt updated` has been killed
          systemctl stop apt-daily.service && systemctl kill --kill-who=all apt-daily.service
          while ! (systemctl list-units --all apt-daily.service | egrep -q '(dead|failed)')
          do sleep 1; done
  EOF

  # the public SSH key
  key_name = var.key_info

  tags = merge(
    var.common_tags,
    { "Name" = "${var.vpc_names[var.idx]}${var.inst_role}0${count.index + 1}" }
  )
}

Что еще вы можете сделать, чтобы обойти эту проблему?

-S

Ответы [ 2 ]

0 голосов
/ 02 марта 2020

Наконец я решил это. Не уверен, что это лучший способ или нет, но теперь работает для меня без ошибок. По сути, я изменил поиск данных следующим образом:

// List of instance attributes by role
data "aws_instance" "by_role" {
  for_each = {
    for ic in range(var.inst_count): "${var.inst_role}0${ic+1}" => ic
  }
  instance_tags  = {
    Name = "${var.vpc_names[var.idx]}${each.key}"
  }
  instance_id    = aws_instance.inst[substr(each.key,4,2)-1].id
}

и использовал его в for_each следующим образом:

for_each = {
    for pair in setproduct(keys(aws_lb_target_group.nlb_target_groups), keys(aws_instance.by_role)):
    "${pair[0]}:${pair[1]}" => {
      target_group = aws_lb_target_group.nlb_target_groups[pair[0]]
      member_name  = aws_instance.by_role[pair[1]]
    }
  }

Подробности здесь , ответил на мой вопрос на форуме сообщества Terraform, на тот случай, если кто-то столкнулся с той же проблемой, что и я.

-San

0 голосов
/ 22 февраля 2020

Идентификаторы экземпляра EC2 не выделяются до тех пор, пока экземпляр не будет создан, поэтому поставщик AWS не может предварительно рассчитать их на этапе планирования. Из-за этого они не подходят для использования в качестве части ключа for_each карты.

Вместо этого вам нужно будет использовать какой-то другой идентификатор для тех экземпляров, который определяется самой конфигурацией, а не данные, возвращенные поставщиком во время подачи заявки. Вы не поделились конфигурацией для самих экземпляров, поэтому я не могу сделать конкретное предложение c, но если они все являются экземплярами одного и того же ресурса, созданного с помощью count или for_each, тогда обычным выбором является использование индекс каждого экземпляра (для count) или уникальный ключ каждого экземпляра (для for_each), так что элементы этой карты будут добавляться и удаляться в соответствии с самими добавляемыми и удаляемыми экземплярами.

...