В главе 2 с помощью консоли AWS вы создали учетную запись AWS и пользователя Access Management (IAM). Теперь с помощью этого пользователя вы можете создавать и администрировать всех будущих пользователей IAM прямо в коде Terraform. Рассмотрим следующий код, который должен находиться в файле live/global/iam/main.tf:
provider "aws" {
region = "us-east-2"
}
resource "aws_iam_user" "example" {
name = "neo"
}
Здесь используется ресурс aws_iam_user для создания одного нового пользователя IAM. Но если необходимо создать трех пользователей? В языке программирования общего назначения вы бы применили цикл for:
# Это просто псевдокод. Он не будет работать в Terraform.
for (i = 0; i < 3; i++) {
resource "aws_iam_user" "example" {
name = "neo"
}
}
В языке Terraform нет встроенной поддержки циклов for и другой традиционной процедурной логики, поэтому такой синтаксис работать не будет. Однако у каждого ресурса Terraform есть метапараметр под названием count. Это самая старая, простая ограниченная разновидность итератора в Terraform: она просто определяет, сколько копий ресурса нужно создать. Вот как с помощью этого параметра создать трех пользователей IAM:
resource "aws_iam_user" "example" {
count = 3
name = "neo"
}
У этого кода есть одна проблема: у всех трех пользователей IAM будет одно и то же имя. Это приведет к ошибке, так как имена пользователей должны быть уникальными. Если бы у вас был доступ к стандартному циклу for, вы могли бы использовать индекс i, чтобы изменить каждое имя:
# Это просто псевдокод. Он не будет работать в Terraform.
for (i = 0; i < 3; i++) {
resource "aws_iam_user" "example" {
name = "neo.${i}"
}
}
Чтобы добиться того же в Terraform и получить индекс каждой итерации в цикле, можно воспользоваться ссылкой count.index:
resource "aws_iam_user" "example" {
count = 3
name = "neo.${count.index}"
}
Если выполнить команду plan для представленного выше кода, можно увидеть, что Terraform собирается создать трех пользователей IAM с разными именами ("neo.0", "neo.1", "neo.2"):
Terraform will perform the following actions:
# aws_iam_user.example[0] will be created
+ resource "aws_iam_user" "example" {
+ arn = (known after apply)
+ force_destroy = false
+ id = (known after apply)
+ name = "neo.0"
+ path = "/"
+ unique_id = (known after apply)
}
# aws_iam_user.example[1] will be created
+ resource "aws_iam_user" "example" {
+ arn = (known after apply)
+ force_destroy = false
+ id = (known after apply)
+ name = "neo.1"
+ path = "/"
+ unique_id = (known after apply)
}
# aws_iam_user.example[2] will be created
+ resource "aws_iam_user" "example" {
+ arn = (known after apply)
+ force_destroy = false
+ id = (known after apply)
+ name = "neo.2"
+ path = "/"
+ unique_id = (known after apply)
}
Plan: 3 to add, 0 to change, 0 to destroy.
Конечно, такое имя, как "neo.0", будет не очень полезным. Но если совместить count.index с некоторыми встроенными в Terraform функциями, каждую итерацию этого цикла можно изменить еще сильнее.
Например, все нужные вам имена пользователей IAM можно перечислить во входной переменной внутри live/global/iam/variables.tf:
variable "user_names" {
description = "Create IAM users with these names"
type = list(string)
default = ["neo", "trinity", "morpheus"]
}
В языке программирования общего назначения с циклами и массивами вы бы назначили каждому пользователю IAM отдельное имя путем поиска значений в массиве var.user_names по индексу i:
# Это просто псевдокод. Он не будет работать в Terraform.
for (i = 0; i < 3; i++) {
resource "aws_iam_user" "example" {
name = vars.user_names[i]
}
}
В Terraform то же самое можно сделать с помощью count в сочетании:
• с
ARRAY[
Например, вот как взять из массива var.user_names элемент с индексом 1:
var.user_names[1]
• с
length(
Как вы уже догадались, функция length возвращает количество элементов в заданном массиве. Она также работает со строками и ассоциативными массивами.
Если все это объединить, получится следующее:
resource "aws_iam_user" "example" {
count = length(var.user_names)
name = var.user_names[count.index]
}
Теперь, если выполнить команду plan, можно увидеть, что Terraform собирается создать трех пользователей IAM с уникальными именами:
Terraform will perform the following actions:
# aws_iam_user.example[0] will be created
+ resource "aws_iam_user" "example" {
+ arn = (known after apply)
+ force_destroy = false
+ id = (known after apply)
+ name = "neo"
+ path = "/"
+ unique_id = (known after apply)
}
# aws_iam_user.example[1] will be created
+ resource "aws_iam_user" "example" {
+ arn = (known after apply)
+ force_destroy = false
+ id = (known after apply)
+ name = "trinity"