gpt4 book ai didi

azure - Terraform:具有多个条件内容的动态 block

转载 作者:行者123 更新时间:2023-12-03 06:12:06 25 4
gpt4 key购买 nike

我正在尝试使用动态 block 为 azure cdn frontdoor 规则创建一个模块:

最初,模块是这样的:

resource "azurerm_cdn_frontdoor_rule" "main" {
name = var.cdn_frontdoor_rule_name
cdn_frontdoor_rule_set_id = var.cdn_frontdoor_rule_set_id
order = var.cdn_frontdoor_rule_order
behavior_on_match = var.cdn_frontdoor_rule_behavior_on_match

dynamic "conditions" {
for_each = var.conditions_settings
content {
host_name_condition {
operator = conditions.value["host_name_operator"]
negate_condition = conditions.value["host_name_negate_condition"]
match_values = conditions.value["host_name_match_values"]
transforms = conditions.value["host_name_transforms"]
}
}
}
}

但现在我想添加其他内容:

resource "azurerm_cdn_frontdoor_rule" "main" {
name = var.cdn_frontdoor_rule_name
cdn_frontdoor_rule_set_id = var.cdn_frontdoor_rule_set_id
order = var.cdn_frontdoor_rule_order
behavior_on_match = var.cdn_frontdoor_rule_behavior_on_match

dynamic "conditions" {
for_each = var.conditions_settings
content {
host_name_condition {
operator = conditions.value["host_name_operator"]
negate_condition = conditions.value["host_name_negate_condition"]
match_values = conditions.value["host_name_match_values"]
transforms = conditions.value["host_name_transforms"]
}
is_device_condition {
operator = conditions.value["is_device_operator"]
negate_condition = conditions.value["is_device_negate_condition"]
match_values = conditions.value["is_device_match_values"]
}
post_args_condition {
post_args_name = conditions.value["post_args_name"]
operator = conditions.value["post_args_operator"]
match_values = conditions.value["post_args_match_values"]
transforms = conditions.value["post_args_transforms"]
}
}
}
}

但是当我运行这个时,我收到以下错误:


│ Error: Missing required argument

│ with module.cdn_frontdoor_rule_set_spa_rule_1.azurerm_cdn_frontdoor_rule.main,
│ on ../../../modules/azure/cdn-frontdoor-rule/main.tf line 1, in resource "azurerm_cdn_frontdoor_rule" "main":
│ 1: resource "azurerm_cdn_frontdoor_rule" "main" {

│ The argument "conditions.0.post_args_condition.0.post_args_name" is required, but no definition was found.


│ Error: Missing required argument

│ with module.cdn_frontdoor_rule_set_spa_rule_1.azurerm_cdn_frontdoor_rule.main,
│ on ../../../modules/azure/cdn-frontdoor-rule/main.tf line 1, in resource "azurerm_cdn_frontdoor_rule" "main":
│ 1: resource "azurerm_cdn_frontdoor_rule" "main" {

│ The argument "conditions.0.post_args_condition.0.operator" is required, but no definition was found.


│ Error: Missing required argument

│ with module.cdn_frontdoor_rule_set_spa_rule_1.azurerm_cdn_frontdoor_rule.main,
│ on ../../../modules/azure/cdn-frontdoor-rule/main.tf line 1, in resource "azurerm_cdn_frontdoor_rule" "main":
│ 1: resource "azurerm_cdn_frontdoor_rule" "main" {

│ The argument "conditions.0.url_filename_condition.0.operator" is required, but no definition was found.

我也尝试过这个:

resource "azurerm_cdn_frontdoor_rule" "main" {
name = var.cdn_frontdoor_rule_name
cdn_frontdoor_rule_set_id = var.cdn_frontdoor_rule_set_id
order = var.cdn_frontdoor_rule_order
behavior_on_match = var.cdn_frontdoor_rule_behavior_on_match

dynamic "conditions" {
for_each = var.conditions_settings
content {
host_name_condition {
operator = conditions.value["host_name_operator"]
negate_condition = conditions.value["host_name_negate_condition"]
match_values = conditions.value["host_name_match_values"]
transforms = conditions.value["host_name_transforms"]
}
}
content {
is_device_condition {
operator = conditions.value["is_device_operator"]
negate_condition = conditions.value["is_device_negate_condition"]
match_values = conditions.value["is_device_match_values"]
}
}
content {
post_args_condition {
post_args_name = conditions.value["post_args_name"]
operator = conditions.value["post_args_operator"]
match_values = conditions.value["post_args_match_values"]
transforms = conditions.value["post_args_transforms"]
}
}
}
}

但我也收到以下错误:

│ Error: Extraneous dynamic content block

│ on ../../../modules/azure/cdn-frontdoor-rule/main.tf line 50, in resource "azurerm_cdn_frontdoor_rule" "main":
│ 50: content {

│ Only one nested content block is allowed for each dynamic block.

如何修复动态 block 内容,使其具有条件性,从而允许有条件地选择内容?

最佳答案

来自引用the documentation for this resource type似乎可以在 conditions block 中使用条件类型 block 的任意组合,但如果您包含任何特定的 block 类型,则必须在其中填充某些参数。

考虑到该结构,我建议使用嵌套结构,其中输入变量反射(reflect)与资源类型的配置架构使用的类似层次结构:

variable "conditions" {
type = object({
host_name = optional(set(object({
operator = string
match_values = optional(list(string))
transforms = optional(list(string))
negate_condition = optional(bool)
})), [])
is_device = optional(set(object({
operator = string
match_values = optional(list(string))
negate_condition = optional(bool)
})), [])
})
default = {}
}

上面的声明要求一个对象类型,每个条件类型都有一个属性,所有这些都是可选的。如果未设置,Terraform 将使用空集作为其默认值。整个变量的默认值是一个具有所有属性默认值的对象,因此默认情况下它们都是空集。

从资源类型文档中并不清楚内部根本没有嵌套 block 的 condition block 是否有效。以防万一,您可以导出所有类型的所有条件的总数,用作是否包含 conditions block 的条件:

locals {
total_conditions_count = sum([
for s in var.conditions : length(s)
]...)
}

这使用 sumfor expression首先计算每个集合中元素的数量,然后将所有这些元素加在一起以找到总数。因此,如果 var.conditions 中没有指定条件,则该值将为零。

有了这些支持声明,您就可以声明资源本身:

resource "azurerm_cdn_frontdoor_rule" "main" {
name = var.cdn_frontdoor_rule_name
cdn_frontdoor_rule_set_id = var.cdn_frontdoor_rule_set_id
order = var.cdn_frontdoor_rule_order
behavior_on_match = var.cdn_frontdoor_rule_behavior_on_match

dynamic "conditions" {
for_each = local.total_conditions_count > 0 ? [var.conditions] : []
content {
dynamic "host_name_condition" {
for_each = conditions.value.host_name
content {
operator = host_name_condition.value.operator
negate_condition = host_name_condition.value.negate_condition
match_values = host_name_condition.value.match_values
transforms = host_name_condition.value.transforms
}
}
dynamic "is_device_condition" {
for_each = conditions.value.is_device
content {
operator = is_device_condition.value.operator
negate_condition = is_device_condition.value.negate_condition
match_values = is_device_condition.value.match_values
}
}
}
}
}

现在使用两级动态 block 。 动态“conditions” block 声明,如果 var.conditions 中至少给出了一个条件,则应该只有一个 conditions block 。如果该条件通过,则每个嵌套动态 block 都会生成每个受支持条件类型的零个或多个 block 。重要的是,如果没有特定类型的条件,那么它将生成零个该类型的 block ,从而避免在存在 block 后需要某些参数时遇到的错误。

调用此模块时,您的用户会将条件指定为嵌套数据结构。例如:

module "example" {
source = "../example"

conditions = {
host_name = [
{
operator = "Equal"
match_values = [
"www.contoso.com",
"images.contoso.com",
"video.contoso.com",
]
transforms = ["Lowercase", "Trim"]
},
]
is_device = [
{
operator = "Equal"
match_values = ["Mobile"]
},
]
}
}

这种嵌套结构的主要优点是变量的类型约束反射(reflect)了与底层资源类型相同的必需和可选参数,因此类型约束确保用户输入始终对资源类型有效,包括生成如果有人在调用模块时定义条件时忘记设置运算符,则会出现与您在模块内部看到的类似错误。

关于azure - Terraform:具有多个条件内容的动态 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76646738/

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