| name | azure-blueprints-migration |
| description | Use when a user needs to migrate off Azure Blueprints (definitions and/or assignments) to Template Specs and Deployment Stacks before the January 31, 2027 retirement. Covers inventory, export, conversion to Bicep, policy decoupling, Template Spec publishing, Deployment Stack deployment with deny-settings, validation, and cutover. |
Azure Blueprints → Template Specs + Deployment Stacks Migration Skill
Audience: Any AI assistant (for example, GitHub Copilot) helping an Azure customer or partner migrate off Azure Blueprints.
Status: Azure Blueprints (preview) is retiring on January 31, 2027, with phased retirement beginning July 31, 2026. Migrate blueprint definitions and assignments to Deployment Stacks (recommended) + Template Specs before then. Authoritative dates, phased timeline, and FAQ: https://aka.ms/AzureBlueprintsRetirement.
Legal notices and disclaimers
[!IMPORTANT]
Read this before using this skill. By using this skill, or by acting on output an AI assistant produces from it, you accept the terms below.
Sample content, provided "AS IS." This skill is sample content made available under the MIT License in this repository. It is provided "AS IS", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, title, accuracy, and non-infringement. To the maximum extent permitted by applicable law, in no event shall Microsoft Corporation, its affiliates, or any contributor be liable for any claim, damages, or other liability — including direct, indirect, incidental, special, exemplary, consequential, or punitive damages, or for loss of data, loss of profits, loss of revenue, or business interruption — arising from, out of, or in connection with this skill or its use, however caused and on any theory of liability, even if advised of the possibility of such damages.
Not a Microsoft product or service. This skill is not a Microsoft product, service, or offering, and is not part of any Azure service. It is not covered by any Microsoft service level agreement (SLA), support agreement, Premier/Unified Support contract, or product lifecycle policy, and Microsoft has no obligation to maintain, update, correct, or continue to publish it. Do not open a Microsoft support case for this skill; file an issue in the Azure/azure-blueprints repository instead. For issues with an Azure service itself, use your normal Azure support channel.
Guidance only — not advice. This content is general technical guidance for informational purposes only. It is not legal, regulatory, compliance, audit, security, financial, tax, or other professional advice, and it neither establishes nor certifies any compliance posture. Migrating away from Azure Blueprints can change governance, policy enforcement, resource locks, role assignments, and audit evidence in your environment. Consult your own legal, compliance, and security advisors before applying any of this guidance to regulated, production, or business-critical workloads.
AI-generated output may be wrong. This skill instructs an AI assistant. AI output is probabilistic and non-deterministic: it may be inaccurate, incomplete, out of date, or inapplicable to your environment, and the same prompt may produce different results at different times. Any commands, scripts, templates, parameters, or resource identifiers an AI assistant generates using this skill are suggestions, not validated instructions, and are not reviewed or endorsed by Microsoft. You are responsible for independently reviewing, understanding, and testing every command before you run it.
Destructive operations — your responsibility. This skill describes operations that can be irreversible and destructive, including without limitation: removing blueprint assignments; deleting blueprint definitions and published versions; creating, updating, or deleting deployment stacks (including deleteResources behavior on unmanage); and applying or removing deny-settings, deny-assignments, and resource locks. Removing a blueprint assignment can also remove policy assignments, role assignments, and other resources it created. You are solely responsible for verifying scope and target identifiers; exporting and backing up definitions, assignments, parameters, and templates before deleting anything; validating in a non-production subscription first; following your own change-management, approval, and rollback processes; and for any resulting data loss, downtime, cost, security exposure, or compliance impact. Microsoft is not responsible for changes you make to your own Azure environment.
Your environment, your credentials, your permissions. Every command described here runs under your credentials and permissions, against your tenants, management groups, subscriptions, and resources. Neither Microsoft nor this skill performs any migration on your behalf, and Microsoft will not automatically migrate your blueprints. Your use of Azure services remains governed by the agreement under which you obtained them (for example, the Microsoft Customer Agreement or an Enterprise Agreement), the Microsoft Product Terms, the Microsoft Privacy Statement, and applicable Azure service-specific terms. Nothing in this skill modifies, supplements, or waives any term of those agreements.
Dates and roadmap are subject to change. Retirement dates, phased timelines, feature availability, product capabilities, and migration recommendations referenced in this skill may change. Nothing here is a commitment, promise, warranty, or binding obligation by Microsoft to deliver any feature or to honor any date, and it should not be relied upon in making purchasing or architectural decisions. The authoritative sources are the official retirement notice at https://aka.ms/AzureBlueprintsRetirement and Microsoft Learn. Always verify against current official documentation before acting.
Do not share secrets or confidential data with an AI assistant. Prompts, files, and command output you provide to an AI assistant may be transmitted to and processed by that assistant's provider under its own terms and privacy policy, which may not be Microsoft's. Do not paste credentials, keys, connection strings, certificates, tokens, personal data, customer data, or other confidential or regulated information into an AI conversation. Handling of anything you submit is governed by the terms of the AI product you are using, not by this repository.
Third-party and separately licensed components. Azure PowerShell (Az, Az.Blueprint), Azure CLI, Bicep, GitHub Copilot, and any other tools, modules, packages, or AI assistants referenced here are licensed separately under their own terms and are not provided, warranted, or supported as part of this skill. Trademarks and logos are subject to the Microsoft Trademark & Brand Guidelines; third-party trademarks are the property of their respective owners, and use of them does not imply endorsement.
Severability. If any provision of these notices is held unenforceable, the remaining provisions remain in full force and effect.
When to use this skill
Invoke this skill whenever the user:
- Mentions Azure Blueprints, blueprint definitions, blueprint assignments, blueprint locks, or the Blueprints retirement.
- Asks for a migration plan, "what replaces Blueprints?", or how to move governance from Blueprints to ARM/Bicep tooling.
- Needs to export, convert, or re-deploy resources currently managed by Blueprints.
- Asks about Template Specs or Deployment Stacks in the context of replacing Blueprints.
If the user is asking a general ARM/Bicep question with no Blueprints context, do not load this skill.
Operating principles (read first)
- Stacks over Template Specs alone. Use Template Specs as the storage/versioning layer; deploy via Deployment Stacks to preserve assignment-like lifecycle behavior. Recommend Template Spec–only deployment only when the user explicitly has no need for resource tracking or deny-settings.
- Do not auto-migrate. Always confirm scope, parameters, and lock parity with the user before producing or running deployment commands. Migration is customer-driven.
- Cutover is destructive. Removing a Blueprint assignment can remove embedded policy assignments. Always sequence: deploy new Stack → verify → re-assign decoupled policies if needed → only then remove the Blueprint assignment.
- Never invent IDs. If the user hasn't provided a management group ID, subscription ID, blueprint name, or version, ask before generating commands.
- Surface the retirement dates. When users plan timelines, remind them Azure Blueprints (preview) retires January 31, 2027, with phased retirement starting July 31, 2026 — so complete migration and export definitions before then. Link to https://aka.ms/AzureBlueprintsRetirement for the phased timeline.
- Definitions count too, not just assignments. The retirement recommendation flags every blueprint definition and published version — not only assignments. Unassigned definitions deploy nothing, but they still must be handled (convert to a Template Spec, or export-and-archive) and then deleted to clear the recommendation. Inventory with
Get-AzBlueprint at each subscription and management group, not just Get-AzBlueprintAssignment.
Inputs to gather from the user
Before producing any migration plan or commands, collect:
- Scope — management group ID, subscription IDs, and/or resource group names involved.
- Blueprint inventory — definition names + versions, and which subscriptions/MGs they're assigned to. Offer to help inventory via
Get-AzBlueprint / Get-AzBlueprintAssignment if unknown.
- Lock mode in use —
None / AllResourcesReadOnly / AllResourcesDoNotDelete. This drives the Stack denySettings choice.
- Identity — system-assigned vs. user-assigned managed identity used by the assignment.
- Policy posture — whether policies embedded in the blueprint are app-specific (keep in template) or baseline (lift to a standalone Initiative).
- Target tooling — Bicep (recommended) or ARM JSON.
- Production tolerance — sandbox available? Side-by-side acceptable? Or strict adopt-in-place required?
If any of these are unknown, ask the user before proceeding.
TL;DR — What replaces what
| Blueprints concept | Recommended replacement | Why |
|---|
| Blueprint Definition (package of artifacts: ARM templates, policy assignments, RBAC, resource groups) | Template Spec | Stores and versions ARM/Bicep templates as first-class Azure resources; closest parity to a Blueprint Definition. |
| Blueprint Assignment (deployment instance + lifecycle binding to a subscription/MG) | Deployment Stack | Tracks the resources it creates, supports deny-settings (parity to Blueprint locks/deny-assignments), and lets you update/delete the whole set as one unit. Preferred end-state. |
| Blueprint locks / deny-assignments | Deployment Stack denySettings | denyDelete or denyWriteAndDelete modes reproduce the protective behavior with first-class tooling. |
| Blueprint parameters | Template Spec / Stack parameters | Direct 1:1; pass the same values through the new deployment call. |
| Sequenced artifact ordering | Bicep dependsOn / ARM dependsOn | Express ordering in the template rather than via Blueprint artifact sequence. |
| Policy assignments inside a Blueprint | Standalone policy assignment or Azure Policy initiative (preferred for shared baselines) | Decouple policy from app/infra deployment so it can be managed independently. |
Decision tree
flowchart TD
A[Have an Azure Blueprint today?] --> B{Definition or<br/>Assignment?}
B -->|Definition only<br/>(reusable template)| C[Migrate to<br/>Template Spec]
B -->|Assignment<br/>(deployed instance)| D{Need lifecycle<br/>tracking + deny-locks?}
D -->|Yes| E[Deploy via<br/>Deployment Stack<br/>with denySettings]
D -->|No, one-shot| F[Deploy from<br/>Template Spec directly]
C --> G[Done — versioned,<br/>shareable template]
E --> H[Done — tracked,<br/>protected, updatable]
F --> H
style E fill:#cfe8ff,stroke:#0078d4,stroke-width:2px
style C fill:#e6f4ea,stroke:#188038,stroke-width:2px
End-to-end migration flow
flowchart LR
subgraph Today["Today — Azure Blueprints"]
BD[Blueprint<br/>Definition]
BA[Blueprint<br/>Assignment]
BL[Locks / Deny<br/>Assignments]
BD --> BA
BA --> BL
end
subgraph Migration["Migration steps"]
INV[1. Inventory<br/>blueprints]
EXT[2. Export<br/>definition JSON]
CONV[3. Convert artifacts<br/>to Bicep/ARM]
POL[4. Split policies<br/>into Policy / Initiative]
TS[5. Publish<br/>Template Spec]
STK[6. Deploy via<br/>Deployment Stack]
VAL[7. Validate<br/>in non-prod]
CUT[8. Cut over<br/>+ remove BP assignment]
end
subgraph Future["Future state"]
TSF[Template Spec<br/>(versioned package)]
STKF[Deployment Stack<br/>(tracked resources)]
DEN[denySettings<br/>(deny-delete)]
POLF[Policy Assignment<br/>/ Initiative]
TSF --> STKF
STKF --> DEN
end
BD -.->|maps to| TSF
BA -.->|maps to| STKF
BL -.->|maps to| DEN
INV --> EXT --> CONV --> POL --> TS --> STK --> VAL --> CUT
CUT --> STKF
How to drive a migration (step-by-step instructions for the AI)
For each step, (a) explain to the user what you're about to do, (b) ask any missing inputs, (c) produce the command or artifact, (d) wait for the user to run it and report results before moving on.
Step 1 — Inventory existing Blueprints
Ask for the management group ID and subscription ID, then produce:
Get-AzBlueprint -ManagementGroupId "<mg-id>" | Select-Object Name, Id, Versions
Get-AzBlueprintAssignment -SubscriptionId "<sub-id>"
For each blueprint, capture: definition ID, latest published version, scopes assigned, assignment parameter values, lock mode, identity.
Step 2 — Export the Blueprint definition
$bp = Get-AzBlueprint -ManagementGroupId "<mg-id>" -Name "<blueprint-name>" -LatestPublished
Export-AzBlueprintWithArtifact -Blueprint $bp -OutputPath ".\exports\<blueprint-name>"
Output is blueprint.json plus one JSON file per artifact. Confirm the export folder structure with the user before continuing.
Step 3 — Convert artifacts to Bicep (or keep as ARM)
For each template artifact:
- Save the embedded template to a
.json file.
- Decompile to Bicep (recommended):
bicep decompile .\template.json. Decompiled output is a starting point — review and refactor it, since it is not always idiomatic.
- Combine related artifacts into a single
main.bicep, or keep modular with module references.
- Preserve the same parameters at the top level (
@description, @allowed, defaults).
For RBAC artifacts: add Microsoft.Authorization/roleAssignments resources with a deterministic guid() name.
For resource-group artifacts: model as Microsoft.Resources/resourceGroups at subscription scope, or skip if the target RG already exists.
Step 4 — Decouple policy assignments
- Shared baseline → publish as an Azure Policy Initiative at the MG and assign once. The Stack/template should not re-assign baseline policies.
- App-specific policy → keep inside the Bicep, assign at resource-group scope so it doesn't conflict with broader inheritance.
Warn the user: removing the Blueprint assignment later will remove any policies embedded in it. Re-assign decoupled policies before removing the Blueprint assignment.
Step 5 — Publish a Template Spec
New-AzTemplateSpec `
-ResourceGroupName "rg-templatespecs" `
-Name "landing-zone" `
-Version "1.0.0" `
-Location "eastus" `
-TemplateFile ".\main.bicep"
This is the versioned, shareable, RBAC-scoped artifact that replaces the Blueprint definition as the package.
Step 6 — Deploy via a Deployment Stack
# Retrieve the Template Spec version resource ID
$ts = Get-AzTemplateSpec -ResourceGroupName "rg-templatespecs" -Name "landing-zone" -Version "1.0.0"
New-AzSubscriptionDeploymentStack `
-Name "landing-zone-stack" `
-Location "eastus" `
-TemplateSpecId $ts.Versions[0].Id `
-TemplateParameterFile ".\params.json" `
-DenySettingsMode "denyDelete" `
-ActionOnUnmanage "detachAll"
Decision points to surface to the user:
-DenySettingsMode → none | denyDelete | denyWriteAndDelete. Map to the old lock mode (see mapping table below).
-ActionOnUnmanage → controls what happens to resources when you delete the stack, or when a resource drops out of the template. Use detachAll during pilot; switch to deleteResources for full-lifecycle parity with a Blueprint assignment delete.
- For management-group scope use
New-AzManagementGroupDeploymentStack instead.
Note — What-If: Deployment stacks do not yet support a native What-If preview. To preview changes, run New-AzSubscriptionDeployment -WhatIf (or az deployment sub what-if) against the underlying template before creating or updating the stack. The stack additionally applies the deny-settings, which won't appear in the template What-If.
Step 7 — Validate in non-production
Deploy to a sandbox subscription first. Confirm with the user:
- Resources created as expected.
- Deny-settings enforced (try a manual delete — it should fail).
- Parameter values applied correctly.
- Diff against the original Blueprint assignment: any drift?
Step 8 — Cut over
For each existing Blueprint assignment:
- Deploy the matching Deployment Stack to the same scope.
- Choose one strategy and confirm with the user:
- Side-by-side then swap — Stack provisions new resources, redirect dependents, then remove old Blueprint-managed resources.
- Adopt existing — the stack begins managing resources whose IDs match resources declared in the template on first successful deployment (there is no separate import command). Resources at the scope that are not in the template are left untouched under
detachAll.
- Re-assign any decoupled policies at the right scope.
- Remove the Blueprint assignment:
Remove-AzBlueprintAssignment -Name "<assignment>" -SubscriptionId "<sub>"
- Confirm the Stack is now the single source of truth:
Get-AzSubscriptionDeploymentStack.
Sequencing gotcha — embedded role/policy assignments. While the Blueprint assignment still exists, it owns the role and policy assignments it created. If your Stack template tries to create a role assignment for the same principal + role + scope, Azure rejects it with 409 RoleAssignmentExists; re-creating an embedded policy under a new name silently produces a duplicate. Removing the Blueprint assignment does not reliably delete the role assignments it created — they often persist and keep triggering 409. The most reliable pattern is to adopt the existing assignments: query the existing name (Get-AzRoleAssignment, or the REST role-assignments list filtered by principalId) and set that exact GUID as the resource name so the deployment is an idempotent no-op the stack then manages.
Step 9 — Cleanup
Once all assignments for a Definition are migrated, delete the definition. Note: Az.Blueprint has no Remove-AzBlueprint cmdlet (only Remove-AzBlueprintAssignment). Delete definitions via Azure CLI or REST, deleting published versions first:
# Azure CLI
az blueprint delete --name "<blueprint-name>" --management-group "<mg-id>" # or --subscription "<sub-id>"
# REST fallback (PowerShell) — published versions first, then the definition
$path = "/subscriptions/<sub-id>/providers/Microsoft.Blueprint/blueprints/<name>" # or /providers/Microsoft.Management/managementGroups/<mg-id>/providers/Microsoft.Blueprint/blueprints/<name>
$api = "api-version=2018-11-01-preview"
(Invoke-AzRestMethod -Method GET -Path "$path/versions?$api").Content |
ConvertFrom-Json | Select-Object -Expand value |
Where-Object { -not [string]::IsNullOrWhiteSpace($_.name) } | # never issue a DELETE with an empty version ID
ForEach-Object { Invoke-AzRestMethod -Method DELETE -Path "$path/versions/$($_.name)?$api" }
Invoke-AzRestMethod -Method DELETE -Path "${path}?$api"
Deleting a management-group-scoped definition requires Blueprint Contributor/Owner at that management group — a subscription-level role returns 403. Stop publishing new versions of the Blueprint Definition.
Mapping reference
| Blueprint setting | Stack equivalent |
|---|
properties.parameters | -TemplateParameterFile / -Parameter |
properties.resourceGroups | Microsoft.Resources/resourceGroups in Bicep |
locks.mode = AllResourcesDoNotDelete | DenySettingsMode = denyDelete |
locks.mode = AllResourcesReadOnly | DenySettingsMode = denyWriteAndDelete |
locks.excludedPrincipals | -DenySettingsExcludedPrincipal (max 5) |
locks.excludedActions | -DenySettingsExcludedAction (max 200) |
Identity (SystemAssigned / UserAssigned) | Stack runs with the caller's identity; deployments use the template's own identity blocks |
| Artifact sequence | Bicep dependsOn |
| Versioning (definition versions) | Template Spec version |
| Assignment scope (Sub / MG) | New-AzSubscriptionDeploymentStack / New-AzManagementGroupDeploymentStack |
Guardrails — things the AI must do
- Surface the disclaimer before any destructive step. Before generating
Remove-AzBlueprintAssignment, az blueprint delete, any REST DELETE against Microsoft.Blueprint, or any deployment stack operation using -ActionOnUnmanage deleteResources, explicitly remind the user that the operation is irreversible, that they are responsible for verifying scope and taking backups/exports first, and that this guidance is provided as is, without warranty (see Legal notices and disclaimers).
- Never assert that output is validated, approved, or supported by Microsoft. Present generated commands as suggestions the user must review and test. Do not state or imply an SLA, support commitment, compliance certification, or guarantee of any date or outcome.
- Do not generate or run any
Remove-AzBlueprintAssignment command until the user confirms the replacement Stack is deployed and validated, and any decoupled policies are re-assigned.
- Do not recommend
denyWriteAndDelete unless the user explicitly needs write-protection — it blocks normal RBAC-allowed updates. Default to denyDelete.
- Do not recommend
-ActionOnUnmanage deleteResources during pilot. Use detachAll until the user is confident.
- Do not invent management group IDs, subscription IDs, blueprint names, or parameter values. Ask.
- Do not claim Microsoft will auto-migrate. It will not. This is customer-driven.
- Do not skip the policy-decoupling step if the blueprint embeds policy assignments. This is the #1 source of post-migration regressions.
Common pitfalls
- Trying to one-shot adopt existing resources. Stacks track resources they create or that already match resources declared in the template; other pre-existing resources may need a brief side-by-side period.
- Forgetting to update policy ownership. If a Blueprint assigned policy that lived inside the definition, removing the assignment also removes that policy. Re-assign at the right scope before removing the Blueprint assignment.
- Wrong deny-settings mode.
denyWriteAndDelete blocks normal RBAC-allowed updates — pick denyDelete unless you truly need write protection.
ActionOnUnmanage = deleteResources during pilot. Use detachAll until you're confident; flip later.
- Deny-assignment limits and gaps. Deny-assignments don't apply at management-group scope (only when a stack deploys into a child subscription), don't cover data-plane operations, and don't protect implicitly created child resources (for example, an AKS node resource group). Add explicit
Microsoft.Authorization/locks where those gaps matter.
- Blueprint-applied tags get stripped. Blueprints stamp managed resources/resource groups with a
Blueprint tag (and similar metadata). A migrated Stack whose template omits those tags will remove them on first deployment (visible as a ~ Modify in template What-If). Carry over any tags you want to keep into the converted Bicep, or accept their removal deliberately.
- Role assignment
409 / duplicate policy on cutover. See the sequencing gotcha in Step 8 — defer embedded role/policy assignments until after the Blueprint assignment is removed, or adopt them by exact existing name.
- Inherited governance noise. At resource-group scope you may see many inherited management-group policy assignments. Don't mistake them for the blueprint's own artifacts when validating.
Remove-AzBlueprint doesn't exist. Az.Blueprint ships Remove-AzBlueprintAssignment but no cmdlet to delete a definition. Use az blueprint delete or REST DELETE (see Step 9); delete published versions first. MG-scoped deletes need MG-level permissions or they return 403.
- Unassigned definitions still count. The retirement recommendation lists every definition and version, not just assignments — and the same test definitions are often replicated across every subscription and the management group. Inventory each scope and archive/convert then delete them to reach zero.
Output artifacts the AI should produce
By the end of a migration session, the user should have:
- Inventory list — definitions, assignments, scopes, lock modes, parameters.
- Export folder per blueprint —
blueprint.json + artifact JSON files.
- Converted Bicep templates —
main.bicep per migrated definition.
- Template Spec resource(s) — published and versioned.
- Deployment Stack(s) — deployed at the correct scope with the right
denySettings.
- Decoupled policy assignments / initiatives — assigned at the appropriate MG/sub/RG scope.
- Cutover checklist — one row per former Blueprint assignment, with status: deployed / validated / cut over / Blueprint removed.
FAQ
Q: Do I have to use Stacks? Can I just keep using Template Spec deployments?
A: Yes, for stateless deployments. But you lose lifecycle tracking and deny-protection. Use Stacks when you used Blueprint assignments for governance.
Q: What about Deployment Stacks at the management-group scope?
A: Supported (New-AzManagementGroupDeploymentStack). This is the right replacement for MG-scoped Blueprint assignments that fan out to many subs. Note that deny-assignments apply at the child-subscription scope the stack deploys into, not at the management-group scope itself.
Q: Will Microsoft auto-migrate my Blueprints?
A: No. Migration is customer-driven — there is no automatic conversion. Use this guide to migrate on your own timeline before retirement.
Q: What happens on the retirement dates?
A: Phased retirement begins July 31, 2026, and the service is fully retired January 31, 2027 — after which create/update operations stop and definitions/assignments are no longer serviced. Export definitions and complete migration before then. See https://aka.ms/AzureBlueprintsRetirement.
Q: I only have unassigned blueprint definitions left. Do those need migrating?
A: Yes — the retirement recommendation counts every definition and published version. If a definition has no assignment it deploys nothing, so either convert it to a Template Spec (if you still want the template) or simply export it for archive and delete it. Deleting definitions (and their versions) is what clears them from the retirement recommendation.
Q: Where do I file questions or issues?
A: Use the public Azure/azure-blueprints GitHub repository and the official retirement notice on Microsoft Learn.
Resources
Skill version: 2.2 · Published by Microsoft as MIT-licensed sample content — see Legal notices and disclaimers. Provided "AS IS" with no warranty, SLA, or support commitment. Verify all commands against the latest Microsoft Learn documentation, and test in a non-production subscription, before running.