Skip to content
Get Started for Free

Resource Manager

Azure Resource Manager (ARM) is the unified deployment and management layer for Azure resources, providing a consistent control-plane API for resource organization and lifecycle management. It enables idempotent, declarative infrastructure as code (IaC) through JSON-based ARM templates and Bicep modules, allowing for automated resource group orchestration and provider registrations.

For more information, see:

LocalStack for Azure enables seamless interaction with the emulator’s management REST API via Azure Resource Manager. It also provides native support for Bicep and ARM templates, allowing for standardized Infrastructure as Code (IaC) deployments within your local environment. The supported APIs are available on our API Coverage section, which provides information on the extent of Resource Manager’s integration with LocalStack.

This guide is designed for users new to Resource Manager and assumes basic knowledge of the Azure CLI and our lstk az proxy.

Launch LocalStack using your preferred method. For more information, see Introduction to LocalStack for Azure. Once the container is running, enable Azure CLI interception by running:

Terminal window
lstk az start-interception

This command points the az CLI away from the public Azure management REST API and toward the LocalStack for Azure emulator API. To revert this configuration, run:

Terminal window
lstk az stop-interception

This reconfigures the az CLI to send commands to the official Azure management REST API.

Create a resource group:

Terminal window
az group create \
--name rg-resources-demo \
--location westeurope
Output
{
"name": "rg-resources-demo",
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-resources-demo",
"location": "westeurope",
"properties": {
"provisioningState": "Succeeded"
},
"..."
}

Get the resource group details:

Terminal window
az group show --name rg-resources-demo
Output
{
"name": "rg-resources-demo",
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-resources-demo",
"location": "westeurope",
"properties": {
"provisioningState": "Succeeded"
},
"..."
}

List matching resource groups:

Terminal window
az group list --query "[?name=='rg-resources-demo']"
Output
[
{
"name": "rg-resources-demo",
"location": "westeurope",
"..."
}
]

Get a specific provider:

Terminal window
az provider show --namespace Microsoft.Resources
Output
{
"namespace": "Microsoft.Resources",
"registrationState": "Registered",
"registrationPolicy": "RegistrationFree",
"resourceTypes": [
{
"resourceType": "resourceGroups",
"apiVersions": ["2023-07-01", "..."],
"..."
}
...
],
"..."
}

List provider registration state:

Terminal window
az provider list --query "[?namespace=='Microsoft.Resources'].{namespace:namespace,registrationState:registrationState}"
Output
[
{
"namespace": "Microsoft.Resources",
"registrationState": "Registered"
}
]

Create a Bicep file named main.bicep that provisions a storage account inside the resource group:

param location string = resourceGroup().location
param storageAccountName string = 'stbicep${uniqueString(resourceGroup().id)}'
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-05-01' = {
name: storageAccountName
location: location
sku: {
name: 'Standard_LRS'
}
kind: 'StorageV2'
}
output storageAccountId string = storageAccount.id

Deploy the template into the resource group:

Terminal window
az deployment group create \
--resource-group rg-resources-demo \
--template-file main.bicep
Output
{
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-resources-demo/providers/Microsoft.Resources/deployments/main",
"name": "main",
"properties": {
"correlationId": "...",
"mode": "Incremental",
"provisioningState": "Succeeded",
"outputResources": [
{
...
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-resources-demo/providers/Microsoft.Storage/storageAccounts/..."
}
],
"outputs": {
"storageAccountId": {
"type": "String",
"value": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-resources-demo/providers/Microsoft.Storage/storageAccounts/..."
}
},
"..."
},
"type": "Microsoft.Resources/deployments",
"..."
}

Verify the deployment status:

Terminal window
az deployment group show \
--resource-group rg-resources-demo \
--name main
Output
{
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-resources-demo/providers/Microsoft.Resources/deployments/main",
"name": "main",
"properties": {
"correlationId": "...",
"mode": "Incremental",
"provisioningState": "Succeeded",
...
},
"type": "Microsoft.Resources/deployments",
"..."
}

The Resource Manager emulator supports the following features:

  • Resource group lifecycle: Create, update, get, list, delete, and check existence of resource groups. Deletion cascades to all contained resources.
  • Resource listing and filtering: List resources across a subscription or within a resource group, with support for $filter and $expand query parameters.
  • Resource move: Move top-level resources between resource groups with validation of source and destination groups, resource locks, and resource hierarchy.
  • ARM template deployments: Create or update deployments at the resource group scope and at the subscription scope. Templates are parsed and resources are provisioned in dependency order.
  • Bicep support: Bicep files compiled by the Azure CLI are accepted as ARM JSON templates. The emulator handles Bicep 2.0 symbolic names, languageVersion, and user-defined types: definitions referenced through $ref, including chains and pointers into a definition, with the constraints they declare. These are the features Azure Verified Modules rely on; the virtual network and virtual machine modules are tested against the emulator.
  • Nested deployments: Inner-scoped and outer-scoped nested templates (Microsoft.Resources/deployments) are supported, including parameter passing between scopes.
  • ARM template functions: Over 60 built-in functions are evaluated locally, including resourceId, reference, listKeys, concat, format, uniqueString, resourceGroup, subscription, copyIndex, if, union, createObject, tryGet, shallowMerge, and the lambda functions map, filter, reduce, sort, toObject, groupBy, and mapValues. Function names are case-insensitive, and if evaluates only the branch it takes.
  • Template validation: A deployment request is validated before anything is deployed, as on Azure, and so is a deployments validate request at the resource group and subscription scopes. Parameter values are checked against their declared type and constraints (allowedValues, minValue, maxValue, minLength, maxLength, object properties and nullable, additionalProperties, discriminated unions, prefixItems, and items), a required parameter must have a value, an undeclared parameter is rejected, and every $ref must resolve. A violation returns the InvalidTemplate error Azure returns, naming the parameter and the broken constraint. A parameter given null takes its default value.
  • Copy loops and conditional resources: The copy element is supported for resources, variables, and outputs, and the condition property for resources and outputs, enabling iterative resource creation and conditional deployment logic.
  • Deployment operations: List deployment operations at the resource group scope and at the subscription scope, including provisioning state and target resource details.
  • Deployment outputs: Template outputs are evaluated once the deployment completes, with full ARM expression resolution. An output computed during the deployment whose value does not match its declared type or constraints fails the deployment with DeploymentOutputEvaluationFailed, as on Azure, and an output whose condition is false is not returned.
  • Secure parameters: The values of secureString and secureObject parameters and outputs are never returned by a deployment, which reports their type only, as on Azure.
  • Subscription management: List and get subscriptions, and list available Azure locations with metadata.
  • Tenant listing: List tenant identifiers associated with the emulator environment.
  • Provider registry: List, get, register, and unregister resource providers, including resource type details, API versions, and zone mappings.
  • Resource group locks: Lock and unlock resource groups to prevent accidental deletion or modification of contained resources.
  • Single subscription: The emulator exposes a single subscription. Multiple subscriptions are not supported.
  • No management group or tenant-scoped deployments: Deployments are supported only at the resource group and subscription scopes.
  • No what-if analysis: The az deployment group what-if operation is not implemented.
  • ARM template function coverage: The emulator does not evaluate cidrHost, cidrSubnet, parseCidr, dataUri, dataUriToString, deployer, distinct, indexFromEnd, tryIndexFromEnd, like, references, roleDefinitions, listOutputsWithSecureValues (which Bicep uses to read a module’s secure outputs), or Bicep user-defined functions. A resource whose expression calls one of them fails with an error that names the function.
  • Failed deployment errors in Azure SDK pollers: A deployment does not expose the Azure-AsyncOperation status endpoint that Azure SDK pollers read, so a poller that ends on a failed deployment raises an error that does not carry the deployment’s error code and message. Read them from the error property of the deployment, for example with az deployment group show.
  • No resource tags on generic resource listings: Tags and extended properties may not be fully populated when listing resources across a subscription.
  • RBAC enforcement on resource operations is opt-in: By default, all API calls succeed without role-based access control checks. Set LS_AZURE_ENFORCE_RBAC to enable control-plane checks across ARM resource types; see Role Assignment: Enabling RBAC enforcement.
  • Deployment concurrency: Resources within a single deployment are created sequentially with dependency resolution, not in full parallel as in Azure.
  • No deployment cancellation: Running deployments cannot be cancelled.
  • No deployment deletion: Deployments are retained in memory and cannot be explicitly deleted via the API.

The following samples demonstrate how to use Azure Resource Manager and Bicep with LocalStack for Azure:

48 of 157 operations implemented

Operation ▲Implemented ▼
Page 1 of 0
Was this page helpful?