Terraform 0.12 делает более сильное различие между списком и установленными значениями, чем 0.11, и включает в себя некоторые дополнительные проверки, подобные этой.
В этом конкретном случае concat
завершается неудачей таким образом, потому что объединение требует всеэлементы должны иметь четко определенный порядок, так что результат также может иметь четко определенный порядок.Наборы не упорядочены, поэтому эта проверка установлена, чтобы напомнить вам о необходимости явно выбирать подходящий порядок при преобразовании в список или вообще не преобразовывать в список.
В данном конкретном случаене похоже, что упорядочение особенно важно, поэтому лексического упорядочения, реализованного с помощью sort
, может быть достаточно:
subnet_ids = concat(
sort(data.aws_subnet_ids.private.ids),
sort(data.aws_subnet_ids.public.ids),
)
(потому что преобразование из списка набора строк всписок строк также накладывает лексическое упорядочение, это функционально эквивалентно tolist
для наборов строк. Я обычно предпочитаю sort
здесь, потому что это подсказка будущему читателю, что результат будет в лексическом порядке.)
Другой вариант - сказать в мире множеств и использовать вместо него setunion
:
subnet_ids = setunion(
data.aws_subnet_ids.private.ids,
data.aws_subnet_ids.public.ids,
)
, так как между этими двумя списками не должно быть дубликатовна самом деле не имеет значения, какой подход вы используете здесь, но для полноты отметим, что в случае, если оба этих набора содержали один и тот же идентификатор подсети, операция setunion
будет дедуплицировать их, потому что каждое уникальное значение может появляться только ноль или один раз в наборе.
В то время, когда я пишу это, где count
по-прежнему является основным способом создания одного экземпляра ресурса вэлемент в коллекции, преобразование в список , в конечном итоге обычно требуется, чтобы отдельные экземпляры могли иметь требуемый порядок. Как только for_each
будет реализован , будет преимущество в использовании наборов, а не списков в ситуациях, подобных этой:
resource "aws_instance" "per_subnet_example" {
# resource-level for_each is not implemented at the time of writing,
# but planned for a future release.
for_each = setunion(
data.aws_subnet_ids.private.ids,
data.aws_subnet_ids.public.ids,
)
# ...
}
При использовании for_each
над набором вместо count
, Terraform будет идентифицировать каждый экземпляр по значению из набора, а не по последовательным индексам, поэтому один экземпляр из этого ресурса может иметь адрес aws_instance.per_subnet_example["subnet-abc123"]
, и это означает, что при добавлении и удалении элементов из этого набора Terraform может просто создать/ уничтожить соответствующий отдельный экземпляр, а не создавать заново все после изменения в упорядоченной последовательности.
Поставщики Terraform используют подобные наборы в тех местах, где это имеет смысл, чтобы упростить использование этого шаблона for_each
.как только он прибудет, но, к сожалению, это означает, что нам нужно в то же время написать несколько явных преобразований типов, чтобы было ясно, что мы работаем с этими значениями в виде последовательности, а не в виде набора.