Deployment Stacks, a new resource type for managing a collection of Azure resources as a single unit, is now generally available (GA). It allows for faster updates and deletions while also preventing unwanted changes to those resources.
The GA release follows last year's public preview and can be considered the follow-up of Azure Blueprints, which will be deprecated by July 2026 and never reached the GA status. The company states customers should migrate their blueprint definitions and assignments to Template Specs and Deployment Stacks.
Ryan Yates, a freelance consultant and former MVP, tweeted:
This has been a long time coming, but it's good that it's finally GA.
A deployment stack is a method of deploying ARM Templates or Bicep files, tracking resources in a "managedResources" list. Beyond the capabilities of conventional deployments, deployment stacks bring two main capabilities to Azure:
- "ActionOnUnmanage": Specifies the action to take when a managed resource becomes unmanaged, either deleting or detaching the resource.
- "DeleteResources": Deletes unmanaged resources, detaching Resource Groups and Management Groups.
Other settings include "DeleteAll," "DetachAll," "DenySettingsMode," "DenyDelete," "DenyWriteAndDelete," and "None".
A deployment stack can be created at different scopes, such as Resource Group, Subscription, and Management Group scope. To create a deployment stack, a user will need the following information:
- A main template, main.bicep or azuredeploy.json, that defines the "managedResources" to be created by the deployment stack. Think about which resources that share the same lifecycle can be defined into a deployment stack (e.g., networking resources, DevTest environments, Applications). For example, here is "mainAppInfra.bicep":
- This file deploys a storage account and a virtual network to different resource groups.
targetScope = 'subscription'
param resourceGroupName1 string = 'testapp-storage'
param resourceGroupName2 string = 'testapp-network'
param resourceGroupLocation string = deployment().location
//Create Resource Groups
resource testrg1 'Microsoft.Resources/resourceGroups@2021-01-01' = {
name: resourceGroupName1
location: resourceGroupLocation
}
resource testrg2 'Microsoft.Resources/resourceGroups@2021-01-01' = {
name: resourceGroupName2
location: resourceGroupLocation
}
//Create Storage Accounts
module firstStorage 'multistorage.bicep' = if (resourceGroupName1 == 'testapp-storage') {
name: uniqueString(resourceGroupName1)
scope: testrg1
params: {
location: resourceGroupLocation
}
}
//Create Virtual Networks
module firstVnet 'multinetwork.bicep' = if (resourceGroupName2 == 'testapp-network') {
name: uniqueString(resourceGroupName2)
scope: testrg2
params: {
location: resourceGroupLocation
}
}
Example of mainAppInfra.bicep (Source: Microsoft Tech Community blog post)
- Next, users choose the "ActionOnUnmanage" setting of "DeleteResources," "DeleteAll," or "DetachAll."
- Subsequently, the "DenySettingsMode" setting of "DenyDelete," "DenyWriteAndDelete," or "None."
- And finally, the scope of the deployment stack and the target scope of its deployment.
An Azure CLI command to create a deployment stack at subscription scope would look as follows:
az stack sub create --name "DevTestEnvStack" --template-file "mainAppInfra.bicep" --location "westus2" --action-on-unmanage "deleteResources" --deny-settings-mode "denyDelete"
Removing a resource in the template and redeploying it with the same CLI Command results in a resource that is no longer being managed, which can be observed in the "deletedResources" array property of the deployment stack response. Beyond deciding on the behavior for "actionOnUnmanage," users must also define what deny settings mode the deployment stack should use. This enables guardrails to help protect "managedResources" against unwanted changes.
Users can also view the Deployment Stack and its contents in the portal by navigating to the specified scope > settings > deployment stacks.
Google Cloud Platform (GCP) and Amazon Web Services (AWS) offer similar capabilities to Azure Deployment Stacks. With GCP, users can leverage Google Cloud Deployment Manager and Terraform as the primary tools for deploying and managing infrastructure. In contrast, with AWS, users have AWS CloudFormation, AWS CDK, and Terraform, which offer similar functionality. Note that Terraform is also an option for Azure, as it can be considered cloud platform agnostic.
Itamar Hirosh, a senior cloud Solution architect at Microsoft, concluded in a technical blog post on Deployment Stacks:
By leveraging Azure Deployment Stacks, we can effectively manage and secure our Terraform backend state storage accounts without falling into the trap of infinite state file loops. This approach not only centralizes the management of backend components but also adds an additional layer of security through deny assignments, preventing unauthorized access and modifications.
Lastly, besides the documentation, more details on Deployment Stacks are available on GitHub.