【问题标题】:Unable to create dynamic terraform outputs for use in terraform_remote_state无法创建用于 terraform_remote_state 的动态 terraform 输出
【发布时间】:2020-01-24 10:58:51
【问题描述】:

我有以下用于创建各种 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 组的输出,以便通过 terraform_remote_state 获取每个组的 ARN 以用作数据,它看起来如下所示

Outputs:

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

我在创建动态输出时遇到问题,因为我不确定如何根据最初创建的资源动态创建输出节,因为使用以下代码会产生引用未知资源“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}"
}

【问题讨论】:

  • 您使用的是什么版本的 Terraform?
  • 我使用的是 v0.11.13

标签: amazon-web-services terraform


【解决方案1】:

此要求的一个初始问题是它需要一个动态的环境列表,但需要多个单独的输出值。为了完成这项工作,您需要使环境输入单独的值或生成描述环境的单个输出值。

# 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 中的新功能允许对此进行一些整理。这是生成地图的版本的惯用 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 将跟踪地址为 aws_iam_group.access["production"]aws_iam_group.access["non_production"] 的那些 IAM 组,因此环境名称在 @987654331 中的位置@list 并不重要,并且可以添加和删除环境,而不会由于列表元素重新编号而潜在地干扰其他环境中的组。

它通过使用resource for_each 实现这一点,这使得aws_iam_group.access 显示为对象映射,其中环境名称是键,而count 使其成为对象列表。

【讨论】:

  • 所以在 v0.11 中,无法动态管理 100 多个环境,听起来好像需要输出才能用作 terraform_remote_state 中的数据以用于其他资源。
  • 您可以拥有任意数量的环境,只要您使用具有值是列表或地图的单个输出的方法。指定 100 个环境会为您提供一个包含 100 个元素的列表或映射。 Terraform 0.12 只是让你更简洁地表达同样的事情。这里的关键是输出 declarations 的集合是静态的,而不是动态的……不过,单个输出可以是包含任意数量元素的集合。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-08
  • 2021-12-31
  • 1970-01-01
  • 2020-01-22
  • 1970-01-01
  • 2022-07-26
  • 2021-05-25
相关资源
最近更新 更多