Azure / Azure/azure-rest-api-specs
[BUG] MG-scope deployments: DeploymentMode.Complete is accepted by the contract but rejected by ARM ("not supported for deployment at the current scope")
- Dominant language
- TypeSpec
- Stars
- 3.1k
- Forks
- 5.9k
- Avg merge
- 2d 22h
- Merged PRs (30d)
- 444
Description
### API Spec link
https://github.com/Azure/azure-rest-api-specs/blob/main/specification/resources/resource-manager/Microsoft.Resources/deployments/models.tsp
### API Spec version
2025-04-01
### Describe the bug
The `Microsoft.Resources/deployments` spec exposes `DeploymentMode` with two values — `Incremental` and `Complete` — and the management-group-scope PUT operation (`/providers/Microsoft.Management/managementGroups/{groupId}/providers/Microsoft.Resources/deployments/{deploymentName}`) takes a body of type `ScopedDeployment`, whose `properties` references the shared `DeploymentProperties` model. That makes `Complete` look like a valid mode for an MG-scope deployment in every generated client (CLI, SDKs) and in the published REST reference docs.
In practice, ARM rejects `Complete` at MG / subscription / tenant scope at runtime with:
```
{
"code": "InvalidDeployment",
"message": "Specified deployment mode 'Complete' is not supported for deployment at the current scope. Please see https://aka.ms/deployment-modes for usage details."
}
```
So the spec/runtime contract is mismatched: clients let users build a request the service will never accept.
Relevant TSP definitions (file [`models.tsp`](https://github.com/Azure/azure-rest-api-specs/blob/main/specification/resources/resource-manager/Microsoft.Resources/deployments/models.tsp)):
```typespec
enum DeploymentMode {
Incremental,
Complete,
}
model ScopedDeployment {
location: string;
properties: DeploymentProperties; // <-- shared with RG-scope; carries `mode`
tags?: Record;
}
model DeploymentProperties {
// ...
mode: DeploymentMode; // <-- accepts Complete at all scopes
// ...
}
```
The same mismatch is also visible in the `Microsoft.Resources/deployments` REST docs at https://learn.microsoft.com/rest/api/resources/deployments/create-or-update-at-management-group-scope where both modes are advertised.
Worth noting up front: per https://aka.ms/deployment-modes, **Complete mode is being deprecated** in favor of [deployment stacks](https://learn.microsoft.com/azure/azure-resource-manager/bicep/deployment-stacks) (which support deletion via `actionOnUnmanage`).
**Suggested fix:**
1. Update the `mode` property description on `DeploymentProperties` to call out that `Complete` is only supported at resource-group scope.
2. Mark `DeploymentMode.Complete` with `@deprecated` (or equivalent doc note) and link to the deployment-stacks alternative.
### Expected behavior
Either:
1. The contract documents the per-scope constraint (e.g., the `mode` property description on `DeploymentProperties` states that `Complete` is only valid at resource-group scope), so generated clients and REST reference docs reflect what ARM actually accepts; OR
2. The contract structurally narrows the allowed values at non-RG scopes (e.g., a `ScopedDeploymentProperties` model where `mode` is restricted to `Incremental`).
Given Complete mode is being deprecated per https://aka.ms/deployment-modes, option (1) plus an `@deprecated` marker on `DeploymentMode.Complete` (or equivalent description note) is likely sufficient and minimizes API surface churn.
### Actual behavior
- Spec accepts `mode: "Complete"` at MG scope (no schema-level validation error from `swagger-tools` / generated clients).
- REST reference docs at https://learn.microsoft.com/rest/api/resources/deployments/create-or-update-at-management-group-scope advertise both modes.
- ARM service rejects it at runtime with `InvalidDeployment` / "not supported for deployment at the current scope".
Sub-scope and tenant-scope deployments suffer the same runtime constraint, but they're less visible because the CLI doesn't surface a `--mode` flag for `az deployment sub create` / `az deployment tenant create` at all. The contract still allows `Complete` there for direct REST callers and SDK users.
### Reproduction Steps
Reproduced today against current ARM, Azure CLI 2.85.0:
```powershell
# Minimal MG-scope template
@'
{
"$schema": "https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": []
}
'@ | Out-File -Encoding utf8 mg-empty.json
# Validate / what-if PASS — the contract accepts Complete
az deployment mg create `
--management-group-id `
--location westus `
--template-file mg-empty.json `
--mode Complete `
--name modecheck-001 `
--what-if
# -> "Resource changes: no change." (no contract-level rejection)
# Real PUT FAILS — ARM rejects at runtime
az deployment mg create `
--management-group-id `
--location westus `
--template-file mg-empty.json `
--mode Complete `
--name modecheck-002
# -> ERROR: {"code": "InvalidDeployment", "message": "Specified deployment mode 'Complete' is not supported for deployment at the current scope. ..."}
```
Same behavior reported in upstream issue https://github.com/Azure/azure-cli/issues/26873 (open since 2023).
### Environment
Azure CLI: 2.85.0
ARM API version tested: 2025-04-01
Scope reproduced: management-group
Date reproduced: 2026-05-20
Contributor guide
Research direction
Start in specification/resources/resource-manager/Microsoft.Resources/deployments/models.tsp and inspect DeploymentMode, DeploymentProperties, and ScopedDeployment. Update the contract documentation so Complete is identified as valid only at resource-group scope and document its deprecation in favor of deployment stacks. Verify the generated REST reference descriptions and relevant TypeSpec validation or generation checks.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- azure
- Domain
- api, cloud
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100