Detach and delete resources from a deployment stack
Changes continue with the deposits application. The team decided to remove resources from the application. Some of the resources need to continue to exist in Azure, while others are safe to delete. You need to learn more about how Azure handles resources that a deployment stack no longer manages.
In this unit, you learn how to use control how Azure handles resources detached from a deployment stack using the action on unmanage parameter.
Note
The commands in this unit are shown to illustrate concepts. Don't run the commands yet. You'll practice what you learn here soon.
Action on unmanage revisited
With deployment stacks, the action on unmanage parameter is used to control how Azure handles detached resources, resource groups, and management groups. You can set the action on unmanage parameter when creating, modifying, or deleting a deployment stack. All three operations have the ability to set the behavior of the action on unmanage parameter. Keep in mind that the value set last takes precedence.
There are three possible values for the --action-on-unmanage
parameter:
deleteAll
- deletes resources, resource groups, and management groupsdeleteResources
- deletes resources, but detaches resource groups and management groupsdetachAll
- detaches all resources, resource groups, and management groups
There are three possible values for the -ActionOnUnmanage
parameter:
DeleteAll
- deletes resources, resource groups, and management groupsDeleteResources
- deletes resources, but detaches resource groups and management groupsDetachAll
- detaches all resources, resource groups, and management groups
Detach a managed resource
A detached resource, also known as an unmanaged resource, is a resource that is no longer tracked or managed by a deployment stack, but the resource still exists in Azure. The default behavior of deployment stacks is to detach resources rather than delete. For example, you might need to keep the resource so that you can use it in another deployment stack in the future, or you might need to manually verify that its data is safe to delete.
There are two values of the action on unmanage parameter that set resources, resource groups, and management groups to detach when the deployment stack no longer manages them.
Deployment stacks can't delete Key vault secrets. If you're removing key vault secrets from a template, make sure to also execute the deployment stack update/delete command with detach mode.
deleteResources
- deletes resources, but detaches resource groups and management groupsdetachAll
- detaches all resources, resource groups, and management groups
Using either deleteResources
or detachAll
when creating, modifying, or deleting your deployment stacks offers some additional protection against accidental deletion. Consider our scenario from the last unit. We added an existing Log Analytics workspace to our deployment stack. The workspace is used by other applications, not just the deposits application. It needs to persist past the life of the application. By using detachAll
as the action on unmanage parameter, needed resources continue to exist in Azure.
DeleteResources
- deletes resources, but detaches resource groups and management groupsDetachAll
- detaches all resources, resource groups, and management groups
Using either DeleteResources
or DetachAll
when creating, modifying, or deleting your deployment stacks offers some additional protection against accidental deletion. Consider our scenario from the last unit. We added an existing Log Analytics workspace to our deployment stack. The workspace is used by other applications, not just the deposits application. It needs to persist past the life of the application. By using DetachAll
as the action on unmanage parameter, needed resources continue to exist in Azure.
Let's consider our Bicep file from the last unit. The template file defines an app service plan, a web app, an Azure SQL server and database, a Log Analytics workspace, and an Application Insights instance. Let's say that we need to remove the Log Analytics workspace and Application Insights instance we created in the last unit. We edit our Bicep file, removing the highlighted code that references our web app.
// Parameters
@description('The location for all resources.')
param location string = 'eastus'
@description('The name of the SQL database.')
param sqlDatabaseName string = 'sqldb-${uniqueString(resourceGroup().id)}'
@description('The password of the admin user.')
param sqlServerAdminUserName string
@description('The name of the admin user.')
@secure()
param sqlServerAdminPassword string
@description('The name of the SQL server.')
param sqlServerName string = 'sql-${uniqueString(resourceGroup().id)}'
@description('The name of the web application.')
param webApplicationName string = 'webapp-${uniqueString(resourceGroup().id)}'
// Variables
@description('The name of the Application Insights instance.')
var applicationInsightsName = 'appinsights-deposits'
@description('The name of the app service plan.')
var appServicePlanName = 'plan-deposits'
@description('The name of the Log Analytics Workspace.')
var logAnalyticsWorkspaceName = 'log-deposits'
// Resource - App Service Plan
resource appServicePlan 'Microsoft.Web/serverfarms@2023-12-01' = {
name: appServicePlanName
location: location
sku: {
name: 'S1'
capacity: 1
}
}
// Resource - Web App
resource webApplication 'Microsoft.Web/sites@2023-12-01' = {
name: webApplicationName
location: location
properties: {
serverFarmId: appServicePlan.id
siteConfig: {
appSettings: [
{
name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
value: applicationInsights.properties.InstrumentationKey
}
]
}
}
}
// Resource - SQL Server
resource sqlServer 'Microsoft.Sql/servers@2021-11-01' ={
name: sqlServerName
location: location
properties: {
administratorLogin: sqlServerAdminUserName
administratorLoginPassword: sqlServerAdminPassword
}
}
// Resource - SQL Database
resource sqlServerDatabase 'Microsoft.Sql/servers/databases@2021-11-01' = {
parent: sqlServer
name: sqlDatabaseName
location: location
sku: {
name: 'Standard'
tier: 'Standard'
}
}
// Resource - Log Analytics Workspace
resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2023-09-01' = {
name: logAnalyticsWorkspaceName
location: location
properties: {
retentionInDays: 30
sku: {
name: 'PerGB2018'
}
}
}
// Resource - Application Insights
resource applicationInsights 'Microsoft.Insights/components@2020-02-02' = {
name: applicationInsightsName
location: location
kind: 'web'
properties: {
Application_Type: 'web'
WorkspaceResourceId: logAnalyticsWorkspace.id
}
}
To apply the changes, we need to update the deployment stack. To update a deployment stack using Azure CLI, use the az stack group create
command.
az stack group create \
--name stack-deposits \
--resource-group rg-depositsApplication \
--template-file ./main.bicep \
--action-on-unmanage detachAll \
--deny-settings-mode none
After the update operation is complete, the deployment stack no longer manages the Log Analytics workspace and Application Insights instance. In our command, we used --action-on-unmanage detachAll
to specify how Azure handles resources that a deployment stack no longer manages. In this case, the resources are detached from the deployment stack, but they still exist in the resource group.
To apply the changes, we need to update the deployment stack. To update a deployment stack using Azure PowerShell, use the Set-AzResourceGroupDeploymentStack
command.
Set-AzResourceGroupDeploymentStack `
-Name stack-deposits `
-ResourceGroupName rg-depositsApplication `
-TemplateFile ./main.bicep `
-ActionOnUnmanage DetachAll `
-DenySettingsMode None
After the update operation is complete, the deployment stack no longer manages the Log Analytics workspace and Application Insights instance. In our command, we used -ActionOnUnmanage DetachAll
to specify how Azure handles resources that a deployment stack no longer manages. In this case, the resources are detached from the deployment stack, but they still exist in the resource group.
Delete a managed resource
Deployment stacks provide for reliable resource cleanup. When you update or delete a deployment stack, you can also delete the managed resources, resource groups, and management groups. There are two values of the action on unmanage parameter that set resources, resource groups, and management groups to delete when the deployment stack no longer manages them.
deleteAll
- deletes resources, resource groups, and management groupsdeleteResources
- deletes resources, but detaches resource groups and management groups
Consider our deposits application. Let's say that the development team decides to use an Azure Database for PostgreSQL instead of Azure SQL Database. We need to first update our deployment stack to remove and fully delete the Azure SQL server and database from Azure. To accomplish this behavior, use the deleteAll
or deleteResources
action on unmanage parameter when updating or deleting the deployment stack.
DeleteAll
- deletes resources, resource groups, and management groupsDeleteResources
- deletes resources, but detaches resource groups and management groups
Consider our deposits application. Let's say that the development team decides to use an Azure Database for PostgreSQL instead of Azure SQL Database. We need to first update our deployment stack to remove and fully delete the Azure SQL server and database from Azure. To accomplish this behavior, use the DeleteAll
or DeleteResources
action on unmanage parameter when updating or deleting the deployment stack.
Let's consider our Bicep file from the previous section. The template file defines an app service plan, a web app, and an Azure SQL server and database. Let's say that we need to remove the Azure SQL server and database. We edit our Bicep file, removing the highlighted code that references our web app.
// Parameters
@description('The location for all resources.')
param location string = 'eastus'
@description('The name of the SQL database.')
param sqlDatabaseName string = 'sqldb-${uniqueString(resourceGroup().id)}'
@description('The password of the admin user.')
param sqlServerAdminUserName string
@description('The name of the admin user.')
@secure()
param sqlServerAdminPassword string
@description('The name of the SQL server.')
param sqlServerName string = 'sql-${uniqueString(resourceGroup().id)}'
@description('The name of the web application.')
param webApplicationName string = 'webapp-${uniqueString(resourceGroup().id)}'
// Variables
@description('The name of the app service plan.')
var appServicePlanName = 'plan-deposits'
// Resource - App Service Plan
resource appServicePlan 'Microsoft.Web/serverfarms@2023-12-01' = {
name: appServicePlanName
location: location
sku: {
name: 'F1'
capacity: 1
}
}
// Resource - Web App
resource webApplication 'Microsoft.Web/sites@2023-12-01' = {
name: webApplicationName
location: location
properties: {
serverFarmId: appServicePlan.id
}
}
// Resource - SQL Server
resource sqlServer 'Microsoft.Sql/servers@2021-11-01' ={
name: sqlServerName
location: location
properties: {
administratorLogin: sqlServerAdminUserName
administratorLoginPassword: sqlServerAdminPassword
}
}
// Resource - SQL Database
resource sqlServerDatabase 'Microsoft.Sql/servers/databases@2021-11-01' = {
parent: sqlServer
name: sqlDatabaseName
location: location
sku: {
name: 'Standard'
tier: 'Standard'
}
}
We're left with the following code in our file:
// Parameters
@description('The location for all resources.')
param location string = 'eastus'
@description('The name of the web application.')
param webApplicationName string = 'webapp-${uniqueString(resourceGroup().id)}'
// Variables
@description('The name of the app service plan.')
var appServicePlanName = 'plan-deposits'
// Resource - App Service Plan
resource appServicePlan 'Microsoft.Web/serverfarms@2023-12-01' = {
name: appServicePlanName
location: location
sku: {
name: 'F1'
capacity: 1
}
}
// Resource - Web App
resource webApplication 'Microsoft.Web/sites@2023-12-01' = {
name: webApplicationName
location: location
properties: {
serverFarmId: appServicePlan.id
}
}
To apply the changes, we need to update the deployment stack. To update a deployment stack using Azure CLI, use the az stack group create
command. This time, we use --action-on-unmanage deleteAll
instead of --action-on-unmanage detachAll
az stack group create \
--name stack-deposits \
--resource-group rg-depositsApplication \
--template-file ./main.bicep \
--action-on-unmanage deleteAll \
--deny-settings-mode none
After the update operation is complete, the only resources that remain are the app service plan and web app. In our command, we used --action-on-unmanage deleteAll
to specify how Azure handles resources that the deployment stack no longer manages. In this case, the resources are deleted from the deployment stack and from Azure.
To apply the changes, we need to update the deployment stack. To update a deployment stack using Azure PowerShell, use the Set-AzResourceGroupDeploymentStack
command.
Set-AzResourceGroupDeploymentStack `
-Name stack-deposits `
-ResourceGroupName rg-depositsApplication `
-TemplateFile ./main.bicep `
-ActionOnUnmanage DeleteAll `
-DenySettingsMode None
After the update operation is complete, the only resources that remain are the app service plan and web app. In our command, we used -ActionOnUnmanage DeleteAll
to specify how Azure handles resources that the deployment stack no longer manages. In this case, the resources are deleted from the deployment stack and from Azure.