Terraform for_each是从地形集合中检索值的唯一方法吗?
Terraform最近引入了Terraform for_each是从地形集合中检索值的唯一方法吗?,terraform,hcl,Terraform,Hcl,Terraform最近引入了集数据类型,描述如下: set(…):没有任何辅助标识符或顺序的唯一值的集合 很难找到关于如何从地形集合中检索值的文档。使用地图,您可以索引键: password = var.passwords["kevin"] 通过列表,您可以对元素编号进行索引: a_record = var.records[1] 但是,我不能使用这两种方法中的任何一种从集合中检索值,即使是只有一个项的集合 在其他地方,文档提到了将作为从集合中获取值的方法 variable
集
数据类型,描述如下:
set(…)
:没有任何辅助标识符或顺序的唯一值的集合
很难找到关于如何从地形集合中检索值的文档。使用地图,您可以索引键:
password = var.passwords["kevin"]
通过列表,您可以对元素编号进行索引:
a_record = var.records[1]
但是,我不能使用这两种方法中的任何一种从集合中检索值,即使是只有一个项的集合
在其他地方,文档提到了将作为从集合中获取值的方法
variable "subnet_ids" {
type = list(string)
}
resource "aws_instance" "server" {
for_each = toset(var.subnet_ids)
ami = "ami-a1b2c3d4"
instance_type = "t2.micro"
subnet_id = each.key # note: each.key and each.value are the same for a set
tags = {
Name = "Server ${each.key}"
}
}
每个元变量的是否是访问集合中的值的唯一方法?您也可以通过先将集合强制转换为列表,然后作为列表访问来切片集合
例如:
variable "set" {
type = set(string)
default = [
"foo",
"bar",
]
}
output "set" {
value = var.set
}
output "set_first_element" {
value = var.set[0]
}
这将导致错误,因为索引无法直接访问集合:
Error: Invalid index
on main.tf line 14, in output "set_first_element":
14: value = var.set[0]
This value does not have any indices.
如果改为使用强制转换,则可以按预期访问它:
output "set_to_list_first_element" {
value = tolist(var.set)[0]
}
请注意,这将返回bar
,而不是foo
。严格来说,地形中的集合是无序的,因此您根本不能依赖于顺序,并且仅在一次地形运行期间是一致的,但实际上,它们是稳定的,并且在以下情况下:
当集合转换为列表或元组时,元素将以任意顺序排列。如果集合的元素是字符串,它们将按字典顺序排列;其他元素类型的集合不保证元素的任何特定顺序
出现这种情况的主要原因是,如果您处理的资源或数据源返回Terraform 0.12中的集合类型,但需要使用单数值。一个基本的例子可能是这样的:
data "aws_subnet_ids" "private" {
vpc_id = var.vpc_id
tags = {
Tier = "Private"
}
}
resource "aws_instance" "app" {
ami = var.ami
instance_type = "t2.micro"
subnet_id = tolist(data.aws_subnet_ids.example.ids)[0]
}
这将在标记为Tier=Private
的子网中创建一个EC2实例,但不对其位置设置其他约束
当您能够使用为每个
访问值时,您还可以使用以下参数循环一组:
然后输出以下内容:
list_comprehension_over_set = [
"SSH",
"HTTP",
]
set_of_objects = [
{
"port" = 22
"service" = "ssh"
},
{
"port" = 80
"service" = "http"
},
]
你能分享一下你是如何尝试从一个集合中访问元素的,以及你从中得到的错误吗?通常你只是把它放到一个列表中,然后把它切分……这不是我以前见过的,也不是我在Terraform的四年中必须自己做的,所以这个用例和那个评论(希望很快能得到答案)都让我感兴趣。除此之外,我会对这个问题说“是”,除了for_each
不是一个元变量(很抱歉,太迂腐了)。为什么你会说for_each
不是一个元变量?将它列为所有资源可用的元参数之一,尽管它比它更复杂,因为它也出现在dynamic
块中,而其他块则不是(主要是因为dynamic
需要它)。谢谢,这就是我最后要做的。。。它在整个示例中看起来更笨拙,因为它在较大变量的中间调用Telist-(),但它确实是个诀窍。这很有帮助。
variable "set_of_objects" {
type = set(object({
port = number
service = string
}))
default = [
{
port = 22
service = "ssh"
},
{
port = 80
service = "http"
},
]
}
output "set_of_objects" {
value = var.set_of_objects
}
output "list_comprehension_over_set" {
value = [ for obj in var.set_of_objects : upper(obj.service) ]
}
list_comprehension_over_set = [
"SSH",
"HTTP",
]
set_of_objects = [
{
"port" = 22
"service" = "ssh"
},
{
"port" = 80
"service" = "http"
},
]