Читаем Terraform: инфраструктура на уровне кода полностью

Обратите внимание на то, что у имени "morpheus" теперь индекс 1, а не 2. Terraform воспринимает индекс в качестве идентификатора ресурса, поэтому данное изменение можно перефразировать так: «переименовать элемент с индексом 1 в morpheus и удалить элемент с индексом 2». Иными словами, каждый раз, когда вы удаляете находящийся внутри списка ресурс, Terraform удаляет все ресурсы, которые следуют за ним, и воссоздает их заново, с нуля. Ох. Конечно, итоговым результатом будет именно то, о чем вы просили (то есть два пользователя IAM с именами "morpheus" и "neo"), но вряд ли вам хотелось бы достичь этого за счет удаления и изменения ресурсов.

Чтобы вы могли обойти эти два ограничения, в Terraform 0.12 появились выражения for_each.

Циклы с выражениями for_each

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

resource "_" "" {

  for_each =

   [CONFIG ...]

}

PROVIDER — это имя провайдера (например, aws), TYPE — тип ресурса, который нужно создать в этом провайдере (скажем, instance), NAME — идентификатор, с помощью которого можно ссылаться на ресурс на разных участках кода Terraform (вроде my_instance), COLLECTION — множество или ассоциативный массив, который нужно перебрать в цикле (при использовании for_each в сочетании с ресурсом списки не поддерживаются), а CONFIG состоит из одного или нескольких аргументов, предназначенных специально для этого ресурса. Внутри CONFIG можно применять ссылки each.key и each.value для доступа к ключу и значению текущего элемента COLLECTION.

Например, так можно создать тех же трех пользователей IAM с помощью for_each:

resource "aws_iam_user" "example" {

  for_each = toset(var.user_names)

  name     = each.value

}

Обратите внимание на функцию toset, которая превращает список var.user_names во множество. Дело в том, что выражение for_each поддерживает множества и ассоциативные массивы только для ресурсов. При переборе этого множества оно предоставляет имя каждого пользователя в виде each.value. То же самое значение будет доступно и в each.key, хотя эта ссылка обычно используется только в ассоциативных массивах с ключами и значениями.

Ресурс, к которому применяется for_each, становится ассоциативным массивом ресурсов (а не обычным массивом, как в случае с count). Чтобы это продемонстрировать, заменим оригинальные выходные переменные all_arns и neo_arn новой, all_users:

output "all_users" {

  value = aws_iam_user.example

}

Вот что произойдет, если выполнить terraformapply:

$ terraform apply

(...)

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

Outputs:

all_users = {

  "morpheus" = {

    "arn" = "arn:aws:iam::123456789012:user/morpheus"

    "force_destroy" = false

    "id" = "morpheus"

    "name" = "morpheus"

    "path" = "/"

    "tags" = {}

  }

  "neo" = {

    "arn" = "arn:aws:iam::123456789012:user/neo"

    "force_destroy" = false

    "id" = "neo"

    "name" = "neo"

    "path" = "/"

    "tags" = {}

  }

  "trinity" = {

    "arn" = "arn:aws:iam::123456789012:user/trinity"

    "force_destroy" = false

    "id" = "trinity"

    "name" = "trinity"

    "path" = "/"

    "tags" = {}

  }

}

Как видите, Terraform создает трех пользователей IAM, а выходная переменная all_users содержит ассоциативный массив, ключи которого (в данном случае имена пользователей) используются в for_each, а значения служат выходными переменными этого ресурса. Если хотите вернуть выходную переменную all_arns, нужно приложить дополнительные усилия, чтобы извлечь соответствующие ARN, добавив встроенную функцию values (которая возвращает только значения ассоциативного массива) и символ *:

output "all_arns" {

  value = values(aws_iam_user.example)[*].arn

}

Мы получим нужный нам вывод:

$ terraform apply

(...)

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

all_arns = [

  "arn:aws:iam::123456789012:user/morpheus",

  "arn:aws:iam::123456789012:user/neo",

  "arn:aws:iam::123456789012:user/trinity",

]

Важно, что у вас теперь есть ассоциативный массив ресурсов с for_each вместо обычного массива ресурсов с count, так как теперь вы можете безопасно удалять его элементы. Например, если опять удалить "trinity" из списка var.user_names и выполнить terraformplan, результат будет следующим:

$ terraform plan

Terraform will perform the following actions:

  # aws_iam_user.example["trinity"] will be destroyed

  - resource "aws_iam_user" "example" {

      - arn           = "arn:aws:iam::123456789012:user/trinity" -> null

      - name          = "trinity" -> null

    }

Plan: 0 to add, 0 to change, 1 to destroy.

Вот так-то лучше! Теперь вы удаляете только тот ресурс, который вам нужен, не смещая все вокруг. Вот почему для создания множественных копий ресурса почти всегда следует выбирать for_each вместо count.

Перейти на страницу:

Все книги серии Бестселлеры O'Reilly

Искусство управления IT-проектами
Искусство управления IT-проектами

В отличие от множества трудов, посвященных руководству проектами и командами, в этой книге не проповедуются никакие новые учения и не превозносятся великие теории. Скотт Беркун считает залогом успеха практику и разнообразие подходов. В книге описываются основные сложности и проблемные ситуации, возникающие в работе менеджера проекта, даны рекомендации по выходу из них.Издание предназначено не только для лидеров команд и менеджеров высшего звена, но и для программистов, тестеров и других исполнителей конкретных проектных заданий. Также оно будет полезно студентам, изучающим бизнес-менеджмент, проектирование изделий или программную инженерию.Текст нового издания значительно переработан автором с целью добиться большей ясности, кроме того, книга дополнена новым приложением и более чем 120 практическими упражнениями.

Скотт Беркун

Деловая литература
iOS. Приемы программирования
iOS. Приемы программирования

Книга, которую вы держите в руках, представляет собой новый, полностью переписанный сборник приемов программирования по работе с iOS. Он поможет вам справиться с наболевшими проблемами, с которыми приходится сталкиваться при разработке приложений для iPhone, iPad и iPod Touch. Вы быстро освоите всю информацию, необходимую для начала работы с iOS 7 SDK, в частности познакомитесь с решениями для добавления в ваши приложения реалистичной физики или движений — в этом вам помогут API UIKit Dynamics.Вы изучите новые многочисленные способы хранения и защиты данных, отправки и получения уведомлений, улучшения и анимации графики, управления файлами и каталогами, а также рассмотрите многие другие темы. При описании каждого приема программирования приводятся образцы кода, которые вы можете смело использовать.

Вандад Нахавандипур

Программирование, программы, базы данных / Программирование / Книги по IT

Похожие книги