Understand resource locking in Azure Blueprints

The creation of consistent environments at scale is only truly valuable if there's a mechanism to maintain that consistency. This article explains how resource locking works in Azure Blueprints. To see an example of resource locking and application of deny assignments, see the protecting new resources tutorial.

Note

Resource locks deployed by Azure Blueprints are only applied to non-extension resources deployed by the blueprint assignment. Existing resources, such as those in resource groups that already exist, don't have locks added to them.

Locking modes and states

Locking Mode applies to the blueprint assignment and it has three options: Don't Lock, Read Only, or Do Not Delete. The locking mode is configured during artifact deployment during a blueprint assignment. A different locking mode can be set by updating the blueprint assignment. Locking modes, however, can't be changed outside of Azure Blueprints.

Resources created by artifacts in a blueprint assignment have four states: Not Locked, Read Only, Cannot Edit / Delete, or Cannot Delete. Each artifact type can be in the Not Locked state. The following table can be used to determine the state of a resource:

Mode Artifact Resource Type State Description
Don't Lock * Not Locked Resources aren't protected by Azure Blueprints. This state is also used for resources added to a Read Only or Do Not Delete resource group artifact from outside a blueprint assignment.
Read Only Resource group Cannot Edit / Delete The resource group is read only and tags on the resource group can't be modified. Not Locked resources can be added, moved, changed, or deleted from this resource group.
Read Only Non-resource group Read Only The resource can't be altered in any way. No changes and it can't be deleted.
Do Not Delete * Cannot Delete The resources can be altered, but can't be deleted. Not Locked resources can be added, moved, changed, or deleted from this resource group.

Overriding locking states

It's typically possible for someone with appropriate Azure role-based access control (Azure RBAC) on the subscription, such as the 'Owner' role, to be allowed to alter or delete any resource. This access isn't the case when Azure Blueprints applies locking as part of a deployed assignment. If the assignment was set with the Read Only or Do Not Delete option, not even the subscription owner can perform the blocked action on the protected resource.

This security measure protects the consistency of the defined blueprint and the environment it was designed to create from accidental or programmatic deletion or alteration.

Assign at management group

The only option to prevent subscription owners from removing a blueprint assignment is to assign the blueprint to a management group. In this scenario, only Owners of the management group have the permissions needed to remove the blueprint assignment.

To assign the blueprint to a management group instead of a subscription, the REST API call changes to look like this:

PUT https://management.azure.com/providers/Microsoft.Management/managementGroups/{assignmentMG}/providers/Microsoft.Blueprint/blueprintAssignments/{assignmentName}?api-version=2018-11-01-preview

The management group defined by {assignmentMG} must be either within the management group hierarchy or be the same management group where the blueprint definition is saved.

The request body of the blueprint assignment looks like this:

{
    "identity": {
        "type": "SystemAssigned"
    },
    "location": "eastus",
    "properties": {
        "description": "enforce pre-defined simpleBlueprint to this XXXXXXXX subscription.",
        "blueprintId": "/providers/Microsoft.Management/managementGroups/{blueprintMG}/providers/Microsoft.Blueprint/blueprints/simpleBlueprint",
        "scope": "/subscriptions/{targetSubscriptionId}",
        "parameters": {
            "storageAccountType": {
                "value": "Standard_LRS"
            },
            "costCenter": {
                "value": "Contoso/Online/Shopping/Production"
            },
            "owners": {
                "value": [
                    "johnDoe@contoso.com",
                    "johnsteam@contoso.com"
                ]
            }
        },
        "resourceGroups": {
            "storageRG": {
                "name": "defaultRG",
                "location": "eastus"
            }
        }
    }
}

The key difference in this request body and one being assigned to a subscription is the properties.scope property. This required property must be set to the subscription that the blueprint assignment applies to. The subscription must be a direct child of the management group hierarchy where the blueprint assignment is stored.

Note

A blueprint assigned to management group scope still operates as a subscription level blueprint assignment. The only difference is where the blueprint assignment is stored to prevent subscription owners from removing the assignment and associated locks.

Removing locking states

If it becomes necessary to modify or delete a resource protected by an assignment, there are two ways to do so.

  • Updating the blueprint assignment to a locking mode of Don't Lock
  • Delete the blueprint assignment

When the assignment is removed, the locks created by Azure Blueprints are removed. However, the resource is left behind and would need to be deleted through normal means.

How blueprint locks work

An Azure RBAC deny assignments deny action is applied to artifact resources during assignment of a blueprint if the assignment selected the Read Only or Do Not Delete option. The deny action is added by the managed identity of the blueprint assignment and can only be removed from the artifact resources by the same managed identity. This security measure enforces the locking mechanism and prevents removing the blueprint lock outside Azure Blueprints.

Screenshot of the Access control (I A M) page and the Deny assignments tab for a resource group.

The deny assignment properties of each mode are as follows:

Mode Permissions.Actions Permissions.NotActions Principals[i].Type ExcludePrincipals[i].Id DoNotApplyToChildScopes
Read Only * */read
Microsoft.Authorization/locks/delete
Microsoft.Network/virtualNetwork/subnets/join/action
SystemDefined (Everyone) blueprint assignment and user-defined in excludedPrincipals Resource group - true; Resource - false
Do Not Delete */delete Microsoft.Authorization/locks/delete
Microsoft.Network/virtualNetwork/subnets/join/action
SystemDefined (Everyone) blueprint assignment and user-defined in excludedPrincipals Resource group - true; Resource - false

Important

Azure Resource Manager caches role assignment details for up to 30 minutes. As a result, deny assignments deny action's on blueprint resources may not immediately be in full effect. During this period of time, it might be possible to delete a resource intended to be protected by blueprint locks.

Exclude a principal from a deny assignment

In some design or security scenarios, it may be necessary to exclude a principal from the deny assignment the blueprint assignment creates. This step is done in REST API by adding up to five values to the excludedPrincipals array in the locks property when creating the assignment. The following assignment definition is an example of a request body that includes excludedPrincipals:

{
  "identity": {
    "type": "SystemAssigned"
  },
  "location": "eastus",
  "properties": {
    "description": "enforce pre-defined simpleBlueprint to this XXXXXXXX subscription.",
    "blueprintId": "/providers/Microsoft.Management/managementGroups/{mgId}/providers/Microsoft.Blueprint/blueprints/simpleBlueprint",
    "locks": {
        "mode": "AllResourcesDoNotDelete",
        "excludedPrincipals": [
            "7be2f100-3af5-4c15-bcb7-27ee43784a1f",
            "38833b56-194d-420b-90ce-cff578296714"
        ]
    },
    "parameters": {
      "storageAccountType": {
        "value": "Standard_LRS"
      },
      "costCenter": {
        "value": "Contoso/Online/Shopping/Production"
      },
      "owners": {
        "value": [
          "johnDoe@contoso.com",
          "johnsteam@contoso.com"
        ]
      }
    },
    "resourceGroups": {
      "storageRG": {
        "name": "defaultRG",
        "location": "eastus"
      }
    }
  }
}

Exclude an action from a deny assignment

Similar to excluding a principal on a deny assignment in a blueprint assignment, you can exclude specific Azure resource provider operations. Within the properties.locks block, in the same place that excludedPrincipals is, an excludedActions can be added:

"locks": {
    "mode": "AllResourcesDoNotDelete",
    "excludedPrincipals": [
        "7be2f100-3af5-4c15-bcb7-27ee43784a1f",
        "38833b56-194d-420b-90ce-cff578296714"
    ],
    "excludedActions": [
        "Microsoft.ContainerRegistry/registries/push/write",
        "Microsoft.Authorization/*/read"
    ]
},

While excludedPrincipals must be explicit, excludedActions entries can make use of * for wildcard matching of resource provider operations.

Next steps