[BUG] MG-scope deployments: DeploymentMode.Complete is accepted by the contract but rejected by ARM ("not supported for deployment at the current scope")
bug
### 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<string>;
}
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 <YourMG> `
--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 <YourMG> `
--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
0 条评论