Зависимость группы безопасности Terraform Decouple Security Group

Это проверено с помощью Terraform v0.12.9

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

resource "aws_security_group" "this" {
  count       = var.create ? 1 : 0
  name_prefix = "${var.security_group_name}_"
  vpc_id      = var.vpc_id

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_security_group_rule" "ingress_rules" {
  count                     = var.create ? length(var.inbound_security_group_ids) : 0

  security_group_id         = aws_security_group.this[0].id
  type                      = "ingress"

  from_port                 = var.from_port
  to_port                   = var.to_port
  protocol                  = "tcp"
  source_security_group_id  = var.inbound_security_group_ids[count.index]
}

Реализация для этого будет выглядеть примерно так:

module "test_module" {
  source                     = "../path/to/module/"

  create                     = true
  vpc_id                     = "vpc-xxxxxx"
  security_group_name        = "${var.service_name}-db"
  from_port                  = 1234
  to_port                    = 1234
  inbound_security_group_ids = [
    module.service.security_group_id_one,
    module.service.security_group_id_two
  ]
}

Проблема

Я хочу, чтобы это работало, если выходы из module.service не созданы. В этом сценарии я ожидаю, что length(var.inbound_security_group_ids) будет оцениваться как 0, что приведет к тому, что правила группы безопасности не будут созданы.

На самом деле происходит то, что length(var.inbound_security_group_ids) оценивается как 2, когда module.service не создается. Предположительно, это потому, что это массив из двух пустых строк ["", ""]

Согласно документации Terraform, я могу справиться с этим с помощью функции compact, который удаляет пустые строки из массива.

resource "aws_security_group_rule" "ingress_rules" {
  count                     = var.create ? length(compact(var.inbound_security_group_ids)) : 0

  security_group_id         = aws_security_group.this[0].id
  type                      = "ingress"

  from_port                 = var.from_port
  to_port                   = var.to_port
  protocol                  = "tcp"
  source_security_group_id  = var.inbound_security_group_ids[count.index]
}

Однако проблема заключается в том, что Terraform не может определить plan, потому что не знает, что var.inbound_security_group_ids оценивает до apply-time. Это сообщение об ошибке (для контекста):

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

Вопрос

Можно ли отделить такую ​​группу безопасности, чтобы она все равно создавалась, даже если атрибут source_security_group_id не имеет значений?


person GreenyMcDuff    schedule 29.10.2019    source источник


Ответы (1)


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

В этом случае вы можете подойти к этому, изменив способ возврата идентификаторов групп безопасности из вашего service модуля, чтобы каждый из этих выходных данных представлял собой список идентификаторов групп безопасности, а не одну строку, которая могла бы быть либо действительный идентификатор группы безопасности, либо пустая строка:

module "test_module" {
  source                     = "../path/to/module/"

  create                     = true
  vpc_id                     = "vpc-xxxxxx"
  security_group_name        = "${var.service_name}-db"
  from_port                  = 1234
  to_port                    = 1234
  inbound_security_group_ids = concat(
    module.service.security_group_ids_one,
    module.service.security_group_ids_two,
  )
}

Если известно, что security_group_ids_one или security_group_ids_two является пустым списком, то concat полностью его проигнорирует. Если они включены, вы можете сделать их известным списком с одним элементом, значение которого неизвестно, и, таким образом, length(var.inbound_security_group_ids) по-прежнему будет иметь известное значение во всех случаях.

person Martin Atkins    schedule 29.10.2019