Cloud & infrastructure

Azure Blueprints Retirement: Move to Template Specs and Deployment Stacks

Azure Blueprints retires on January 31, 2027. Export your definitions, rebuild them in Bicep, publish template specs and recreate blueprint locks with deployment stack deny settings.

13 min read
On this page

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.

DateWhat stops working
July 31, 2026Creating new blueprint definitions and versions
October 31, 2026Modifying existing definitions; creating new assignments
December 31, 2026Modifying existing assignments (including changing the lock mode)
January 31, 2027The 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 capabilityReplacement
Definition: store and version a package of artifactsTemplate spec (or a Git repository)
Assignment: deploy, track and update the artifacts at a scopeDeployment stack
Lock: Read Only or Do Not DeleteDeployment stack deny settings
Policy assignment artifactMicrosoft.Authorization/policyAssignments resource
Role assignment artifactMicrosoft.Authorization/roleAssignments resource
ARM template artifactBicep module, nested or linked template
Resource group artifactMicrosoft.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, ProvisioningState

The 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 DeployIfNotExists or Modify effects needs an identity block, and location is 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.json and dynamic values from the exported assignment map to param declarations and a .bicepparam or JSON parameters file.
  • Sequencing. Blueprints let you order artifacts explicitly. In Bicep, ordering comes from references between resources and modules; add dependsOn only 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.bicep

The PowerShell equivalent:

New-AzTemplateSpec -Name corp-baseline -Version 2.0.0 -ResourceGroupName rg-templatespecs `
  -Location westeurope -TemplateFile ./main.bicep

Retrieve 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 lockDeny settings modeCutover order
Don't Lock (None)noneDeploy the stack, then remove the assignment
Do Not Delete (AllResourcesDoNotDelete)denyDeleteDeploy the stack, then remove the assignment
Read Only (AllResourcesReadOnly)denyWriteAndDeleteRemove 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 None

Azure 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 detachAll

The 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 DetachAll

Settings 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 excludedActions list.
  • --deny-settings-apply-to-child-scopes extends 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.

  1. The stack manages what you expect. Each entry in the resource list shows status and denyStatus.
az stack sub show --name corp-baseline-prod --output json
(Get-AzSubscriptionDeploymentStack -Name corp-baseline-prod).Resources
  1. 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.
  2. 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 $subId

Troubleshooting

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 detachAll for 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

Questions people ask

When exactly is Azure Blueprints retired?

Azure Blueprints (Preview) is retired on January 31, 2027, after a phased shutdown that started on July 31, 2026. New definitions stopped on July 31, 2026, new assignments and definition edits stop on October 31, 2026, and assignment edits stop on December 31, 2026. On the retirement date the API stops responding and unexported definitions are deleted.

Are resources deployed by a blueprint deleted at retirement?

No. Resources created through blueprints remain in place and inherit RBAC from their parent scope. What disappears is the management layer: the definitions, the assignments and the blueprint locks (deny assignments), so any protection that depended on a Read Only or Do Not Delete lock is gone.

Do I need template specs to use deployment stacks?

No. A deployment stack can deploy a Bicep file or ARM template directly, for example from a pipeline that reads a Git repository. Template specs are useful when you want versioned templates stored in Azure and shared through RBAC, which is the role blueprint definitions used to play.

Which deny setting replaces a blueprint Read Only lock?

Use the denyWriteAndDelete deny settings mode for Read Only and denyDelete for Do Not Delete. Excluded principals (up to five) replace the blueprint excludedPrincipals list, and excluded actions (up to 200) replace excludedActions.

Azure BlueprintsTemplate SpecsDeployment StacksBicepAzure Policy
  1. A practical Azure landing zone for small and mid-size companies

    Set up Azure management groups, subscriptions, hub-and-spoke networking, Azure Policy, RBAC and budgets the right way from day one, scaled down from Microsoft's landing zone architecture.

  2. Azure Policy Tag Enforcement: Require, Inherit and Remediate Tags

    Enforce CostCenter and Owner tags with built-in Azure Policy definitions: deny untagged resource groups, inherit tags onto resources, and remediate existing resources with managed identities.

  3. Azure Update Manager: Schedule Patching for Azure VMs and Arc Servers

    Replace Automation Update Management or WSUS-only patching with Azure Update Manager: periodic assessment, maintenance configurations, dynamic scopes and scheduled patching for Azure and Arc servers.