You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

配置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.

问题分析与修复

核心问题

  1. 变量类型与传入值不匹配:变量management_policy定义为map(object({ rule = object(...) })),要求每个map值都包含rule属性,但实际传入的rule键对应的value里没有嵌套rule字段,触发必填属性错误。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 08:44:54