【问题标题】:Obtain value from a local list从本地列表中获取值
【发布时间】:2021-08-06 13:16:06
【问题描述】:

我正在尝试使用 terraform 标记 docker swarm 实例 我将变量和局部变量定义为 variables.tf

variable "instance_count" {
  default = "3"
}
variable "instance_type" {
  default = "t2.micro"
}
variable "aws_region" {
  default = "us-east-1"
}
variable "ami" {
  default = "ami-09e67e426f25ce0d7"
}
variable "host_name" {
  type    = map(number)
  default = {
    "Manager" = 1
    "Worker" = 2
  }
}

当我引用此列表的每个值以将其作为标签分配给 ec2 实例时,如下所示 ec2instance.tf

resource "aws_instance" "swarm_instance" {
  count           = var.instance_count
  ami             = var.ami
  instance_type   = var.instance_type
  key_name        = aws_key_pair.dockerswarm.key_name

  tags = {
    Name = "Swarm_Instance-${count.index + 1}"
  }
   tags = {
    Name = "${local.expanded_names}"
  }
locals {
  expanded_names = {
    for name, count in var.host_name : name => [
      for i in range(count) : format("%s-%02d", name, i+1)
    ]
  }
}

Terraform 抱怨 local.expanded_names is object with 2 attributes 我尝试使用${local.expanded_names.value},但后来它抱怨 object does not have an attribute named "value"。 那么当 terraform 中 value 属性不可用时如何从列表中检索值。

【问题讨论】:

  • 你如何迭代 expanded_names 本地?理想情况下,您的问题应该形成一个minimal reproducible example,这样更容易理解如何重现您的特定问题并指出您可能犯了错误的地方。
  • 您使用tags的完整代码是什么?
  • 我已经按照 cmets 更新了上面的代码。我想获取本地扩展名的值。

标签: terraform terraform-provider-aws


【解决方案1】:

标签应该是字符串,在您的情况下,我会使用jsonencode 从您正在构建的对象中获取字符串,请参阅下面的示例代码

variable "host_name" {
  type    = map(number)
  default = {
    "Manager" = 1
    "Worker" = 2
  }
}

locals {
  expanded_names = jsonencode({
    for name, count in var.host_name : name => [
      for i in range(count) : format("%s-%02d", name, i+1)
    ]
  })
}

provider "aws" {
  region = "us-east-1"
}

resource "aws_instance" "instance" {
  ami           = "ami-1c761163"
  instance_type = "r5.large"

  tags = {
    Terraformed = "true"
    Name        = local.expanded_names
  }
}

如果我们对此进行 terraform 计划,我们会得到以下结果:

Terraform will perform the following actions:

  # aws_instance.instance will be created
  + resource "aws_instance" "instance" {
      + ami                                  = "ami-1c761163"
      ...
      + instance_state                       = (known after apply)
      + instance_type                        = "r5.large"
      ...
      + subnet_id                            = (known after apply)
      + tags                                 = {
          + "Name"        = jsonencode(
                {
                  + Manager = [
                      + "Manager-01",
                    ]
                  + Worker  = [
                      + "Worker-01",
                      + "Worker-02",
                    ]
                }
            )
          + "Terraformed" = "true"
        }



或者也许您的意思是创建一个名称数组:

  • 经理-01
  • 工人-01
  • 工人-02

然后将其用作实例名称...如果是这种情况,您的扩展名称不应该是对象{},而是数组[],那么我们使用它而不是您的计数,请参见下面的代码示例:

variable "host_name" {
  type    = map(number)
  default = {
    "Manager" = 1
    "Worker" = 2
  }
}

locals {
  expanded_names = flatten([
    for name, count in var.host_name : [
      for i in range(count) : format("%s-%02d", name, i+1)
    ]
  ])
}

provider "aws" {
  region = "us-east-1"
}

resource "aws_instance" "instance" {
  for_each = toset(local.expanded_names)

  ami           = "ami-1c761163"
  instance_type = "r5.large"

  tags = {
    Terraformed = "true"
    Name        = each.value
  }
}

以及关于该输出的 terraform 计划:

Terraform will perform the following actions:

  # aws_instance.instance["Manager-01"] will be created
  + resource "aws_instance" "instance" {
      + ami                                  = "ami-1c761163"
      ...
      + tags                                 = {
          + "Name"        = "Manager-01"
          + "Terraformed" = "true"
        }
      ...
    }

  # aws_instance.instance["Worker-01"] will be created
  + resource "aws_instance" "instance" {
      + ami                                  = "ami-1c761163"
      ...
      + tags                                 = {
          + "Name"        = "Worker-01"
          + "Terraformed" = "true"
        }
      ...
    }

  # aws_instance.instance["Worker-02"] will be created
  + resource "aws_instance" "instance" {
      + ami                                  = "ami-1c761163"
      ...
      + tags                                 = {
          + "Name"        = "Worker-02"
          + "Terraformed" = "true"
        }
      ...
    }

Plan: 3 to add, 0 to change, 0 to destroy.

【讨论】:

  • 感谢您的回答@helder-sepulveda。我已遵循您的建议,但无法从编码的 json 字符串中检索用作实例标记的值。请看prnt.sc/1325fuw
  • @RaviKumarCH 您的图像看起来不错,您期望的究竟是什么? ...如果我们需要一个字符串并且我们将其编码为 json,那么您的扩展名称就是一个对象
  • @RaviKumarCH 看到我对上面答案的编辑......我想你想要 expand_names 作为一个数组,然后遍历名称
  • 太好了,效果很好..再次感谢@helder-sepulveda
猜你喜欢
  • 2011-05-10
  • 2021-12-16
  • 2017-06-20
  • 2022-08-17
  • 1970-01-01
  • 2023-01-24
  • 2014-08-07
  • 2018-10-27
  • 1970-01-01
相关资源
最近更新 更多