This chapter covers Azure Deployment Stacks, a powerful resource lifecycle management feature introduced to simplify the creation, updating, and deletion of groups of Azure resources as a single unit. For the AZ-104 exam, deployment stacks appear under Objective 3.4 (Manage resources) and typically account for 5-8% of questions, often in scenario-based items where you must choose between deployment stacks, Azure Blueprints, or Resource Manager templates. Mastering deployment stacks is critical because they offer a cleaner alternative to manual resource group management and provide built-in deny settings to prevent accidental modifications. By the end of this chapter, you will understand the internal mechanisms, configuration steps, and exam-specific nuances of deployment stacks.
Jump to a section
Imagine you are a construction project manager overseeing the building of a new office complex. You have a master blueprint that includes everything: foundation, framing, electrical, plumbing, and finishing. Instead of ordering materials and contractors piecemeal, you create a 'stack' — a bundle of all the blueprints, material lists, and subcontractor assignments. When you hand this stack to a general contractor, they execute the entire build. If you later decide to add a wing or change the roofing, you update the stack and re-apply it. The contractor compares the new stack to the current state of the building and applies only the differences — adding, modifying, or removing parts as needed. If you want to demolish the entire building, you simply delete the stack, and the contractor tears everything down in the right order. The stack is not the building itself; it is the plan that manages the building's lifecycle. In Azure, a deployment stack works the same way: it is a resource that wraps an ARM template (the blueprint) and manages the lifecycle of all resources it provisions. When you update the stack, Azure calculates the delta and applies changes. When you delete the stack, you can opt to delete all managed resources — a clean teardown. This prevents resource sprawl and ensures consistent state management across environments.
What is an Azure Deployment Stack?
An Azure Deployment Stack is a resource that acts as a container for an ARM template (or Bicep file) and manages the lifecycle of all Azure resources defined in that template. Unlike a direct template deployment, which creates resources but leaves them orphaned (no parent link to the deployment), a deployment stack maintains an active association with the resources it creates. This allows you to update the stack (which updates resources), delete the stack (which can optionally delete all managed resources), and lock resources against accidental modification.
Deployment stacks are scoped to a resource group, subscription, or management group. They were introduced in late 2022 and are now the recommended approach for managing infrastructure-as-code deployments at scale.
Why Deployment Stacks Exist
Before deployment stacks, Azure administrators had two primary ways to deploy infrastructure:
Direct ARM template deployments: These created resources but left no management relationship. To update, you had to redeploy the template. To delete, you had to manually delete each resource or the entire resource group.
Azure Blueprints: These provided governance and compliance but were heavy, required a subscription-level scope, and had limitations (e.g., no support for certain resource types like Azure Policy assignments at management group scope).
Deployment stacks fill the gap: they provide a lightweight, scoped, and manageable wrapper for template deployments. They are particularly useful for:
Managing shared services (e.g., a hub VNet, firewall, and bastion host)
Deploying and updating application environments (dev, test, prod)
Enforcing compliance by denying modifications to critical resources
How Deployment Stacks Work Internally
When you create a deployment stack, Azure does the following: 1. Stores the template (ARM JSON or Bicep file) and parameters in the stack resource. 2. Evaluates the template to determine the set of resources to create. 3. Deploys the resources using the same mechanism as a standard ARM deployment (resource provider calls). 4. Records the resource IDs in the stack's managedResources property. 5. Applies deny settings (if configured) to the managed resources via Azure RBAC deny assignments.
When you update the stack (e.g., change a parameter or template), Azure: 1. Compares the desired state (new template) with the current state (existing resources). 2. Calculates the difference: resources to add, modify, or delete. 3. Performs the operations in the correct order (respecting dependencies). 4. Updates the managedResources list.
When you delete the stack, you have two options:
Detach: The stack is deleted, but the resources remain (orphaned).
Delete: The stack and all managed resources are deleted in dependency order.
Key Components, Values, and Defaults
Stack Resource Properties:
- name: Unique within the scope.
- location: Azure region where the stack metadata is stored (not the resources themselves).
- template: The ARM template or Bicep file (specified inline or via URI).
- parameters: Template parameters.
- actionOnUnmanage: Determines behavior when a resource is no longer in the template. Options: detach (default) or deleteAll.
- denySettings: Controls deny assignments. Options:
- denySettingsMode: none, denyDelete, denyWriteAndDelete.
- denySettingsExcludedActions: List of actions to exclude from deny.
- denySettingsExcludedPrincipals: List of AAD principals excluded.
- denySettingsApplyToChildScopes: Boolean (default false).
Default values:
- actionOnUnmanage: detach — if you remove a resource from the template, it is detached (not deleted) by default. To delete unmanaged resources, you must explicitly set actionOnUnmanage to deleteAll.
- denySettingsMode: none — no deny assignments are applied unless you specify a mode.
Important timers: - Deployment stack operations are synchronous within the Azure Resource Manager. There is no specific timeout; it follows the standard ARM deployment timeout (usually 1 hour per resource, but overall can be up to 2 hours).
Configuration and Verification Commands
Deployment stacks can be managed via Azure CLI, Azure PowerShell, or the Azure portal. The exam focuses on CLI and PowerShell.
Azure CLI:
Create a stack at resource group scope:
az stack group create \
--name MyStack \
--resource-group MyRG \
--template-file template.json \
--parameters params.json \
--deny-settings-mode DenyDelete \
--action-on-unmanage deleteAllList stacks:
az stack group list --resource-group MyRGShow stack details:
az stack group show --name MyStack --resource-group MyRGUpdate a stack (modify template or parameters):
az stack group create \
--name MyStack \
--resource-group MyRG \
--template-file new-template.json \
--parameters new-params.json \
--deny-settings-mode DenyDelete \
--action-on-unmanage detachDelete a stack (with resource deletion):
az stack group delete --name MyStack --resource-group MyRG --action-on-unmanage deleteAllAzure PowerShell:
Create a stack:
New-AzResourceGroupDeploymentStack `
-Name MyStack `
-ResourceGroupName MyRG `
-TemplateFile template.json `
-TemplateParameterFile params.json `
-DenySettingsMode DenyDelete `
-ActionOnUnmanage DeleteAllGet stack:
Get-AzResourceGroupDeploymentStack -Name MyStack -ResourceGroupName MyRGRemove stack (with resource deletion):
Remove-AzResourceGroupDeploymentStack -Name MyStack -ResourceGroupName MyRG -ActionOnUnmanage DeleteAllInteraction with Related Technologies
Azure Policy: Deployment stacks can be used in conjunction with Azure Policy. Policy can audit or enforce that resources are created only via stacks. Deny settings on stacks provide an additional layer of protection, but they are not a replacement for Azure Policy (which is broader and can enforce compliance across subscriptions).
Azure Blueprints: Blueprints are deprecated in favor of deployment stacks. Blueprints were subscription-scoped and included artifacts like policies and role assignments. Deployment stacks are more flexible (any scope) and simpler. However, Blueprints are still on the exam, so know the difference: Blueprints are for governance (compliance), stacks are for lifecycle management.
Resource Groups: A deployment stack can be created at the resource group scope, but it is not tied to the resource group's lifecycle. Deleting the resource group does not delete the stack; you must delete the stack separately. Conversely, deleting the stack does not delete the resource group (only the managed resources).
Deny Assignments: When you enable deny settings on a stack, Azure creates deny assignments (read-only from the portal) that block specified operations. These assignments are visible via Azure CLI: az role assignment list --scope <resource-id> --include-inherited. Deny assignments are inherited by child resources if denySettingsApplyToChildScopes is true.
Common Pitfalls
Forgetting to set `actionOnUnmanage`: By default, removing a resource from the template only detaches it, not deletes it. This can lead to resource sprawl.
Overlapping deny settings: If you apply deny settings to a resource that also has Azure Policy deny effects, both apply. The most restrictive wins.
Stack name uniqueness: Stack names must be unique within the scope (resource group, subscription, or management group).
Template size limit: The template file must be under 4 MB (same as ARM template limit).
Plan the Stack Scope
Determine the appropriate scope for the deployment stack: resource group, subscription, or management group. Resource group scope is most common for application workloads. Subscription scope is used for shared infrastructure (e.g., hub VNet, Azure Firewall). Management group scope is for organization-wide resources like policy assignments or role assignments. The scope determines where the stack resource is stored and which resources it can manage. For example, a subscription-scoped stack can manage resources in any resource group within that subscription. Choose the scope based on the resources you need to manage and the isolation requirements.
Define the Template and Parameters
Create an ARM template (JSON) or Bicep file that declares the desired Azure resources. The template must be idempotent — deploying it multiple times should produce the same result. Parameters allow you to customize the deployment for different environments (dev, test, prod). Use parameters for settings like SKU sizes, locations, and naming prefixes. The template is stored inline in the stack (up to 4 MB) or referenced via a URI (e.g., from a storage account). For exam scenarios, remember that the template is evaluated at deployment time, not stored as a separate artifact.
Create the Deployment Stack
Use Azure CLI, PowerShell, or portal to create the stack. Specify the name (unique within scope), template, parameters, deny settings mode, and action on unmanage. During creation, Azure deploys all resources defined in the template. The stack resource itself is created in the same region as the scope (for resource group scope, the stack region is the resource group's region). The resources can be in any region, independent of the stack region. After creation, the stack's 'managedResources' property lists all resource IDs. Verify with `az stack group show`.
Update the Stack as Needed
To update resources, modify the template or parameters and run the create command again (the stack is updated in place). Azure calculates the difference between the desired state (new template) and the current state (existing resources). It then performs create, update, or delete operations on the managed resources. For example, if you add a new subnet to a VNet template, Azure will create that subnet. If you change a VM size, Azure will resize the VM. If you remove a resource from the template, Azure will either detach it (default) or delete it, depending on the `actionOnUnmanage` setting. The update is atomic within the stack — either all changes succeed or the stack rolls back (though rollback is not automatic; you must redeploy the previous template).
Delete the Stack and Clean Up
When you no longer need the resources, delete the stack. You have two choices: `detach` (default) removes the stack but leaves all managed resources orphaned — they still exist but are no longer managed by the stack. `deleteAll` removes both the stack and all managed resources in dependency order. For example, if the stack managed a VNet and a VM, the VM is deleted first, then the VNet. This is a powerful feature for cleaning up entire environments. Be careful: if you choose `deleteAll`, all resources are permanently deleted. You can also delete individual managed resources manually, but the stack will then show them as 'unmanaged' until you update the stack to remove them from the template.
Enterprise Scenario 1: Shared Services Hub Deployment
A large enterprise manages multiple application teams, each with their own subscriptions. The central cloud team deploys a shared hub VNet with Azure Firewall, VPN gateway, and a bastion host in a central subscription. They use a deployment stack at subscription scope to manage these resources. The stack template includes the VNet, subnets, firewall rules, and gateway configuration. Deny settings are set to DenyDelete to prevent accidental deletion of critical network components. When a new subnet is needed, the team updates the template and re-runs the stack. When a firewall rule changes, they modify the template and update the stack. The stack ensures consistency: if someone manually deletes a subnet, the stack detects the drift and recreates it on the next update. In production, this stack manages 50+ resources across 3 resource groups. The team uses actionOnUnmanage set to deleteAll so that if they remove a resource from the template (e.g., an old test subnet), it is automatically deleted. The main challenge is managing deny settings: if a developer needs to temporarily disable a firewall rule for troubleshooting, they must be added to the excluded principals list.
Enterprise Scenario 2: Multi-Environment Application Deployment
A SaaS company deploys their application in three environments: dev, test, and prod. Each environment consists of an App Service plan, a SQL Database, a storage account, and a Key Vault. They create a deployment stack per environment at the resource group scope. The template is parameterized with environment-specific values (e.g., SKU, backup retention). The stacks use denySettingsMode of DenyWriteAndDelete in prod to prevent any manual changes. The CI/CD pipeline updates the stacks automatically when code changes are merged. The pipeline uses az stack group create with the --action-on-unmanage detach setting so that if a resource is temporarily removed from the template (e.g., during a migration), it is not deleted. The team monitors stack status using Azure Monitor alerts on stack deployment failures. A common issue is stack update failures due to resource conflicts (e.g., a SQL database cannot be renamed). In such cases, the pipeline rolls back by redeploying the previous template.
Scenario 3: Compliance-Driven Resource Management
A financial services company must ensure that all resources in a management group comply with internal policies. They use a management group-scoped deployment stack to deploy mandatory resources like Log Analytics workspaces, Azure Policy assignments, and role assignments. The stack template includes the policies and workspaces. Deny settings are set to DenyDelete to prevent removal of audit logs. The stack is updated quarterly as compliance requirements change. The cloud center of excellence (CCoE) team is the only group with permissions to modify the stack. Application teams are excluded from deny settings via denySettingsExcludedPrincipals so they can write data to the Log Analytics workspace. The main challenge is that management group-scoped stacks can only manage resources at that scope (e.g., policy assignments) and cannot manage resources in child subscriptions directly. This limitation requires careful planning of what goes into the stack versus what is deployed separately.
AZ-104 Exam Focus: Deployment Stacks
Deployment stacks are tested under Objective 3.4 (Manage resources), specifically sub-objective 'Manage resource groups and deployment stacks'. Expect 2-3 questions on the exam. The questions are scenario-based, asking you to choose the best approach for a given situation.
Common Wrong Answers and Why
Choosing Azure Blueprints over deployment stacks for simple lifecycle management. Candidates pick Blueprints because they are familiar from older exam versions. However, Blueprints are deprecated and deployment stacks are the modern equivalent. The exam will test scenarios where you need to deploy and update a set of resources — stacks are the correct answer.
Selecting 'detach' as the action when deleting a stack and expecting resources to be deleted. Candidates confuse detach with deleteAll. The default is detach, which leaves resources orphaned. The exam will ask: 'You delete a stack. What happens to the resources?' The correct answer depends on the actionOnUnmanage setting at deletion time. If not specified, detach is used.
Assuming deny settings on a stack prevent all modifications. Deny settings only block the specific actions defined in the mode. DenyDelete prevents deletes but allows writes. DenyWriteAndDelete prevents both. Candidates may think that DenyDelete also prevents writes. Also, deny settings do not block actions by excluded principals or actions listed in excludedActions.
Thinking a deployment stack creates a new resource group. The stack itself does not create a resource group; it deploys resources into an existing resource group (or subscription/management group). Candidates may mistakenly think the stack creates a resource group automatically.
Specific Numbers and Terms
Deny settings modes: none, denyDelete, denyWriteAndDelete. Know the exact strings.
Action on unmanage: detach (default), deleteAll.
Scope options: resource group, subscription, management group.
Template size limit: 4 MB.
Stack name uniqueness: Unique within the scope.
Edge Cases and Exceptions
Stack update with removed resources: If you remove a resource from the template and actionOnUnmanage is detach, the resource remains but is no longer managed. If you then update the stack again, Azure does not delete the detached resource. To delete it, you must either set actionOnUnmanage to deleteAll or manually delete the resource and update the stack.
Deny settings and Azure Policy: Both can apply. The most restrictive permission wins. If a policy denies write and the stack denies delete, both are enforced.
Stack at management group scope: Can only manage resources at that scope (e.g., policy assignments, role assignments). It cannot manage resources in child subscriptions.
Stack deletion with `deleteAll`: Resources are deleted in dependency order. If a resource cannot be deleted (e.g., due to a lock), the stack deletion fails and resources remain.
How to Eliminate Wrong Answers
Identify the scope needed: If the question mentions managing resources across multiple resource groups in a subscription, the stack must be at subscription scope. If it's within a single resource group, use resource group scope.
Check for lifecycle requirements: If the question asks for easy update and deletion of a group of resources, deployment stack is the answer. If it asks for compliance and policy enforcement, consider Azure Policy or Blueprints (though Blueprints are deprecated).
Look for deny settings keywords: If the question mentions preventing accidental deletion of resources, look for denySettingsMode set to DenyDelete or DenyWriteAndDelete.
Notice the action on unmanage: If the question says 'resources should be automatically deleted when removed from the template', choose deleteAll.
Eliminate options that mention Blueprints if the scenario is purely about resource lifecycle, not governance.
Deployment stacks provide lifecycle management for groups of Azure resources defined in an ARM template or Bicep file.
Stacks can be scoped to a resource group, subscription, or management group.
When you delete a stack, you can choose to detach resources (default) or delete all managed resources by setting `actionOnUnmanage` to `deleteAll`.
Deny settings on stacks (DenyDelete or DenyWriteAndDelete) prevent accidental modifications via deny assignments.
Updating a stack recalculates the delta and applies changes incrementally — no need to delete and recreate.
Stack names must be unique within their scope.
Azure Blueprints are deprecated; deployment stacks are the modern alternative for resource lifecycle management.
Deny settings do not affect excluded principals or actions listed in `excludedActions`.
Stacks cannot manage resources outside their scope (e.g., a resource group stack cannot manage resources in another resource group).
The template size limit for a deployment stack is 4 MB.
These come up on the exam all the time. Here's how to tell them apart.
Deployment Stack
Lightweight; scoped to resource group, subscription, or management group.
Manages resource lifecycle (create, update, delete) with deny settings.
Uses ARM templates or Bicep files directly.
Supports incremental updates (delta calculation).
Recommended for modern IaC deployments; Blueprints are deprecated.
Azure Blueprint
Heavy; scoped only to subscription or management group.
Focuses on governance (compliance, policy, role assignments).
Uses artifacts (templates, policies, role assignments) in a blueprint definition.
Versioned and published; updates require new version.
Deprecated in favor of deployment stacks and other tools.
Deployment Stack with DenyDelete
Blocks delete operations on managed resources.
Can exclude specific principals or actions.
Applied via deny assignments; can be inherited to child scopes.
Does not block write operations (if mode is DenyDelete only).
Managed automatically by the stack; removed when stack is deleted.
Resource Lock (Read-Only)
Blocks all operations (read-only) or delete only (CanNotDelete).
Cannot exclude principals; applies to all users.
Applied at resource or resource group level; not inherited by default.
Blocks write operations if set to ReadOnly.
Must be manually set and removed.
Mistake
Deployment stacks replace Azure Resource Manager templates entirely.
Correct
Deployment stacks are a wrapper around ARM templates. They do not replace templates; they use templates to define resources and add lifecycle management features like deny settings and bulk deletion.
Mistake
Deleting a deployment stack always deletes the managed resources.
Correct
By default, deleting a stack detaches the resources (they remain). To delete resources, you must specify `actionOnUnmanage` as `deleteAll` at deletion time.
Mistake
Deny settings on a deployment stack prevent all modifications to managed resources.
Correct
Deny settings only block the actions specified by the mode (e.g., `DenyDelete` blocks delete, `DenyWriteAndDelete` blocks write and delete). They do not block read operations or actions by excluded principals.
Mistake
A deployment stack can only be created at the resource group scope.
Correct
Deployment stacks can be created at resource group, subscription, or management group scope, providing flexibility to manage resources at different levels.
Mistake
Updating a deployment stack always requires deleting and recreating it.
Correct
You can update a stack by running the create command again with a new template or parameters. Azure calculates the delta and applies changes incrementally.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
A standard ARM template deployment creates resources but does not maintain a management relationship. After deployment, the resources are orphaned — there is no parent resource that tracks them. In contrast, a deployment stack is a resource that wraps the template and maintains a list of managed resources. This allows you to update the stack (which updates resources), delete the stack (which can delete resources), and apply deny settings. Stacks also support incremental updates by calculating the delta between the desired and current state.
Yes, if the stack is scoped to a subscription or management group. A subscription-scoped stack can manage resources in any resource group within that subscription. A management group-scoped stack can manage resources at that scope (e.g., policy assignments) but cannot manage resources in child subscriptions directly. A resource group-scoped stack can only manage resources within that specific resource group.
Deny settings use Azure RBAC deny assignments to block specific operations on managed resources. There are three modes: `none` (no deny), `denyDelete` (blocks delete operations), and `denyWriteAndDelete` (blocks both write and delete). You can exclude specific AAD principals or actions from the deny. Deny assignments are inherited by child resources if `denySettingsApplyToChildScopes` is set to true. Deny settings are independent of resource locks; both can be applied simultaneously.
By default, deleting a stack uses the `detach` action. The stack resource is removed, but all managed resources remain in your Azure subscription. They become orphaned — no longer managed by any stack. You can later delete them manually or reattach them to a new stack. To delete the resources along with the stack, you must explicitly set `actionOnUnmanage` to `deleteAll` when running the delete command.
Yes. When you update a stack by running the create command with a new template or parameters, Azure compares the desired state (new template) with the current state (existing resources). It calculates the difference and performs only the necessary create, update, or delete operations. This is similar to the incremental mode of ARM template deployments. For example, if you add a new subnet to a VNet template, only that subnet is created.
Yes, deployment stacks are available in the Azure portal under the resource group, subscription, or management group blade. You can create, view, update, and delete stacks from the portal. However, the exam focuses on CLI and PowerShell commands. The portal provides a visual interface but the same underlying operations.
You can view the managed resources using Azure CLI: `az stack group show --name MyStack --resource-group MyRG --query managedResources`. In the portal, the stack's overview blade lists the managed resources. The stack's `managedResources` property contains an array of resource IDs.
You've just covered Azure Deployment Stacks — now see how well it sticks with free AZ-104 practice questions. Full explanations included, no account needed.
Done with this chapter?