sha*_*ako 1 foreach if-statement terraform terraform-provider-azure
当我试图让我的 terraform 代码更加动态时,我遇到了问题。请重点关注“vm2”配置。
\n1. 工作场景
\n在我的 locals.tf 中我有:
\n vms_configurations = {\n "vm1" = {\n size = "Standard_E4ds_v5"\n vm_backup_policy_frequency = "Weekly"\n vm_backup_weekly = {\n count = 4\n weekdays = ["Sunday"]\n }\n }\n "vm2" = {\n size = "Standard_DS12_v2"\n vm_backup_policy_frequency = "Daily"\n vm_backup_daily_policy_retention = 7\n vm_backup_weekly = {\n }\n }\n }\nRun Code Online (Sandbox Code Playgroud)\n在我对备份模块的调用中,我有:
\n...\n vm_backup_weekly = each.value["vm_backup_weekly"]\n vm_backup_daily_policy_retention = each.value["vm_backup_policy_frequency"] == "Daily" ? each.value["vm_backup_daily_policy_retention"] : null\n...\nRun Code Online (Sandbox Code Playgroud)\n一切都很好。
\n2. 失败场景
\n但是,如果我尝试从 locals.tf 中的“vm2”配置中删除“vm_backup_weekly”,如下所示:
\n vms_configurations = {\n "vm1" = {\n size = "Standard_E4ds_v5"\n vm_backup_policy_frequency = "Weekly"\n vm_backup_weekly = {\n count = 4\n weekdays = ["Sunday"]\n }\n }\n "vm2" = {\n size = "Standard_DS12_v2"\n vm_backup_policy_frequency = "Daily"\n vm_backup_daily_policy_retention = 7\n }\n }\nRun Code Online (Sandbox Code Playgroud)\n并在我对备份模块的调用中使用条件表达式,如下所示:
\n...\n vm_backup_weekly = each.value["vm_backup_policy_frequency"] == "Weekly" ? each.value["vm_backup_weekly"] : {}\n vm_backup_daily_policy_retention = each.value["vm_backup_policy_frequency"] == "Daily" ? each.value["vm_backup_daily_policy_retention"] : null\n...\nRun Code Online (Sandbox Code Playgroud)\n它失败并显示消息:
\n\xe2\x94\x82 Error: Inconsistent conditional result types\n\xe2\x94\x82\n\xe2\x94\x82 on r-vm.tf line 33, in module "vms":\n\xe2\x94\x82 33: vm_backup_weekly = each.value["vm_backup_policy_frequency"] == "Weekly" ? each.value["vm_backup_weekly"] : {}\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\n\xe2\x94\x82 \xe2\x94\x82 each.value["vm_backup_policy_frequency"] is "Weekly"\n\xe2\x94\x82 \xe2\x94\x82 each.value["vm_backup_weekly"] is object with 2 attributes\n\xe2\x94\x82\n\xe2\x94\x82 The true and false result expressions must have consistent types. The 'true' value includes object attribute "count", which is absent in the 'false'\n\xe2\x94\x82 value.\nRun Code Online (Sandbox Code Playgroud)\n你知道我错过了什么吗?
\nTerraform 对三元运算符非常挑剔,但有一个巧妙的技巧可以使其适用于任意类型:
attribute = [true, "false"][condition ? 0 : 1]
Run Code Online (Sandbox Code Playgroud)
这并没有提高可读性,而是允许任何值,无论 Terraform 认为什么是正确的。
这里的技巧是创建一个混合类型的元组,然后使用三元引用索引。
在你的情况下,这看起来像:
vm_backup_weekly = [each.value["vm_backup_weekly"], {}][each.value["vm_backup_policy_frequency"] == "Weekly" ? 0 : 1]
Run Code Online (Sandbox Code Playgroud)
如前所述,它不是最具可读性的版本,但它消除了几乎所有情况下的痛苦。
根据您继续使用该值的方式,Terraform 可能会再次吹毛求疵。
在Terramate中,我们实现了tm_ternary()函数,因为 HCL 三元并没有解决我们所有的用例,并且还尝试始终评估双方。