Quickstart: Create and deploy a deployment stack with Bicep

This quickstart describes how to create a deployment stack.

Prerequisites

Create a Bicep file

Create a Bicep file to create a storage account and a virtual network.

param resourceGroupLocation string = resourceGroup().location
param storageAccountName string = 'store${uniqueString(resourceGroup().id)}'
param vnetName string = 'vnet${uniqueString(resourceGroup().id)}'

resource storageAccount 'Microsoft.Storage/storageAccounts@2023-04-01' = {
  name: storageAccountName
  location: resourceGroupLocation
  kind: 'StorageV2'
  sku: {
    name: 'Standard_LRS'
  }
}

resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-11-01' = {
  name: vnetName
  location: resourceGroupLocation
  properties: {
    addressSpace: {
      addressPrefixes: [
        '10.0.0.0/16'
      ]
    }
    subnets: [
      {
        name: 'Subnet-1'
        properties: {
          addressPrefix: '10.0.0.0/24'
        }
      }
      {
        name: 'Subnet-2'
        properties: {
          addressPrefix: '10.0.1.0/24'
        }
      }
    ]
  }
}

Save the Bicep file as main.bicep.

Create a deployment stack

In this quickstart, you create the deployment stack at the resource group scope. You can also create the deployment stack at the subscription scope or the management group scope. For more information, see Create deployment stacks.

az group create \
  --name 'demoRg' \
  --location 'centralus'

az stack group create \
  --name demoStack \
  --resource-group 'demoRg' \
  --template-file './main.bicep' \
  --action-on-unmanage 'detachAll' \
  --deny-settings-mode 'none'

For more information about action-on-unmanage and deny-setting-mode, see Deployment stacks.

Verify the deployment

To list the deployed deployment stacks at the resource group level:

az stack group show \
  --resource-group 'demoRg' \
  --name 'demoStack'

The output shows two managed resources - one storage account and one virtual network:

{
  "actionOnUnmanage": {
    "managementGroups": "detach",
    "resourceGroups": "detach",
    "resources": "detach"
  },
  "debugSetting": null,
  "deletedResources": [],
  "denySettings": {
    "applyToChildScopes": false,
    "excludedActions": null,
    "excludedPrincipals": null,
    "mode": "none"
  },
  "deploymentId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/demoRg/providers/Microsoft.Resources/deployments/demoStack-24051714epybc",
  "deploymentScope": null,
  "description": null,
  "detachedResources": [],
  "duration": "PT32.5330364S",
  "error": null,
  "failedResources": [],
  "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/demoRg/providers/Microsoft.Resources/deploymentStacks/demoStack",
  "location": null,
  "name": "demoStack",
  "outputs": null,
  "parameters": {},
  "parametersLink": null,
  "provisioningState": "succeeded",
  "resourceGroup": "demoRg",
  "resources": [
    {
      "denyStatus": "none",
      "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/demoRg/providers/Microsoft.Network/virtualNetworks/vnetthmimleef5fwk",
      "resourceGroup": "demoRg",
      "status": "managed"
    },
    {
      "denyStatus": "none",
      "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/demoRg/providers/Microsoft.Storage/storageAccounts/storethmimleef5fwk",
      "resourceGroup": "demoRg",
      "status": "managed"
    }
  ],
  "systemData": {
    "createdAt": "2024-05-17T14:50:18.382948+00:00",
    "createdBy": "johndoe@contoso.com",
    "createdByType": "User",
    "lastModifiedAt": "2024-05-17T14:50:18.382948+00:00",
    "lastModifiedBy": "johndoe@contoso.com",
    "lastModifiedByType": "User"
  },
  "tags": {},
  "template": null,
  "templateLink": null,
  "type": "Microsoft.Resources/deploymentStacks"
}

You can also verify the deployment by list the managed resources in the deployment stack:

az stack group show \
  --name 'demoStack' \
  --resource-group 'demoRg' \
  --output 'json'

The output is similar to:

{
  "actionOnUnmanage": {
    "managementGroups": "detach",
    "resourceGroups": "detach",
    "resources": "detach"
  },
  "debugSetting": null,
  "deletedResources": [],
  "denySettings": {
    "applyToChildScopes": false,
    "excludedActions": null,
    "excludedPrincipals": null,
    "mode": "none"
  },
  "deploymentId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/demoRg/providers/Microsoft.Resources/deployments/demoStack-24051714epybc",
  "deploymentScope": null,
  "description": null,
  "detachedResources": [],
  "duration": "PT32.5330364S",
  "error": null,
  "failedResources": [],
  "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/demoRg/providers/Microsoft.Resources/deploymentStacks/demoStack",
  "location": null,
  "name": "demoStack",
  "outputs": null,
  "parameters": {},
  "parametersLink": null,
  "provisioningState": "succeeded",
  "resourceGroup": "demoRg",
  "resources": [
    {
      "denyStatus": "none",
      "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/demoRg/providers/Microsoft.Network/virtualNetworks/vnetthmimleef5fwk",
      "resourceGroup": "demoRg",
      "status": "managed"
    },
    {
      "denyStatus": "none",
      "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/demoRg/providers/Microsoft.Storage/storageAccounts/storethmimleef5fwk",
      "resourceGroup": "demoRg",
      "status": "managed"
    }
  ],
  "systemData": {
    "createdAt": "2024-05-17T14:50:18.382948+00:00",
    "createdBy": "johndoe@contoso.com",
    "createdByType": "User",
    "lastModifiedAt": "2024-05-17T14:50:18.382948+00:00",
    "lastModifiedBy": "johndoe@contoso.com",
    "lastModifiedByType": "User"
  },
  "tags": {},
  "template": null,
  "templateLink": null,
  "type": "Microsoft.Resources/deploymentStacks"
}

Once a stack is created, you can access and view both the stack itself and the managed resources associated with it through the Azure portal. Navigate to the resource group where the stack has been deployed, and you can access all the relevant information and settings.

Screenshot of a deployment stack in the Azure portal.

Update the deployment stack

To update a deployment stack, you can modify the underlying Bicep file and rerunning the create deployment stack command.

Edit main.bicep to change the sku name to Standard_GRS from Standard_LRS:

Run the following command:

az stack group create \
  --name 'demoStack' \
  --resource-group 'demoRg' \
  --template-file './main.bicep' \
  --action-on-unmanage 'detachAll' \
  --deny-settings-mode 'none'

From the Azure portal, check the properties of the storage account to confirm the change.

Using the same method, you can add a resource to the deployment stack or remove a managed resource from the deployment stack. For more information, see Add resources to a deployment stack and Delete managed resources from a deployment stack.

Delete the deployment stack

To delete the deployment stack, and the managed resources:

az stack group delete \
  --name 'demoStack' \
  --resource-group 'demoRg' \
  --action-on-unmanage 'deleteAll'

To delete the deployment stack, but retain the managed resources:

az stack group delete \
  --name 'demoStack' \
  --resource-group 'demoRg' \
  --action-on-unmanage 'detachAll'

For more information, see Delete deployment stacks.

The remove command exclusively removes managed resources and managed resource groups. You are still responsible for deleting the resource groups that are not managed by the deployment stack.

Clean up resources

Delete the unmanaged resource group.

az group delete \
  --name 'demoRg'

Next steps