Terraform: инфраструктура на уровне кода | страница 105



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.

Рассмотрим еще одно преимущество выражения for_each: его способность создавать множественные вложенные блоки внутри ресурса. Например, с его помощью можно динамически сгенерировать вложенные блоки tag для ASG в модуле webserver-cluster. Чтобы пользователь мог указывать собственные теги, добавим в файл modules/services/webserver-cluster/variables.tf новую входную переменную с ассоциативным массивом под названием custom_tags:

variable "custom_tags" {

  description = "Custom tags to set on the Instances in the ASG"

  type        = map(string)

  default     = {}

}

Далее установим некоторые пользовательские теги в промышленной среде в файле live/prod/services/webserver-cluster/main.tf:

module "webserver_cluster" {

  source = "../../../../modules/services/webserver-cluster"

  cluster_name           = "webservers-prod"

  db_remote_state_bucket = "(YOUR_BUCKET_NAME)"

  db_remote_state_key    = "prod/data-stores/mysql/terraform.tfstate"

  instance_type      = "m4.large"

  min_size           = 2

  max_size           = 10

  custom_tags = {

    Owner      = "team-foo"

    DeployedBy = "terraform"

  }

}

В этом листинге устанавливается несколько полезных тегов: Owner определяет, какой команде принадлежит ASG, а DeployedBy сигнализирует, что данная инфраструктура была развернута с помощью Terraform (это говорит о том, что ее не следует редактировать вручную; см. подраздел «Даже хороший план может оказаться неудачным» на с. 207). Обычно имеет смысл выработать систему тегов внутри своей команды и воплотить ее в виде кода с помощью модулей Terraform.