有人可以帮我解决这个问题吗?我正在使用Terraform 12.28。
我有两张看起来像这样的地图:
instances = {
"instance1" = "us-east-1a"
"instance2" = "us-east-1a"
"instance3" = "us-east-1c"
"instance4" = "us-east-1b"
"instance5" = "us-east-1b"
"instance6" = "us-east-1c"
}
snapshots = {
"snap1" = "us-east-1c"
"snap2" = "us-east-1b"
"snap3" = "us-east-1b"
"snap4" = "us-east-1c"
"snap5" = "us-east-1a"
"snap6" = "us-east-1a"
}
我想从中得到的是:
desired_result = {
"instance1" = "snap5"
"instance2" = "snap6"
"instnace3" = "snap1"
"instance4" = "snap2"
"instance5" = "snap3"
"instance6" = "snap4"
}
我只需要确保实例具有来自同一Az的快照即可。任何想法将不胜感激!
答案 0 :(得分:0)
您描述的结果是不可能的,因为您的查找值重叠。 Instance1
和instance2
都可能导致snap5
或snap6
,因为它们都位于us-east-1a
中。其他可用区也是如此。获得实际结果的一种方法是反转列表之一并将值分组。之后,您可以使用该列表在另一个列表中查找相应的值。这是我的示例:
locals {
instances = {
"instance1" = "us-east-1a"
"instance2" = "us-east-1a"
"instance3" = "us-east-1c"
"instance4" = "us-east-1b"
"instance5" = "us-east-1b"
"instance6" = "us-east-1c"
}
snapshots = {
"snap1" = "us-east-1c"
"snap2" = "us-east-1b"
"snap3" = "us-east-1b"
"snap4" = "us-east-1c"
"snap5" = "us-east-1a"
"snap6" = "us-east-1a"
}
# Reverse and group (...)
reversed_snapshots = {
for key, value in local.snapshots:
value => key...
}
}
output "result" {
value = {
for key, value in local.instances:
# Match instance to snapshots by looking up az
key => lookup(local.reversed_snapshots, value, null)
}
}
结果与原始问题中的结果有些不同,因为每个实例基本上都可以具有位于同一AZ中的两个快照之一。公用标识符AZ具有重复的值,因此也许您可以找到另一个唯一的标识符,例如snapshotID或类似名称。或者,将两个快照与一个实例相关联不是一个问题。
result = {
"instance1" = [
"snap5",
"snap6",
]
"instance2" = [
"snap5",
"snap6",
]
"instance3" = [
"snap1",
"snap4",
]
"instance4" = [
"snap2",
"snap3",
]
"instance5" = [
"snap2",
"snap3",
]
"instance6" = [
"snap1",
"snap4",
]
}
答案 1 :(得分:0)
您可能会说,我正在尝试将卷映射到灾难恢复terraform脚本的同一Availability_zone中的实例。原始(灾难前)群集在3个可用区之间分布了相等数量的实例。在发生灾难的情况下,我需要在相同数量的可用区中还原群集,以将节点保留为可用区组组合。
我不确定这是否是解决此问题的最干净的方法,但这就是我最终要做的事情。如果有人有更好/更干净的方法,我仍然可以提出建议,但我很高兴至少现在可以这样做。
首先,我最终根据像这样的可用区创建了字符串映射图元组:
instance_az = [
flatten([for instance in aws_instance.cassandra:
map(
instance.availability_zone,
zipmap(
matchkeys(
tolist(aws_instance.cassandra.*.id),
tolist(aws_instance.cassandra.*.availability_zone),
[instance.availability_zone]
),
matchkeys(
tolist(aws_ebs_volume.data.*.id),
tolist(aws_ebs_volume.data.*.availability_zone),
[instance.availability_zone]
)
)
)
])
]
示例输出:
instance_az = [
[
{
"us-east-1c" = {
"i-0a18b339d3f1ddd80" = "vol-0ace4794f40c256ed"
"i-0bd9681b1b856c3db" = "vol-00f694635ef7b0904"
}
},
{
"us-east-1a" = {
"i-033c004ed25dbd907" = "vol-0a31e52f2e11dfdef"
"i-0ed01a562756800e9" = "vol-0a20cabb0ae568084"
}
},
{
"us-east-1b" = {
"i-0400baef538ea327a" = "vol-060aff04e902f7005"
"i-08ed6b26743a2bd95" = "vol-06917d88b07bd5d5c"
}
},
{
"us-east-1c" = {
"i-0a18b339d3f1ddd80" = "vol-0ace4794f40c256ed"
"i-0bd9681b1b856c3db" = "vol-00f694635ef7b0904"
}
},
{
"us-east-1a" = {
"i-033c004ed25dbd907" = "vol-0a31e52f2e11dfdef"
"i-0ed01a562756800e9" = "vol-0a20cabb0ae568084"
}
},
{
"us-east-1b" = {
"i-0400baef538ea327a" = "vol-060aff04e902f7005"
"i-08ed6b26743a2bd95" = "vol-06917d88b07bd5d5c"
}
},
],
]
该输出的问题是,每个可用区都被列出两次,且具有完全相同的instanceId-> volumeId映射。接下来,我想删除重复项,因此我将其转换为这样的集合:
inst_vol_to_set = {
s = toset(local.instance_az[0])
}
现在我的输出如下:
inst_vol_to_set = {
"s" = [
{
"us-east-1a" = {
"i-033c004ed25dbd907" = "vol-0a31e52f2e11dfdef"
"i-0ed01a562756800e9" = "vol-0a20cabb0ae568084"
}
},
{
"us-east-1b" = {
"i-0400baef538ea327a" = "vol-060aff04e902f7005"
"i-08ed6b26743a2bd95" = "vol-06917d88b07bd5d5c"
}
},
{
"us-east-1c" = {
"i-0a18b339d3f1ddd80" = "vol-0ace4794f40c256ed"
"i-0bd9681b1b856c3db" = "vol-00f694635ef7b0904"
}
},
]
}
确定看起来更像我想要完成的目标。现在,我只需要将其转换为instanceId-> VolumeId的映射即可:
inst_vol = [
flatten([for s in lookup(local.inst_vol_to_set, "s"): [
for key in keys(s): [
for idx, v in keys(s[key]): {
"${v}" = lookup(s[key], v)
}
]
]])
]
现在看起来好多了,但仍然是地图的元组:
inst_vol = [
[
{
"i-033c004ed25dbd907" = "vol-0a31e52f2e11dfdef"
},
{
"i-0ed01a562756800e9" = "vol-0a20cabb0ae568084"
},
{
"i-0400baef538ea327a" = "vol-060aff04e902f7005"
},
{
"i-08ed6b26743a2bd95" = "vol-06917d88b07bd5d5c"
},
{
"i-0a18b339d3f1ddd80" = "vol-0ace4794f40c256ed"
},
{
"i-0bd9681b1b856c3db" = "vol-00f694635ef7b0904"
},
],
]
最后要做的是将结果展平,以便我可以查找instance_id并使其返回volume_id:
instance_to_volume_map = merge(flatten(local.inst_vol)...)
现在这正是我想要的:
instance_to_volume_map = {
"i-033c004ed25dbd907" = "vol-0a31e52f2e11dfdef"
"i-0400baef538ea327a" = "vol-060aff04e902f7005"
"i-08ed6b26743a2bd95" = "vol-06917d88b07bd5d5c"
"i-0a18b339d3f1ddd80" = "vol-0ace4794f40c256ed"
"i-0bd9681b1b856c3db" = "vol-00f694635ef7b0904"
"i-0ed01a562756800e9" = "vol-0a20cabb0ae568084"
}