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 позволяет выполнять циклический перебор списков, множеств и ассоциативных массивов с последующим созданием множественных копий либо всего ресурса, либо вложенного в него блока. Сначала рассмотрим первый вариант. Синтаксис выглядит так: