Невозможно создать динамические c выходные данные terraform для использования в terraform_remote_state - PullRequest
0 голосов
/ 23 января 2020

У меня есть следующий кодовый блок для создания различных групп IAM

resource "aws_iam_group" "environment-access" {
  count = "${length(var.environments)}"
  name = "access-${element(var.environments, count.index)}"
}

variable "environments" {
  default = ["production", "non-production"]
  type = "list"
}

Я хочу записать выходные данные созданных групп IAM, чтобы получить ARN каждой группы для использования в качестве данных через terraform_remote_state, где это выглядело бы примерно так:

Outputs:

access-production = arn:aws:iam::XXXXXXX:group/basepath/access-production
access-non-production = arn:aws:iam::XXXXXXX:group/basepath/access-non-production

У меня проблемы с созданием динамических c выходных данных, поскольку я не уверен, как динамически создавать выходные разделы на основе ресурса, первоначально созданного с использованием приведенного ниже кода. выдает ошибку, ссылающуюся на неизвестный ресурс 'aws_iam_group.access-production', на который ссылаются.

output "access-production" {
  value = "${aws_iam_group.access-production.arn}"
}

output "access-non-production" {
  value = "${aws_iam_group.access-non-production.arn}"
}

1 Ответ

0 голосов
/ 24 января 2020

Первоначальная проблема с этим требованием состоит в том, что он требует наличия одного динамического списка 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 делает это список объектов.

...