Azure Blueprints (Preview) is retired on January 31, 2027, and the shutdown is already under way: since July 31, 2026 you can't create new definitions, from October 31, 2026 you can't edit definitions or create assignments, and from December 31, 2026 you can't modify assignments. To replace a blueprint, export its definition with Export-AzBlueprintWithArtifact, rebuild the artifacts as one Bicep file, optionally publish it as a template spec, and deploy it through a deployment stack whose deny settings (denyDelete or denyWriteAndDelete) take over from the blueprint lock. Once the stack is verified, remove the blueprint assignment; the deployed resources stay where they are.
Who this is for and what you will have at the end
This guide is for platform and governance teams that still have blueprint assignments on subscriptions or management groups, typically landing zone baselines that bundle policy assignments, role assignments, resource groups and ARM templates. It assumes you can read Bicep and run Azure PowerShell or the Azure CLI.
At the end you will have:
- An exported copy of every blueprint definition, version and assignment you want to keep.
- One Bicep file per blueprint, with policy assignments, role assignments, resource groups and templates as ordinary resources and modules.
- A versioned template spec for each converted blueprint (optional but recommended if teams consume it from Azure).
- A deployment stack per former assignment, with deny settings that reproduce the old lock behavior.
- Retired blueprint assignments, without a gap in protection.
What changes and when
The retirement is phased. Plan your work around the dates, not just the final one, because the October and December cut-offs remove the options you would normally use to rehearse.
| Date | What stops working |
|---|---|
| July 31, 2026 | Creating new blueprint definitions and versions |
| October 31, 2026 | Modifying existing definitions; creating new assignments |
| December 31, 2026 | Modifying existing assignments (including changing the lock mode) |
| January 31, 2027 | The service: API, Azure CLI and PowerShell commands, portal blade, blueprint locks. Unexported definitions, versions and assignments are deleted |
Read and delete operations stay available until retirement. That matters for the migration order later in this article: after December 31, 2026 you can still delete an assignment (which removes its locks), but you can no longer switch it to Don't Lock.
If you do nothing, resources deployed by blueprints stay in place and inherit RBAC from their parent scope, but every deny assignment created by a blueprint lock is removed automatically. For anyone who relied on a Read Only lock to stop subscription owners from changing a hub network or a logging workspace, that effectively widens access overnight.
Which replacement does what
Blueprints combined two jobs. Microsoft now splits them across two generally available features.
| Blueprint capability | Replacement |
|---|---|
| Definition: store and version a package of artifacts | Template spec (or a Git repository) |
| Assignment: deploy, track and update the artifacts at a scope | Deployment stack |
| Lock: Read Only or Do Not Delete | Deployment stack deny settings |
| Policy assignment artifact | Microsoft.Authorization/policyAssignments resource |
| Role assignment artifact | Microsoft.Authorization/roleAssignments resource |
| ARM template artifact | Bicep module, nested or linked template |
| Resource group artifact | Microsoft.Resources/resourceGroups resource |
Template specs live in a resource group and are shared through RBAC (the built-in Template Spec Reader and Template Spec Contributor roles). Deployment stacks can be created at resource group, subscription or management group scope.
Prerequisites
- Azure PowerShell 12.0.0 or later or Azure CLI 2.61.0 or later. Deployment stacks require these versions.
- The Az.Blueprint module for the export:
Install-Module -Name Az.Blueprint. - Permissions. Read access to the blueprint definitions; rights to create template specs (the built-in Template Spec Contributor role) and to deploy the template's resources at the target scope. For the stack itself, the built-in Azure Deployment Stack Owner role can manage stacks including their deny settings, while Azure Deployment Stack Contributor can manage stacks but can't create or delete their deny assignments.
- A decision on where stacks live. Microsoft recommends storing a stack at the parent of the scope it protects, so the people working inside the subscription can't edit the stack and its deny assignment. Deny assignments aren't supported at management group scope, but they are supported in a management group stack that deploys to a subscription.
Step 1: Inventory every blueprint
Start with the two inventory sources Microsoft lists: the Azure Advisor recommendation that highlights subscriptions and management groups where Blueprints is in use, and the Azure Blueprints blade in the portal. Then capture the details with PowerShell, because you need the lock mode and parameters of each assignment.
Connect-AzAccount
$subId = "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e"
# Definitions saved in the subscription (repeat with -ManagementGroupId for management groups)
Get-AzBlueprint -SubscriptionId $subId | Select-Object Name, Versions, TargetScope
# Assignments, including their lock mode
Get-AzBlueprintAssignment -SubscriptionId $subId |
Select-Object Name, Scope, LockMode, ProvisioningStateThe LockMode column shows None, AllResourcesReadOnly or AllResourcesDoNotDelete. Record it for every assignment; it decides both the deny settings mode you use and the order of the cutover in step 5.
Step 2: Export definitions and assignments
Export each definition, including its artifacts, before you change anything. The export writes a folder per blueprint containing blueprint.json and an artifacts subfolder with one JSON file per artifact.
$bp = Get-AzBlueprint -SubscriptionId $subId -Name 'corp-baseline' -Version '1.3'
Export-AzBlueprintWithArtifact -Blueprint $bp -OutputPath 'C:\Blueprints'
# Keep the assignment details too: parameters, resource group names, lock mode
Get-AzBlueprintAssignment -SubscriptionId $subId -Name 'corp-baseline-prod' |
ConvertTo-Json -Depth 10 |
Out-File 'C:\Blueprints\corp-baseline-prod.assignment.json'Commit the exported folders to source control. They are your only copy after January 31, 2027, and they are the input for the conversion.
Step 3: Convert the artifacts to Bicep
Rebuild each blueprint as a single main Bicep file. Set targetScope to match where the blueprint was assigned (usually subscription), then translate each artifact JSON file into the equivalent resource. Copy role definition IDs, policy definition IDs and parameter names from the exported artifacts rather than retyping them.
targetScope = 'subscription'
param location string = 'westeurope'
param networkRgName string = 'rg-network-prod'
param readerPrincipalId string
param readerRoleDefinitionGuid string
param allowedLocationsPolicyId string
param allowedLocations array = [
'westeurope'
'northeurope'
]
// Resource group artifact
resource networkRg 'Microsoft.Resources/resourceGroups@2025-04-01' = {
name: networkRgName
location: location
}
// Role assignment artifact
resource readerAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(subscription().id, readerPrincipalId, readerRoleDefinitionGuid)
properties: {
principalId: readerPrincipalId
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', readerRoleDefinitionGuid)
}
}
// Policy assignment artifact
resource allowedLocationsAssignment 'Microsoft.Authorization/policyAssignments@2025-03-01' = {
name: 'allowed-locations'
properties: {
displayName: 'Allowed locations (migrated from corp-baseline)'
policyDefinitionId: allowedLocationsPolicyId
enforcementMode: 'Default'
parameters: {
listOfAllowedLocations: {
value: allowedLocations
}
}
}
}
// ARM template artifact, rewritten as a module
module hubNetwork 'modules/hub-network.bicep' = {
name: 'hub-network'
scope: networkRg
params: {
location: location
}
}Points that trip people up during conversion:
- Names must match what already exists. If the blueprint created
rg-network-prod, the Bicep file must declare exactly that name, or the stack creates a second resource group instead of adopting the existing one. - Policies that deploy or modify resources need an identity. A policy assignment with
DeployIfNotExistsorModifyeffects needs anidentityblock, andlocationis required when you use a managed identity. Grant that identity the roles the policy definition lists. - Blueprint parameters become Bicep parameters. Static values in
blueprint.jsonand dynamic values from the exported assignment map toparamdeclarations and a.bicepparamor JSON parameters file. - Sequencing. Blueprints let you order artifacts explicitly. In Bicep, ordering comes from references between resources and modules; add
dependsOnonly where there is no natural reference.
Step 4: Publish the template as a template spec
If teams consume the baseline from Azure rather than from a repository, publish the converted file as a template spec. Bicep is transpiled to JSON when the spec is created, and each spec can hold any number of versions.
az ts create \
--name corp-baseline \
--version 2.0.0 \
--resource-group rg-templatespecs \
--location westeurope \
--template-file ./main.bicepThe PowerShell equivalent:
New-AzTemplateSpec -Name corp-baseline -Version 2.0.0 -ResourceGroupName rg-templatespecs `
-Location westeurope -TemplateFile ./main.bicepRetrieve the version ID for the next step with az ts show --name corp-baseline --resource-group rg-templatespecs --version 2.0.0 --query id. A template spec is limited to roughly 2 MB; larger content fails with TemplateSpecTooLarge, and Microsoft's guidance is to split it into several specs.
Step 5: Plan the cutover for each lock mode
A blueprint lock is a deny assignment that applies to everyone except the blueprint assignment's managed identity and any excluded principals. That has a direct consequence for the cutover order.
| Blueprint lock | Deny settings mode | Cutover order |
|---|---|---|
Don't Lock (None) | none | Deploy the stack, then remove the assignment |
Do Not Delete (AllResourcesDoNotDelete) | denyDelete | Deploy the stack, then remove the assignment |
Read Only (AllResourcesReadOnly) | denyWriteAndDelete | Remove or relax the blueprint lock, then deploy the stack immediately |
Do Not Delete only blocks */delete, so the stack can write to the protected resources while the blueprint lock is still in place, and there is no window without protection. Read Only blocks writes, so a stack deployment that touches those resources would be denied. For those assignments, either switch the lock to none with Set-AzBlueprintAssignment -Lock None (possible only until December 31, 2026) or delete the assignment with Remove-AzBlueprintAssignment, then deploy the stack straight away. Removing an assignment removes its locks but leaves the resources behind.
$bp = Get-AzBlueprint -SubscriptionId $subId -Name 'corp-baseline' -Version '1.3'
Set-AzBlueprintAssignment -Name 'corp-baseline-prod' -Blueprint $bp -SubscriptionId $subId -Lock NoneAzure Resource Manager caches role assignment details for up to 30 minutes, so allow for some delay between a lock change and the result you see.
Step 6: Deploy the deployment stack
Deploy the template spec version (or the Bicep file) as a stack. For the first deployment of migrated resources, detachAll is the cautious choice for --action-on-unmanage: if your Bicep file accidentally omits something the blueprint created, the resource is only detached from the stack instead of deleted. Switch to deleteResources later if you want the stack to clean up what you remove from the template.
az stack sub create \
--name corp-baseline-prod \
--location westeurope \
--template-spec "/subscriptions/<subscriptionId>/resourceGroups/rg-templatespecs/providers/Microsoft.Resources/templateSpecs/corp-baseline/versions/2.0.0" \
--parameters ./prod.parameters.json \
--deny-settings-mode denyWriteAndDelete \
--deny-settings-excluded-principals '<platform-team-group-object-id> <pipeline-sp-object-id>' \
--action-on-unmanage detachAllThe same stack with PowerShell:
New-AzSubscriptionDeploymentStack -Name corp-baseline-prod -Location westeurope `
-TemplateSpecId "/subscriptions/<subscriptionId>/resourceGroups/rg-templatespecs/providers/Microsoft.Resources/templateSpecs/corp-baseline/versions/2.0.0" `
-TemplateParameterFile ./prod.parameters.json `
-DenySettingsMode DenyWriteAndDelete `
-DenySettingsExcludedPrincipal "<platform-team-group-object-id>","<pipeline-sp-object-id>" `
-ActionOnUnmanage DetachAllSettings worth knowing:
- Excluded principals accept users, groups, service principals and managed identities, with a maximum of five. Exclude a group rather than individuals so membership changes don't require a stack update. Specifying more than five doesn't return an error, so check the count yourself.
- Excluded actions accept up to 200 resource provider operations, the equivalent of the blueprint
excludedActionslist. --deny-settings-apply-to-child-scopesextends the deny setting to child resources, for example databases under a SQL server.- Deny settings cover control plane operations only. Data plane objects such as Key Vault secrets or blob containers, and resources created implicitly by another resource, aren't protected or managed by the stack.
To store the stack one level up, use az stack mg create with --deployment-subscription, or New-AzManagementGroupDeploymentStack with -DeploymentSubscriptionId. Subscription owners then can't edit the stack or its deny assignment.
Verification
Confirm three things before you retire the blueprint.
- The stack manages what you expect. Each entry in the resource list shows
statusanddenyStatus.
az stack sub show --name corp-baseline-prod --output json(Get-AzSubscriptionDeploymentStack -Name corp-baseline-prod).Resources- The deny assignment is present. On a protected resource group, open Access control (IAM) and check the Deny assignments tab. Then test with an account that isn't excluded: a delete (and, for
denyWriteAndDelete, a change) should fail. - Policy and role assignments exist at the target scope and policy compliance evaluates as before.
When all three check out, remove the blueprint assignment if it still exists, and delete the definition once you're sure the export is in source control:
$assignment = Get-AzBlueprintAssignment -SubscriptionId $subId -Name 'corp-baseline-prod'
Remove-AzBlueprintAssignment -InputObject $assignment -SubscriptionId $subIdTroubleshooting
Stack out of sync. An update or delete can stop with: The deployment stack '{0}' might not have an accurate list of managed resources. To prevent resources from being accidentally deleted, check that the managed resource list doesn't have any additional values. Redeploy the current template with the same parameters, review the managed resource list, and only then rerun with --bypass-stack-out-of-sync-error (CLI) or -BypassStackOutOfSyncError (PowerShell).
Deny settings rejected. Creating or updating a stack with a deny settings mode other than none, or changing a stack that already has one, needs the permission behind the Azure Deployment Stack Owner role (Microsoft.Resources/deploymentStacks/manageDenySetting/action). Contributor-level stack rights aren't enough.
Generic template validation error in PowerShell. The New-* and Set-* stack cmdlets sometimes return an unhelpful validation error. Rerun the cmdlet with -Debug to see the detailed message in the raw response.
Resource group deleted despite deny settings. A stack at resource group scope doesn't manage its own resource group, so the group can still be deleted, taking the stack with it. Deploy at subscription scope and declare the resource group in the Bicep file, as in step 3.
Resource moved out of protection. Deny assignments are evaluated at the resource group for move operations, so a protected resource can be moved and loses the stack's protection. Microsoft's interim mitigation is a read-only resource lock on the resource group, removed temporarily while you update the stack.
Blueprint assignment can't be changed. After December 31, 2026 the PUT operations are disabled. Use Remove-AzBlueprintAssignment instead of Set-AzBlueprintAssignment.
No what-if preview. The what-if operation isn't available for deployment stacks yet. Run az stack sub validate with the same arguments as az stack sub create to validate the stack before you deploy it, and test the Bicep file against a non-production subscription first. The Microsoft Graph Bicep provider isn't supported in stacks either.
Checklist
- Every blueprint definition, version and assignment exported and committed before January 31, 2027.
- Lock mode recorded for each assignment; Read Only assignments switched to none before December 31, 2026, or scheduled for removal at cutover.
- One Bicep file per blueprint, with resource names matching the deployed resources.
- Template spec versions published (or a pipeline that deploys from Git).
- Stacks deployed with the right deny settings mode, excluded principals limited to five groups or identities, and
detachAllfor the first run. - Deny assignments verified on the IAM blade and with a negative test.
- Blueprint assignments removed and definitions deleted.
If the blueprint was part of a wider landing zone or migration programme, the governance section of the enterprise Azure cloud migration playbook covers how these baselines fit with subscriptions, policy and networking.
References
- Azure Blueprints retirement
- Azure Blueprints retirement FAQ
- Migrate Azure Blueprints to template specs
- Migrate blueprints to deployment stacks
- Create and deploy Azure deployment stacks in Bicep
- Known issues for deployment stacks
- Create and deploy template specs in Bicep
- Import and export blueprints with PowerShell
- How to manage assignments with PowerShell
- Understand resource locking in Azure Blueprints
- Microsoft.Authorization/policyAssignments template reference