Dictionary 地形多级地图

Dictionary 地形多级地图,dictionary,terraform,multi-level,Dictionary,Terraform,Multi Level,当我尝试使用多层地图(3+层)时,我在“地形图”上遇到了错误,似乎无法指出确切的问题。错误:“给定值对变量“secgroups”无效:元素“bastion”:属性“direction”是必需的。“my variables.tf映射到secgroups.auto.tf时是否正确?”?ports_min和ports_max将是为安全组名称打开的所有端口的列表 版本: 变量.tf secgroups.auto.tfvars(只是一个片段) Main.tf 你的定义有几个问题 假设您的完整secgrou

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

版本: 变量.tf secgroups.auto.tfvars(只是一个片段) Main.tf
你的定义有几个问题

假设您的完整
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\u ip\u prefix
,因为您的对象不一致。但是,由于
入口
出口
tcp
udp
似乎是一致的,因此您可能可以使用以下方法:

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))))
}
更新:测试输出
你的定义有几个问题

假设您的完整
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\u ip\u prefix
,因为您的对象不一致。但是,由于
入口
出口
tcp
udp
似乎是一致的,因此您可能可以使用以下方法:

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))))
}
更新:测试输出
指定
对象
类型时,必须提供由指定名称编写的参数。密钥不能是任何字符串。看起来您真正想要的是
map(map(map(object))
,但也可以很容易地将其重构为展平的
map(object)
。谢谢,马特。我把main.tf文件放平了,我把它贴在上面了。我是否需要更改它或变量.tf定义?我对这一点还不太熟悉,请原谅我的无知。当指定
对象
类型时,必须按照指定的名称提供参数。密钥不能是任何字符串。看起来您真正想要的是
map(map(map(object))
,但也可以很容易地将其重构为展平的
map(object)
。谢谢,马特。我把main.tf文件放平了,我把它贴在上面了。我是否需要更改它或变量.tf定义?我对这一点还不太熟悉,请原谅我的无知。然后我是否可以将模块中的单个值称为:var.secgroups.ssh\u from_bastion.ingres.tcp.ports\u min等,获取该特定值?@7Powell79是的。我用测试输出更新了答案。顺便说一句,如果我的回答有帮助的话,我们将不胜感激。然后我是否可以将模块中的单个值称为:var.secgroups.ssh_from_bastion.ingres.tcp.ports_min等,以获取该特定值?@7Powell79是的。我用测试输出更新了答案。顺便说一句,如果我的回答有帮助的话,我们将不胜感激。
output "test" {
  value = var.secgroups.ssh_from_bastion.ingress.tcp.ports_min
}