我想要比较两个地图(对象),然后将比较结果返回到存储在我的 terraform 模块中的局部变量中的值。
{
"boot_volume_name": {
"id": "some id",
"size": "100GB"
},
"block_volume_name": {
"id": "some id",
"size": "300GB"
},
"block_volume_name2": {
"id": "some id",
"size": "1000GB"
}
}
{
"boot_volume_name": {
"id": "some id",
"size": "100GB"
},
"block_volume_name": {
"id": "some id",
"size": "400GB"
},
"block_volume_name2": {
"id": "some id",
"size": "1000GB"
}
}
在此示例中,第一个 JSON 映射(对象)是根据远程状态中找到的内容创建的。第二个是根据使用 auto.tfvars 文件中定义的给定变量找到的内容创建的。我想要处理此信息的是返回一个值,我可以将其与 terraform 资源一起使用,以根据此信息运行或不运行。其真正原因是基于云提供商的问题以及他们无法使用其正常资源 terraform 提供商禁用驱动器扩展的复制。理想情况下,它的工作方式看起来像这样(可能不准确,这正是我此刻的想法:
locals {
volumes = {
map of volumes generated from the auto.tfvars file
}
volumes_from_state = {
map of volumes generated from the state outputs
}
variables_with_comparison = {
logic that I'm trying to figure out, which effectively contains a key, value of the first block volume
}
volumes_with_changes = [
{ for key, value in local.volumes : key => value if contains(local.varaibles_with_comparision, key) }
]
volumes_no_changes = [
{ for key, value in local.volumes : key => value if !contains(local.varaibles_with_comparision, key) }
]
}
resource "null_resource" "disable_replication" {
for_each = local.volumes_with_changes
provisioner "local-exec" {
command = "command to run api update of volume group to disable replication for each.value.id"
}
}
resource "null_resource" "disable_replication" {
for_each = "local.volumes_no_changes
provisioner "local-exec" {
command = "command to run api update of volume group to enable replication for this volume"
}
}
正如你所看到的,我在概念上已经考虑了这一点......但我不太确定等式的比较部分。对此的任何帮助将不胜感激。
另外,相信我,我宁愿只使用提供卷的 terraform 资源来处理更改,因为这将是最理想的情况......但是,由于云提供商,我们陷入了困境......
需要注意的是,我们使用的是 Terraform 版本 1.1.7,因此任何涉及比该版本更新的功能的内容都无法在我们的环境中工作。
我不明白你到底需要什么样的比较:
我创建了一个示例 PoC,希望可以帮助您。我假设两个地图都有相同的键:
locals {
volumes = {
"boot_volume_name" : {
"id" : "a",
"size" : "100GB"
},
"block_volume_name" : {
"id" : "b",
"size" : "300GB"
},
"block_volume_name2" : {
"id" : "c",
"size" : "1000GB"
}
}
volumes_from_state = {
"boot_volume_name" : {
"id" : "a",
"size" : "100GB"
},
"block_volume_name" : {
"id" : "b",
"size" : "400GB"
},
"block_volume_name2" : {
"id" : "c",
"size" : "1000GB"
}
}
changed_volumes = {
for key, value in local.volumes : key => {
for k, v in value : k => v
}
if value != local.volumes_from_state[key]
}
are_maps_equal = length(local.volumes) == 0
}
output "changed_volumes" {
value = local.changed_volumes
description = "A map containing the volumes that have changed"
}
output "are_maps_equal" {
value = local.are_maps_equal
description = "A boolean value indicating whether the two maps are equal or not"
}
运行
terraform apply ...
命令:
Changes to Outputs:
+ are_maps_equal = false
+ changed_volumes = {
+ block_volume_name = {
+ id = "b"
+ size = "300GB"
}
}
You can apply this plan to save these new output values to the Terraform
state, without changing any real infrastructure.
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
are_maps_equal = false
changed_volumes = {
"block_volume_name" = {
"id" = "b"
"size" = "300GB"
}
}
请注意,我使用了 Terraform v1.7,但希望代码与旧版本(包括 v1.1)兼容。