Первоначальная проблема с этим требованием состоит в том, что он требует наличия одного динамического списка c сред, но нескольких отдельных выходных значений. Для того, чтобы эта работа работала, вам нужно либо сделать входные данные среды отдельными значениями, либо создать одно выходное значение, описывающее среды.
# Variant with a fixed set of environments (v0.11 syntax)
variable "production_environment_name" {
type = "string"
default = "production"
}
variable "non_production_environment_name" {
type = "string"
default = "non-production"
}
resource "aws_iam_group" "production_access" {
name = "access-${var.production_environment_name}"
}
resource "aws_iam_group" "non_production_access" {
name = "access-${var.non_production_environment_name}"
}
output "access_production" {
value = "aws_iam_group.production_access.arn"
}
output "access_non_production" {
value = "aws_iam_group.non_production_access.arn"
}
# Variant with dynamic set of environments (v0.11 syntax)
variable "environments" {
type = "list"
default = ["production", "non_production"]
}
resource "aws_iam_group" "access" {
count = "${length(var.environments)}"
name = "access-${var.environments[count.index]}"
}
output "access" {
value = "${aws_iam_group.access.*.arn}"
}
Ключом здесь является то, что входная переменная и выходное значение должно иметь ту же форму, чтобы мы могли сделать все необходимые ссылки между объектами. Во втором примере имена среды предоставляются в виде списка, а групповые ARN также предоставляются в виде списка, так что индексы соответствуют между ними.
Вы также можете использовать вариант output "access"
Выражение для объединения двух с zipmap
и получения карты с именами окружения, что, вероятно, будет более удобным для вызывающей стороны:
output "access" {
value = "${zipmap(var.environments, aws_iam_group.access.*.arn)}"
}
Новые функции в Terraform 0.12 позволяют немного убрать это. Вот идиоматический c Terraform, эквивалентный версии 0.12 версии, которая в результате создает карту:
# Variant with dynamic set of environments (v0.12 syntax)
variable "environments" {
type = set(string)
default = ["production", "non_production"]
}
resource "aws_iam_group" "access" {
for_each = var.environments
name = "access-${each.key}"
}
output "access" {
value = { for env, group in aws_iam_group.access : env => group.arn }
}
Помимо некоторых немного отличающихся синтаксических шаблонов, этот пример 0,12 имеет дополнительное практическое преимущество: Terraform будет отслеживать эти группы IAM с адресами, такими как aws_iam_group.access["production"]
и aws_iam_group.access["non_production"]
, поэтому позиции имен среды в списке var.environments
не важны, и можно добавлять и удалять среды, не мешая группам из других сред из-за перенумерация элементов списка.
Это достигается за счет использования resource for_each
, в результате чего aws_iam_group.access
отображается как карта объектов, в которых имена среды являются ключами, тогда как count
делает это список объектов.