Resource groups and locks
A resource group is the container every Azure resource lives in, and a management lock stops a resource or group from being deleted until someone removes the lock. On the Azure platform each unit owns its own resource group, and the resources that would be expensive or impossible to rebuild carry a CanNotDelete lock.
What it does
A resource group collects resources that share a lifecycle. Deleting the group deletes everything in it, role assignments can be made at the group, and cost views can be filtered by it. A management lock is set on a subscription, group or resource. CanNotDelete allows reads and changes but refuses every delete, for every principal including Owners, and a lock on a group protects everything inside it. Removing a lock needs Microsoft.Authorization/locks/delete, which Owner and User Access Administrator carry and Contributor does not.
How BuiltForProd uses it
One group per unit. Every module that creates resources creates its own resource group: 26 in the Baseline modules, 10 in the Web App Blueprint and 3 in the Data and ETL Blueprint. Names follow root.hcl's name_prefix ({namespace}-{environment}-{stage}) plus the unit's purpose, such as acme-eus2-prd-kv-publish-rg, acme-eus2-security-observability-rg or acme-eus2-prd-aks-rg. The group is therefore the unit's scope for a lock, a role assignment or a cost filter, and a unit's resources never mix with another's. The one exception to the pattern is NetworkWatcherRG, which the subscription baseline creates under Azure's conventional name. Every repository generates its provider with prevent_deletion_if_contains_resources = true, so OpenTofu will not delete a group that still holds a resource it does not manage.
Locks in the Baseline. The units that hold state, evidence or shared foundations put a CanNotDelete lock on their resource group (the contract vault on the vault itself):
| Locked | Unit | Subscription |
|---|---|---|
| State backend group | state-backend | acme-core-root |
| Baseline group of every subscription | subscription-baseline | all 14 |
| Audit workspace, audit storage, audit key | audit-workspace, audit-storage, audit-cmk | acme-core-audit |
| Security workspace and action group | observability-sink | acme-core-security |
| SOPS key vault | sops-keys | acme-core-security |
| Hub, spoke and runner virtual networks | vnet-hub, vnet-spoke, vnet-runner | acme-core-network, plat, acme-core-auto |
| Private DNS zones; public DNS zones | private-dns; dns-zones | acme-core-network; acme-core-dns |
| Container registry; metastore storage | acr; uc-metastore | acme-core-artifacts |
| CI platform vault | platform-kv | acme-core-auto |
| Contract vault | kv-publish | each plat subscription |
Most lock notes say the same thing: removal needs an activated Privileged Identity Management role, because of the groups in the access matrix only Owner can lift it (standing Owner while PIM is off). The audit trail has a second layer: the audit-protection initiative of Azure Policy denies deleting the audit workspace, the audit storage and any diagnostic setting, whatever the locks say.
Locks in the blueprints. The blueprints switch their locks per stage with delete_locks. In the Web App Blueprint it locks the application vault, the Cosmos DB for MongoDB vCore cluster and the Managed Redis cache; in the Data and ETL Blueprint the lake and Databricks workspace groups. Both stack files set it to true in prod and false in dev and staging, so lower stages can be torn down and rebuilt freely.
Terms you will see
| Term | Meaning |
|---|---|
| Resource group | The lifecycle and access container of a unit's resources. |
name_prefix | {namespace}-{environment}-{stage}, such as acme-eus2-prd; starts every name. |
CanNotDelete | The lock level that refuses deletes and allows every other operation. |
delete_locks | The blueprints' per-stage switch for locks on their data and secrets. |
NetworkWatcherRG | The one group named by Azure's convention instead of the prefix. |
Where to read more
- Azure Enterprise Baseline overview for where each unit runs.
- Azure Web App Blueprint overview and Data and ETL Blueprint overview for the locked data stores.
- Recoverable for how locks fit the platform's recovery guarantees.