Search code examples
azurelifecycleazure-cli

Unable to add new rule in Storage Management Policy on Azure


I am using az cli to add a storage management-policy to delete the blobs in the containers whose modification time is more than 7 days.
Here is the policy.json file:

  "rules": [
    {
      "name": "expirationRule1",
      "enabled": true,
      "type": "Lifecycle",
      "definition": {
        "filters": {
          "blobTypes": [ "blockBlob" ],
          "prefixMatch": [ "container1" ]
        },
        "actions": {
          "baseBlob": {
            "delete": { "daysAfterModificationGreaterThan": 7 }
          }
        }
      }
    }
  ]
}

I create this lifecycle management policy using the command:

az storage account management-policy create --account-name <my_acc_name> --policy <policy_file> --resource-group <my_res_group>

This step succeeds. Now I want to add another policy on a different container. The policy.json remains same with prefixMatch changed to container2 and name changed to expirationRule2. Now when I apply this new policy with the same command mentioned above, I cannot see the older policy applied, but can only see the new policy.
Here are the steps:

$az storage account management-policy create --account-name resacc1 --resource-group resgrp1 --policy /tmp/azure_lifecycle.json

{
  "id": "<some_id_here>",
  "lastModifiedTime": "2021-05-10T10:10:32.261245+00:00",
  "name": "DefaultManagementPolicy",
  "policy": {
    "rules": [
      {
        "definition": {
          "actions": {
            "baseBlob": {
              "delete": {
                "daysAfterLastAccessTimeGreaterThan": null,
                "daysAfterModificationGreaterThan": 7.0
              },
              "enableAutoTierToHotFromCool": null,
              "tierToArchive": null,
              "tierToCool": null
            },
            "snapshot": null,
            "version": null
          },
          "filters": {
            "blobIndexMatch": null,
            "blobTypes": [
              "blockBlob"
            ],
            "prefixMatch": [
              "container1"                                << container1 is prefixMatch
            ]
          }
        },
        "enabled": true,
        "name": "expirationRule1",
        "type": "Lifecycle"
      }
    ]
  },
  "resourceGroup": "resgrp1",
  "type": "Microsoft.Storage/storageAccounts/managementPolicies"
}

Now I add new policy with container2:

$ az storage account management-policy create --account-name resacc1 --resource-group resgrp1 --policy /tmp/azure_lifecycle.json
{
  "id": "<some_id_here>",
  "lastModifiedTime": "2021-05-10T10:11:54.622184+00:00",
  "name": "DefaultManagementPolicy",
  "policy": {
    "rules": [
      {
        "definition": {
          "actions": {
            "baseBlob": {
              "delete": {
                "daysAfterLastAccessTimeGreaterThan": null,
                "daysAfterModificationGreaterThan": 7.0
              },
              "enableAutoTierToHotFromCool": null,
              "tierToArchive": null,
              "tierToCool": null
            },
            "snapshot": null,
            "version": null
          },
          "filters": {
            "blobIndexMatch": null,
            "blobTypes": [
              "blockBlob"
            ],
            "prefixMatch": [
              "container2"                                    << container2 in prefixMatch
            ]
          }
        },
        "enabled": true,
        "name": "expirationRule2",
        "type": "Lifecycle"
      }
    ]
  },
  "resourceGroup": "resgrp1",
  "type": "Microsoft.Storage/storageAccounts/managementPolicies"
}

Now after applying the 2 rules, when I do a show command it only shows that a single policy is applied on the storage account.

$ az storage account management-policy show --account-name resacc1 --resource-group resgrp1
{
  "id": "<some_id_here>",
  "lastModifiedTime": "2021-05-10T10:11:54.622184+00:00",
  "name": "DefaultManagementPolicy",
  "policy": {
    "rules": [
      {
        "definition": {
          "actions": {
            "baseBlob": {
              "delete": {
                "daysAfterLastAccessTimeGreaterThan": null,
                "daysAfterModificationGreaterThan": 7.0
              },
              "enableAutoTierToHotFromCool": null,
              "tierToArchive": null,
              "tierToCool": null
            },
            "snapshot": null,
            "version": null
          },
          "filters": {
            "blobIndexMatch": null,
            "blobTypes": [
              "blockBlob"
            ],
            "prefixMatch": [
              "container2"
            ]
          }
        },
        "enabled": true,
        "name": "expirationRule2",
        "type": "Lifecycle"
      }
    ]
  },
  "resourceGroup": "resgrp1",
  "type": "Microsoft.Storage/storageAccounts/managementPolicies"
}

Can someone please help me out on knowing how to append a new rule to an already existing policy OR create a new policy all together, so that I have both the rules applied on the containers in my storage account.


Solution

  • Looking at AZ CLI documentation, the only options available to you are either creating a new policy or updating an existing policy (i.e. replacing a policy completely). No command is available to add a rule to an existing policy.

    The reason you're seeing the behavior is because you're updating the entire policy which is overriding the previous policy contents.

    What you would need to do is modify your policy.json file and include both rules and then update the policy on the storage account. Or you could get the existing policy using az storage account management-policy show, parse the policy JSON, add new rule and then update the policy using az storage account management-policy update.