---
cuppy_hub: azure
cuppy_path: guides/bicep/deploy-bicep.md
cuppy_section: docs
cuppy_doc: RKED-DQ1C
cuppy_doc_uuid: 3796c871-01d5-47a2-a775-61345aaa73aa
cuppy_permalink: https://cuppy.io/azure/d/RKED-DQ1C
cuppy_version: 1
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/azure/docs/guides/bicep/deploy-bicep
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: 858e3a74a60d89d3b68684e390c9c0a881e2b52509312a7298675939b0a757c6
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---


# Deploy a Bicep file at the right scope

**A Bicep file deploys to one scope, declared by `targetScope` (default `resourceGroup`), with the matching command.** Anything at another scope goes through a module with `scope:`. Then: compile, preview, deploy, all in incremental mode.

## 1. Scope and command

| `targetScope` | Command | Typical contents |
|---|---|---|
| `'resourceGroup'` (default) | `az deployment group create --resource-group <rg>` | Most resources |
| `'subscription'` | `az deployment sub create --location <loc>` | Resource groups, subscription policy and role assignments |
| `'managementGroup'` | `az deployment mg create --management-group-id <mg> --location <loc>` | Policy and RBAC across subscriptions |
| `'tenant'` | `az deployment tenant create --location <loc>` | Management groups |

For non-group scopes, `--location` is where the **deployment record** is stored, not where resources go. Reusing a deployment name with another location fails (`InvalidDeploymentLocation`). Deploying a resource that belongs to another scope directly fails at compile time, for example `BCP135: Scope "resourceGroup" is not valid for this resource type. Permitted scopes: "subscription".`

## 2. A subscription-scope file that creates its group, then deploys into it

```bicep
targetScope = 'subscription'

param location string = 'eastus2'
param name string = 'orders'

resource rg 'Microsoft.Resources/resourceGroups@2025-04-01' = {
  name: 'rg-${name}'
  location: location
}

module storage 'storage.bicep' = {
  scope: rg
  params: {
    location: location
    prefix: name
  }
}

output storageId string = storage.outputs.id
```

```bicep
// storage.bicep (targetScope defaults to resourceGroup)
param location string
param prefix string

resource sa 'Microsoft.Storage/storageAccounts@2026-06-01' = {
  name: take('st${prefix}${uniqueString(resourceGroup().id)}', 24)
  location: location
  sku: { name: 'Standard_LRS' }
  kind: 'StorageV2'
  properties: {
    minimumTlsVersion: 'TLS1_2'
    allowBlobPublicAccess: false
  }
}

output id string = sa.id
```

`uniqueString(resourceGroup().id)` gives a stable, globally unlikely name. `take(…, 24)` keeps it inside the storage name limit.

**Pick API versions Bicep has types for.** The newest REST API version isn't always in the Bicep CLI's type library: storage `2026-09-01` is in the REST specs, but Bicep 0.48.1 has no types for it and warns `BCP081 … does not have types available` (no property checking at all). Use the newest version that compiles without BCP081, here `2026-06-01`.

## 3. Parameters in a `.bicepparam` file

```bicep
using './main.bicep'

param location = 'eastus2'
param name = 'orders'
```

Pass it with `--parameters main.bicepparam`. Parameter files are plain text, so never put secrets in them. Read a secret at deploy time instead: `param adminPassword = getSecret('<sub-id>', '<rg>', '<vault>', '<secret>')` (or `kv.getSecret('<secret>')` in a `.bicep` file for a `@secure()` module parameter). That needs the vault's `enabledForTemplateDeployment: true` and, for the deployer, `Microsoft.KeyVault/vaults/deploy/action` (included in Owner and Contributor).

## 4. Compile, validate, preview, deploy

```
bicep build main.bicep                     # BCP errors and warnings, with line and column
az deployment sub validate --location eastus2 --template-file main.bicep --parameters main.bicepparam
az deployment sub what-if  --location eastus2 --template-file main.bicep --parameters main.bicepparam
az deployment sub create   --location eastus2 --template-file main.bicep --parameters main.bicepparam \
  --name orders-$(date +%Y%m%d%H%M) --confirm-with-what-if
```

- **`--validation-level`** (CLI 2.76+): `Provider` (default, includes permission checks), `ProviderNoRbac` (checks only read permission: useful for a reviewer identity), `Template` (syntax only).
- **What-if limits:** it doesn't expand `templateLink` (linked templates and template specs), stops expanding after 800 resource groups, and since CLI 2.75 reports what it couldn't analyze ("short-circuiting"). Treat an `Ignore` or unanalyzed entry as unknown, not as "no change".
- **`--confirm-with-what-if` / `-c`** shows the preview and asks before deploying: right for humans. In CI, run `what-if` as its own step and review it.

## 5. What incremental mode really does

- Incremental (the default) leaves resources **not in the file** alone. That's why it's safe.
- **For resources that are in the file, every property is reapplied, not merged.** A property you leave out goes back to its default.
- Define subnets in the VNet's `subnets` array, not as separate child resources, or a redeploy of the VNet removes them. Web app settings live in the `Microsoft.Web/sites/config` child.
- **Complete mode** deletes everything in the group that isn't in the file, and Microsoft is gradually deprecating it. To delete resources as part of a deployment, use a deployment stack (`reference/arm/deployment-stacks.md`).

## 6. Reference what already exists

```bicep
resource kv 'Microsoft.KeyVault/vaults@2026-05-15' existing = {
  name: 'kv-orders'
  scope: resourceGroup('rg-shared')
}

output vaultUri string = kv.properties.vaultUri
```

Reference resources by **symbol** (`kv.id`, `sa.properties.primaryEndpoints.blob`) rather than building `resourceId()` strings: the symbol creates the dependency, and a string doesn't. Names and IDs must be computable at the start of the deployment. Using a runtime property as a `name` fails with `BCP120`.

## Next

Failures: `guides/arm/debug-failed-deployment.md`. Compiler messages: `reference/bicep/compile-errors.md`. Making redeploys idempotent: `patterns/bicep-idempotent-redeploy.md`.


---
<!-- cuppy -->
You are reading one file. The same content is free over MCP at https://cuppy.io/mcp with no signup: ranked search across all 107 documents in this hub, the merged view when you work in a layer, known workarounds matched to the error you hit, and depth control so you spend tokens on what you need. Start with the `_hello` tool. How to connect: https://cuppy.io/azure/ Something wrong in this document? Report it with the `session feedback` tool on the same endpoint.
<!-- /cuppy -->
