gpt4 book ai didi

dictionary - Terraform 多层 map

转载 作者:行者123 更新时间:2023-12-04 15:19:38 25 4
gpt4 key购买 nike

在尝试使用多层 map (3 层以上)时,我在“terraform plan”上遇到错误,似乎无法指出确切的问题。错误:“给定值对变量“secgroups”无效:元素“bastion”:需要属性“direction”。”我的 variables.tf 是否正确映射到 secgroups.auto.tf? ports_min 和 ports_max 将是为安全组名称打开的全部端口列表。

版本:

Terraform v0.13.0
+ provider registry.terraform.io/hashicorp/local v1.4.0
+ provider registry.terraform.io/hashicorp/null v2.1.2
+ provider registry.terraform.io/hashicorp/tls v2.2.0
+ provider registry.terraform.io/terraform-providers/openstack v1.26.0

变量.tf

variable "secgroups" {
type = map(object({
direction = (map(object({
protocols = (map(object({
name = string
description = string
ports_min = list(number)
ports_max = list(number)
remote_ip_prefix = list(string)
remote_group_id = list(string)
security_group_id = list(string)
})))
})))
}))
}

secgroups.auto.tfvars(只是一个片段)

  ssh_from_bastion = {
ingress = {
tcp = {
ports_min = [22]
ports_max = [22]
remote_group_id = ["openstack_networking_secgroup_v2.bastion.id"]
security_group_id = ["openstack_networking_secgroup_v2.bastion.id"]
},
udp = {
ports_min = [0]
ports_max = [0]
remote_group_id = ["openstack_networking_secgroup_v2.bastion.id"]
security_group_id = ["openstack_networking_secgroup_v2.bastion.id"]
}
},
egress = {
tcp = {
ports_min = [0]
ports_max = [0]
remote_ip_prefix = ["0.0.0.0/0"]
security_group_id = ["openstack_networking_secgroup_v2.bastion.id"]
},
udp = {
ports_min = [0]
ports_max = [0]
remote_ip_prefix = ["0.0.0.0/0"]
security_group_id = ["openstack_networking_secgroup_v2.bastion.id"]
}
}
},

主.tf

 locals {
security_groups = flatten({
for secgroup_name,direction in var.secgroups : {
name = each.secgroup_name
description = "Security group for ${each.secgroup_name}"
for protocol,config in each.direction : {
direction = each.direction
protocol = each.protocol
for config_value in config : {
ports_min = each.config_value.ports_min
ports_max = each.config_value.ports_max
remote_ip_prefix = each.config_value.remote_ip_prefix
security_group_id = each.config_value.security_group_id
}
}
}
})
}

最佳答案

您的定义有几个问题。

假设您的完整 secgroups.auto.tfvars 是:

secgroups = {
ssh_from_bastion = {
ingress = {
tcp = {
ports_min = [22]
ports_max = [22]
remote_group_id = ["openstack_networking_secgroup_v2.bastion.id"]
security_group_id = ["openstack_networking_secgroup_v2.bastion.id"]
},
udp = {
ports_min = [0]
ports_max = [0]
remote_group_id = ["openstack_networking_secgroup_v2.bastion.id"]
security_group_id = ["openstack_networking_secgroup_v2.bastion.id"]
}
},
egress = {
tcp = {
ports_min = [0]
ports_max = [0]
remote_ip_prefix = ["0.0.0.0/0"]
security_group_id = ["openstack_networking_secgroup_v2.bastion.id"]
},
udp = {
ports_min = [0]
ports_max = [0]
remote_ip_prefix = ["0.0.0.0/0"]
security_group_id = ["openstack_networking_secgroup_v2.bastion.id"]
}
}
}
}

对应的定义应该是:

variable "secgroups" {
type = map(map(map(object({
ports_min = list(number)
ports_max = list(number)
security_group_id = list(string)
}))))
}

但是上面的内部对象会丢弃所有额外的属性,例如remote_ip_prefix,因为你的对象不一致。但是,由于 ingressegresstcpudp 似乎是一致的,您可能会使用以下内容:

variable "secgroups" {
type = map(object({
ingress = object({tcp = map(any), udp = map(any)})
egress = object({tcp = map(any), udp = map(any)})
}))
}

作为最后一个资源,如果没有什么是一致的,那么你可以使用:

variable "secgroups" {
type = map(map(map(map(any))))
}

更新:测试输出

output "test" {
value = var.secgroups.ssh_from_bastion.ingress.tcp.ports_min
}

关于dictionary - Terraform 多层 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63604408/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com