Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Azure Developer CLI (azd) supports layered provisioning, which you can use to define multiple provisioning layers in your azure.yaml file. Each layer points to its own set of Infrastructure as Code (IaC) templates. The CLI provisions layers sequentially in the order you define them. You can also provision or tear down individual layers independently.
This feature solves complex dependency scenarios where resources in one layer depend on resources from another layer. Instead of mixing IaC with imperative hook scripts, layered provisioning keeps everything declarative.
Note
Layered provisioning is currently a beta feature. Learn more about the versioning strategy.
When to use layered provisioning
Use layered provisioning when a single azd provision deployment can't handle all of your infrastructure needs in one step. Consider using layered provisioning when:
- Circular dependencies: Some resources need to reference other resources that must be created first, such as a virtual network that must exist before a private endpoint can be configured.
- Foundational infrastructure differs from application infrastructure: You manage shared networking, security, or identity resources separately from per-application resources.
- Independent lifecycle management is needed: You update and tear down different infrastructure components at different times. For example, a networking layer might be long-lived, while an application layer is frequently redeployed.
- Monorepo projects with distinct infrastructure groups: A single repository contains multiple independent services (such as an Event Hub, a Container App, and a Function App), each with its own infrastructure templates.
Configure layers in azure.yaml
Define layers under the infra section of your azure.yaml file. Each layer requires a name and a path pointing to the directory that contains the IaC templates for that layer.
name: my-app
infra:
layers:
- name: networking
path: ./infra/networking
- name: application
path: ./infra/application
services:
api:
project: ./src/api
language: js
host: containerapp
Important
Layer processing order: azd provision processes layers top to bottom in the order they're listed in azure.yaml. azd down processes layers in reverse order (bottom to top). Define your layers so that foundational resources appear first, followed by layers that depend on them. This order ensures you create dependencies before the resources that need them, and remove dependencies after those resources.
Layer properties
Each layer supports the following properties:
| Property | Required | Description |
|---|---|---|
name |
Yes | A unique name for the layer. Use this name when targeting a specific layer with commands. |
path |
Yes | The relative path to the directory containing the IaC templates for this layer. |
module |
No | The name of the module within the layer's directory. Defaults to main. |
provider |
No | The IaC provider for this layer (bicep or terraform). Inherits from the root infra.provider if you don't specify it. |
Important
When you define infra.layers, you can't declare other properties on the infra section (path, module, deploymentStacks) at the root level. You must specify all infrastructure configuration within each layer.
Directory structure
A typical project using layered provisioning might have the following directory structure:
my-app/
├── azure.yaml
├── infra/
│ ├── networking/
│ │ └── main.bicep
│ └── application/
│ └── main.bicep
└── src/
└── api/
└── ...
Each layer directory contains its own complete set of IaC templates, just as a standard azd project's infra directory would.
Provision and manage layers
You can provision all layers at once or target a specific layer by name. The following sections describe common commands for provisioning, tearing down, and refreshing layer state.
Provision all layers
Run azd provision without arguments to provision all layers sequentially in the order they're defined in azure.yaml:
azd provision
azd processes each layer one at a time, ensuring the first layer completes before the second layer begins. This process guarantees that dependent resources exist before layers that reference them are deployed.
Provision a specific layer
To provision only a specific layer, pass the layer name as an argument:
azd provision networking
This command deploys only the resources defined in the networking layer. Provisioning a specific layer is useful when:
- You're iterating on a single layer during development.
- You need to update one layer without redeploying others.
- You're setting up a new layer on top of existing infrastructure.
Tear down all layers
Run azd down without arguments to tear down resources from all layers. When multiple layers exist, azd processes them in reverse order, so dependent resources are removed before the foundational resources they depend on:
azd down
Tear down a specific layer
To tear down only a specific layer, pass the layer name as an argument:
azd down application
This command removes only the resources deployed by the application layer, leaving the other layers intact.
Refresh environment state
You can refresh the environment state from a specific layer by using the --layer flag with azd env refresh:
azd env refresh --layer networking
This command updates the environment variables and outputs based on the most recent deployment of the specified layer.
Example: Monorepo with multiple services
The following example demonstrates layered provisioning for a monorepo that contains an Event Hub, a Container App running multiple containers, and an Azure Function App:
name: logging-app
infra:
layers:
- name: eventhub
path: ./infra/eventhub
- name: aca
path: ./infra/aca
- name: functionapp
path: ./infra/functionapp
services:
functionapp:
resourceName: ${site_name}
language: dotnet
project: ./src/function/functionapp.csproj
host: appservice
resourceGroup: ${rg_name}
The corresponding directory structure:
logging-app/
├── azure.yaml
├── infra/
│ ├── eventhub/
│ │ └── main.bicep
│ ├── aca/
│ │ └── main.bicep
│ └── functionapp/
│ └── main.bicep
└── src/
└── function/
└── functionapp.csproj
With this configuration, you can:
- Provision only the Event Hub infrastructure:
azd provision eventhub - Provision only the Container App infrastructure:
azd provision aca - Provision everything in order:
azd provision - Tear down only the Function App layer:
azd down functionapp
Example: Base and application layers
A common pattern separates shared or foundational infrastructure from per-application infrastructure:
name: my-app
infra:
layers:
- name: base
path: ./infra/base
- name: app
path: ./infra/app
services:
web:
project: ./src/web
language: js
host: containerapp
The base layer creates shared resources like networking, identity, and monitoring. The app layer creates the application-specific resources (such as a Container App environment and container apps) that reference the base resources.
During development, you might provision the base layer once and iterate on the application layer:
azd provision base
azd provision app
azd provision app # re-provision only the app layer after changes
Example: Mixed IaC providers
Each layer can use a different IaC provider. For example, you might use Bicep for networking and Terraform for the application layer:
name: my-app
infra:
layers:
- name: networking
path: ./infra/networking
provider: bicep
- name: application
path: ./infra/application
provider: terraform
Considerations and limitations
- When provisioning all layers,
azdprocesses them sequentially in the order you define. Plan your layer order so that foundational resources are provisioned first. - When tearing down all layers,
azdprocesses them in reverse order.- If multiple layers deploy resources into the same Azure resource group and you use the default resource-group–based deletion behavior, shared resources may be deleted when running azd down.
- To allow independent tracking and deletion of layered infrastructure, enable deployment stacks using the command
azd config set alpha.deployment.stacks onDeployment stacks allow azd to track resources per layer instead of relying solely on resource group deletion.
- You can't use the
--previewflag when provisioning multiple layers at once. Specify a<layer>name to use preview mode. - Layers operate independently in terms of IaC. To reference outputs from one layer in another layer, use environment variables that
azdsets after each layer's deployment. - All standard
azdprovisioning features (deployment state caching, hooks, parameters, Bicep, or Terraform) work within each individual layer.- Command-level hooks (for example,
preprovision,postprovision) are invoked once per layer. When multiple layers are defined, hooks run for each layer in the order layers are processed.
- Command-level hooks (for example,