从本地列表中获取值
Obtain value from a local list
我正在尝试使用 terraform 标记 docker 群实例
我将变量和局部变量定义为
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 中的值属性不可用时如何从列表中检索值。
标签应该是字符串,在您的情况下,我会使用 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 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"
}
或者您可能想要创建一个名称数组:
- Manager-01
- 工人 01
- 工人 02
然后将其用作实例名称...如果是这种情况,您的 expanded_names 不应该是一个对象 {}
而应该是一个数组 []
,那么我们将使用它来代替您的计数,请参阅下面的代码示例:
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.
我正在尝试使用 terraform 标记 docker 群实例 我将变量和局部变量定义为 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 中的值属性不可用时如何从列表中检索值。
标签应该是字符串,在您的情况下,我会使用 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 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"
}
或者您可能想要创建一个名称数组:
- Manager-01
- 工人 01
- 工人 02
然后将其用作实例名称...如果是这种情况,您的 expanded_names 不应该是一个对象 {}
而应该是一个数组 []
,那么我们将使用它来代替您的计数,请参阅下面的代码示例:
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.