Search code examples
azureterraformterraform-provider-azure

trying to write module for azurerm_storage_management_policy


I need to configure azurerm_storage_management_policy for module. I have wrote following terraform resource block and getting error during terraform plan. I believe this is something wrong with the variable .

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 - terraform Plan **

│ 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.


Solution

  • Creating storage management policy using terraform.

    The main blocker is due to the way you define the variable file. The variable file required rule to be defined which is missing the in your configuration.

    I tried an updated configuration by making the management_policy variable is expceted to be a map with a rules key, where each rule is also a map.

    Configuration:

    main.tf

    resource "azurerm_storage_management_policy" "mgmt_policy" {
      storage_account_id = azurerm_storage_account.example.id
    
      dynamic "rule" {
        for_each = var.management_policy["policy1"].rules
    
        content {
          name    = rule.value.name
          enabled = rule.value.enabled
    
          filters {
            prefix_match = try(rule.value.filters.prefix_match, null)
            blob_types   = try(rule.value.filters.blob_types, null)
    
            dynamic "match_blob_index_tag" {
              for_each = try(rule.value.filters.match_blob_index_tags, [])
    
              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 {
            base_blob {
              tier_to_cool_after_days_since_modification_greater_than     = try(rule.value.actions.base_blob.tier_to_cool_after_days_since_modification_greater_than, null)
              tier_to_archive_after_days_since_modification_greater_than  = try(rule.value.actions.base_blob.tier_to_archive_after_days_since_modification_greater_than, null)
              delete_after_days_since_modification_greater_than           = try(rule.value.actions.base_blob.delete_after_days_since_modification_greater_than, null)
            }
    
            snapshot {
              delete_after_days_since_creation_greater_than = try(rule.value.actions.snapshot.delete_after_days_since_creation_greater_than, null)
            }
    
            version {
              change_tier_to_archive_after_days_since_creation = try(rule.value.actions.version.change_tier_to_archive_after_days_since_creation, null)
              change_tier_to_cool_after_days_since_creation    = try(rule.value.actions.version.change_tier_to_cool_after_days_since_creation, null)
              delete_after_days_since_creation                 = try(rule.value.actions.version.delete_after_days_since_creation, null)
            }
          }
        }
      }
    }
    

    variable.tf:

    variable "management_policy" {
      type = map(object({
        rules = map(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      = 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)
            }))
          }))
        }))
      }))
    }
    
    variable "storage_account_name" {
      description = "The name of the Azure Storage Account."
      type        = string
    }
    

    tfvars:

    management_policy = {
      "policy1" = {
        rules = {
          "rule1" = {
            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
              }
            }
          }
        }
      }
    }
    
    storage_account_name = "vinayccssstorageacct" 
    

    Deployement:

    enter image description here

    enter image description here

    Refer:

    https://learn.microsoft.com/en-us/azure/storage/blobs/lifecycle-management-policy-configure?tabs=azure-portal

    https://developer.hashicorp.com/terraform/language/expressions/type-constraints

    https://developer.hashicorp.com/terraform/language/expressions/dynamic-blocks

    azurerm_storage_management_policy | Resources | hashicorp/azurerm | Terraform | Terraform Registry