Terraform: инфраструктура на уровне кода | страница 103
variable "user_names" {
description = "Create IAM users with these names"
type = list(string)
default = ["neo", "trinity", "morpheus"]
}
Представьте, что вы убрали из этого списка "trinity". Что произойдет при выполнении terraformplan?
$ terraform plan
(...)
Terraform will perform the following actions:
# aws_iam_user.example[1] will be updated in-place
~ resource "aws_iam_user" "example" {
id = "trinity"
~ name = "trinity" -> "morpheus"
}
# aws_iam_user.example[2] will be destroyed
- resource "aws_iam_user" "example" {
- id = "morpheus" -> null
- name = "morpheus" -> null
}
Plan: 0 to add, 1 to change, 1 to destroy.
Постойте, это не совсем то, чего мы ожидали! Вместо простого удаления пользователя IAM "trinity" вывод plan говорит о том, что Terraform собирается переименовать его в "morpheus" и затем удалить оригинального пользователя с этим именем. Что происходит?
Ресурс, в котором указан параметр count, превращается в список или массив ресурсов. К сожалению, Terraform определяет каждый элемент массива по его позиции (индексу). То есть после первого выполнения apply с именами трех пользователей внутреннее представление массива в Terraform выглядит примерно так:
aws_iam_user.example[0]: neo
aws_iam_user.example[1]: trinity
aws_iam_user.example[2]: morpheus
Если удалить элемент посреди массива, все остальные элементы, которые шли за ним, смещаются назад на позицию. Поэтому после выполнения plan с именами двух пользователей внутреннее представление будет таким:
aws_iam_user.example[0]: neo
aws_iam_user.example[1]: morpheus
Обратите внимание на то, что у имени "morpheus" теперь индекс 1, а не 2. Terraform воспринимает индекс в качестве идентификатора ресурса, поэтому данное изменение можно перефразировать так: «переименовать элемент с индексом 1 в morpheus и удалить элемент с индексом 2». Иными словами, каждый раз, когда вы удаляете находящийся внутри списка ресурс, Terraform удаляет все ресурсы, которые следуют за ним, и воссоздает их заново, с нуля. Ох. Конечно, итоговым результатом будет именно то, о чем вы просили (то есть два пользователя IAM с именами "morpheus" и "neo"), но вряд ли вам хотелось бы достичь этого за счет удаления и изменения ресурсов.
Чтобы вы могли обойти эти два ограничения, в Terraform 0.12 появились выражения for_each.
Циклы с выражениями for_each
Выражение for_each позволяет выполнять циклический перебор списков, множеств и ассоциативных массивов с последующим созданием множественных копий либо всего ресурса, либо вложенного в него блока. Сначала рассмотрим первый вариант. Синтаксис выглядит так: