配置azurerm_storage_management_policy模块时Terraform变量报错求助
解决Terraform azurerm_storage_management_policy模块变量配置错误
问题描述
编写azurerm_storage_management_policy的Terraform模块时,已完成资源块和变量定义,但执行terraform plan触发变量错误,需排查配置问题。
main.tf
resource "azurerm_storage_management_policy" "mgmt_policy" { storage_account_id = var.storage_account_id dynamic "rule" { for_each = var.settings.rules content { name = rule.value.name enabled = rule.value.enabled dynamic "filters" { for_each = try(rule.value.filters, {}) content { prefix_match = try(filters.value.prefix_match, null) blob_types = try(filters.value.blob_types, null) dynamic "match_blob_index_tag" { for_each = try(filters.match_blob_index_tag, {}) content { name = try(match_blob_index_tag.value.name, null) operation = try(match_blob_index_tag.value.operation, null) value = try(match_blob_index_tag.value.value, null) } } } } actions { dynamic "base_blob" { for_each = try(rule.value.actions.base_blob, {}) content { tier_to_cool_after_days_since_modification_greater_than = try(base_blob.value.tier_to_cool_after_days_since_modification_greater_than, null) tier_to_cool_after_days_since_last_access_time_greater_than = try(base_blob.value.tier_to_cool_after_days_since_last_access_time_greater_than, null) tier_to_archive_after_days_since_modification_greater_than = try(base_blob.value.tier_to_archive_after_days_since_modification_greater_than, null) tier_to_archive_after_days_since_last_access_time_greater_than = try(base_blob.value.tier_to_archive_after_days_since_last_access_time_greater_than, null) delete_after_days_since_modification_greater_than = try(base_blob.value.delete_after_days_since_modification_greater_than, null) delete_after_days_since_last_access_time_greater_than = try(base_blob.value.delete_after_days_since_last_access_time_greater_than, null) } } dynamic "snapshot" { for_each = try(rule.value.actions.snapshot, {}) content { change_tier_to_archive_after_days_since_creation = try(snapshot.value.change_tier_to_archive_after_days_since_creation, null) change_tier_to_cool_after_days_since_creation = try(snapshot.value.change_tier_to_cool_after_days_since_creation, null) delete_after_days_since_creation_greater_than = try(snapshot.value.delete_after_days_since_creation_greater_than, null) } } dynamic "version" { for_each = try(rule.value.actions.version, {}) content { change_tier_to_archive_after_days_since_creation = try(version.value.change_tier_to_archive_after_days_since_creation, null) change_tier_to_cool_after_days_since_creation = try(version.value.change_tier_to_cool_after_days_since_creation, null) delete_after_days_since_creation = try(version.value.delete_after_days_since_creation, null) } } } } } }
variable.tf
variable "management_policy" { type = map(object({ rule = object({ name = string enabled = bool filters = optional(object({ prefix_match = optional(list(string)) blob_types = optional(list(string)) })) match_blob_index_tags = optional(object({ name = optional(string) value = optional(string) operation = optional(string) })) actions = optional(object({ base_blob = optional(object({ tier_to_cool_after_days_since_modification_greater_than = optional(number) tier_to_archive_after_days_since_modification_greater_than = optional(number) delete_after_days_since_modification_greater_than = optional(number) })) snapshot = optional(object({ delete_after_days_since_creation_greater_than = optional(number) })) version = optional(object({ change_tier_to_archive_after_days_since_creation = optional(number) change_tier_to_cool_after_days_since_creation = optional(number) delete_after_days_since_creation = optional(number) })) })) }) })) }
example.tf
management_policy = { rule = { name = "rule1" enabled = true filters = { prefix_match = ["test"] blob_types = ["blockBlob"] } match_blob_index_tags = { name = "tag1" value = "value1" operation = "All" } actions = { base_blob = { tier_to_cool_after_days_since_modification_greater_than = 30 tier_to_archive_after_days_since_modification_greater_than = 60 delete_after_days_since_modification_greater_than = 90 } snapshot = { delete_after_days_since_creation_greater_than = 180 } version = { change_tier_to_archive_after_days_since_creation = 30 change_tier_to_cool_after_days_since_creation = 60 delete_after_days_since_creation = 90 } } } }
报错信息
│ Error: Invalid value for input variable │ │ on main.tf line 125, in module "this": │ 125: management_policy = { │ 126: rule = { │ 127: name = "rule1" │ 128: enabled = true │ 129: filters = { │ 130: prefix_match = ["test"] │ 131: blob_types = ["blockBlob"] │ 132: } │ 133: match_blob_index_tags = { │ 134: name = "tag1" │ 135: value = "value1" │ 136: operation = "All" │ 137: } │ 138: actions = { │ 139: base_blob = { │ 140: tier_to_cool_after_days_since_modification_greater_than = 30 │ 141: tier_to_archive_after_days_since_modification_greater_than = 60 │ 142: delete_after_days_since_modification_greater_than = 90 │ 143: } │ 144: snapshot = { │ 145: delete_after_days_since_creation_greater_than = 180 │ 146: } │ 147: version = { │ 148: change_tier_to_archive_after_days_since_creation = 30 │ 149: change_tier_to_cool_after_days_since_creation = 60 │ 150: delete_after_days_since_creation = 90 │ 151: } │ 152: } │ 153: } │ 154: } │ │ The given value is not suitable for module.this.var.management_policy declared at ../../variables.management_policy.tf:1,1-29: │ element "rule": attribute "rule" is required.
问题分析与修复
核心问题
- 变量类型与传入值不匹配:变量
management_policy定义为map(object({ rule = object(...) })),要求每个map值都包含rule属性,但实际传入的rule键对应的value里没有嵌套rule字段,触发必填属性错误。 - main.tf变量引用错误:代码中使用
var.settings.rules,但变量定义里不存在settings变量,逻辑不匹配。
修复步骤
1. 修正变量定义(variable.tf)
将变量改为列表类型适配多规则场景,同时修正标签匹配字段的类型(支持多个标签):
variable "management_policy_rules" { type = list(object({ name = string enabled = bool filters = optional(object({ prefix_match = optional(list(string)) blob_types = optional(list(string)) match_blob_index_tags = optional(list(object({ name = string value = string operation = string }))) })) actions = object({ base_blob = optional(object({ tier_to_cool_after_days_since_modification_greater_than = optional(number) tier_to_archive_after_days_since_modification_greater_than = optional(number) delete_after_days_since_modification_greater_than = optional(number) tier_to_cool_after_days_since_last_access_time_greater_than = optional(number) tier_to_archive_after_days_since_last_access_time_greater_than = optional(number) delete_after_days_since_last_access_time_greater_than = optional(number) })) snapshot = optional(object({ change_tier_to_archive_after_days_since_creation = optional(number) change_tier_to_cool_after_days_since_creation = optional(number) delete_after_days_since_creation_greater_than = optional(number) })) version = optional(object({ change_tier_to_archive_after_days_since_creation = optional(number) change_tier_to_cool_after_days_since_creation = optional(number) delete_after_days_since_creation = optional(number) })) }) })) description = "List of rules for the storage management policy" }
2. 修正main.tf变量引用与逻辑
调整动态块的for_each目标,替换为新变量,并简化空值判断逻辑:
resource "azurerm_storage_management_policy" "mgmt_policy" { storage_account_id = var.storage_account_id dynamic "rule" { for_each = var.management_policy_rules content { name = rule.value.name enabled = rule.value.enabled dynamic "filters" { for_each = rule.value.filters != null ? [rule.value.filters] : [] content { prefix_match = filters.value.prefix_match blob_types = filters.value.blob_types dynamic "match_blob_index_tag" { for_each = filters.value.match_blob_index_tags != null ? filters.value.match_blob_index_tags : [] content { name = match_blob_index_tag.value.name operation = match_blob_index_tag.value.operation value = match_blob_index_tag.value.value } } } } actions { dynamic "base_blob" { for_each = rule.value.actions.base_blob != null ? [rule.value.actions.base_blob] : [] content { tier_to_cool_after_days_since_modification_greater_than = base_blob.value.tier_to_cool_after_days_since_modification_greater_than tier_to_cool_after_days_since_last_access_time_greater_than = base_blob.value.tier_to_cool_after_days_since_last_access_time_greater_than tier_to_archive_after_days_since_modification_greater_than = base_blob.value.tier_to_archive_after_days_since_modification_greater_than tier_to_archive_after_days_since_last_access_time_greater_than = base_blob.value.tier_to_archive_after_days_since_last_access_time_greater_than delete_after_days_since_modification_greater_than = base_blob.value.delete_after_days_since_modification_greater_than delete_after_days_since_last_access_time_greater_than = base_blob.value.delete_after_days_since_last_access_time_greater_than } } dynamic "snapshot" { for_each = rule.value.actions.snapshot != null ? [rule.value.actions.snapshot] : [] content { change_tier_to_archive_after_days_since_creation = snapshot.value.change_tier_to_archive_after_days_since_creation change_tier_to_cool_after_days_since_creation = snapshot.value.change_tier_to_cool_after_days_since_creation delete_after_days_since_creation_greater_than = snapshot.value.delete_after_days_since_creation_greater_than } } dynamic "version" { for_each = rule.value.actions.version != null ? [rule.value.actions.version] : [] content { change_tier_to_archive_after_days_since_creation = version.value.change_tier_to_archive_after_days_since_creation change_tier_to_cool_after_days_since_creation = version.value.change_tier_to_cool_after_days_since_creation delete_after_days_since_creation = version.value.delete_after_days_since_creation } } } } } }
3. 修正example.tf传入格式
改为列表形式传递规则:
management_policy_rules = [ { name = "rule1" enabled = true filters = { prefix_match = ["test"] blob_types = ["blockBlob"] match_blob_index_tags = [ { name = "tag1" value = "value1" operation = "All" } ] } actions = { base_blob = { tier_to_cool_after_days_since_modification_greater_than = 30 tier_to_archive_after_days_since_modification_greater_than = 60 delete_after_days_since_modification_greater_than = 90 } snapshot = { delete_after_days_since_creation_greater_than = 180 } version = { change_tier_to_archive_after_days_since_creation = 30 change_tier_to_cool_after_days_since_creation = 60 delete_after_days_since_creation = 90 } } } ]
额外说明
- 原
map类型变量不符合存储管理策略多规则的实际场景,改为list更合理。 - 修正
match_blob_index_tags为列表类型,支持同时匹配多个索引标签。 - 移除冗余的
try函数,改用空值判断处理可选字段,逻辑更清晰。
内容的提问来源于stack exchange,提问作者steve
相关产品推荐
相关产品推荐

