Fundamentação Teórica: Configure Resource Locks
1. Intuição Inicial
Imagine que você tem um servidor de banco de dados crítico em produção. Você sabe que qualquer exclusão acidental desse servidor causaria uma catástrofe para o negócio. RBAC controla quem pode agir, mas um administrador legítimo com permissão de Contributor ainda poderia deletar esse servidor por engano.
O que você precisa é de uma trava física no recurso, independente de quem está tentando agir sobre ele. Algo que diga: "não importa quem você é ou quais permissões você tem, este recurso não pode ser deletado."
Isso é um Resource Lock: uma proteção que age no nível do recurso em si, bloqueando operações de exclusão ou modificação, independentemente das permissões RBAC do usuário. É o equivalente a colocar um cadeado de segurança em um equipamento crítico, onde mesmo o gerente do departamento precisa de uma chave especial para removê-lo.
2. Contexto
Onde Resource Locks se encaixam na governança Azure
Resource Locks são uma camada de proteção distinta das demais:
Resource Locks existem porque as camadas anteriores não são suficientes para proteção contra acidentes ou ações maliciosas de usuários privilegiados. Um Owner pode deletar qualquer recurso por definição do RBAC. Um Resource Lock impede isso sem precisar revogar as permissões de Owner.
O que Resource Locks protegem
- Recursos críticos de produção contra exclusão acidental
- Infraestrutura de rede central (VNets, gateways) contra modificação
- Contas de storage com dados críticos
- Key Vaults com segredos de produção
- Qualquer recurso cuja indisponibilidade ou perda causaria impacto severo
3. Construção dos Conceitos
3.1 Os dois tipos de lock
Existem exatamente dois tipos de Resource Lock, e entender a diferença entre eles é fundamental:
| Tipo | Nome no portal | Operações bloqueadas | Operações permitidas |
|---|---|---|---|
| CanNotDelete | Delete | DELETE | Leitura e modificação |
| ReadOnly | Read-only | DELETE e PUT/PATCH | Apenas GET (leitura) |
CanNotDelete protege contra exclusão, mas ainda permite que o recurso seja modificado. Um usuário pode alterar configurações, mas não deletar.
ReadOnly é muito mais restritivo: bloqueia qualquer operação que altere o estado do recurso, incluindo criação de recursos filhos. Ele transforma o recurso em somente leitura para todos, independente de permissões.
3.2 Quem pode criar e remover locks
Gerenciar Resource Locks requer uma das seguintes roles:
| Role | Pode criar locks | Pode remover locks |
|---|---|---|
| Owner | Sim | Sim |
| User Access Administrator | Sim | Sim |
| Contributor | Não | Não |
| Reader | Não | Não |
Este é um ponto crítico e contraintuitivo: Contributor não pode gerenciar locks. Um Contributor tem amplo poder de criar e modificar recursos, mas não pode colocar ou remover um lock. Isso é intencional: a proteção não pode ser removida por quem tem acesso operacional comum.
Para gerenciar locks especificamente sem conceder Owner completo, existe a built-in role Microsoft.Authorization/locks/* que cobre as operações de lock.
3.3 Herança de locks
Locks se comportam de forma similar ao RBAC em relação à herança: um lock aplicado em um nível superior afeta todos os recursos abaixo.
Se você aplica um ReadOnly no Resource Group, todos os recursos dentro dele ficam ReadOnly, independentemente de locks individuais nos recursos. Um lock no RG é mais abrangente e mais difícil de "esquecer" do que locks em recursos individuais.
3.4 Locks e recursos filhos
Um comportamento fundamental e não óbvio: um lock em um Resource Group não aparece como um lock nos recursos individuais dentro do RG. Se você acessar Access Control ou a aba Locks de uma VM dentro de um RG com lock, a VM pode não mostrar nenhum lock na sua própria lista. O lock está no RG, não na VM.
Para ver todos os locks efetivos em um recurso, você precisa verificar o recurso em si e todos os seus escopos ancestrais (RG e Subscription).
4. Visão Estrutural
Fluxo de avaliação de uma operação com locks
Quando uma operação é bloqueada por lock, o ARM retorna o erro HTTP 409 Conflict com o código ScopeLocked. Este erro é distinto de um erro 403 de RBAC (que indica falta de permissão) e informa claramente que o bloqueio é por causa de um lock, não de permissão insuficiente.
Locks vs. RBAC vs. Policy: comparação estrutural
5. Funcionamento na Prática
Comportamentos não óbvios do ReadOnly
O lock ReadOnly tem implicações que vão muito além de "não pode modificar". Alguns comportamentos surpreendentes:
1. Storage Account com ReadOnly não permite listar chaves de acesso.
A operação de listar chaves (listKeys) é classificada como uma ação POST que modifica estado (gera um recurso de credencial). Com ReadOnly, ela é bloqueada. Aplicações que dependem de listar as chaves para acessar o storage deixarão de funcionar.
2. VMs com ReadOnly não podem ser iniciadas ou paradas. Iniciar uma VM é uma operação de escrita no estado do recurso. Com um lock ReadOnly no Resource Group que contém a VM, nenhuma operação de start/stop/restart funcionará.
3. Não é possível criar recursos dentro de um Resource Group com ReadOnly. Se o RG tem ReadOnly, nenhum recurso novo pode ser criado nele, pois criar é uma operação de escrita.
4. App Services com ReadOnly no RG podem ter problemas de execução. Algumas operações internas do runtime do App Service escrevem estado. Um ReadOnly no RG pode quebrar serviços em execução, não apenas operações de gerenciamento.
Conclusão prática: Use ReadOnly com extrema cautela em recursos que precisam operar normalmente. Ele é adequado principalmente para infraestrutura estática que não precisa ser gerenciada no dia a dia.
Comportamento do CanNotDelete com recursos filhos
Quando você tenta deletar um Resource Group com lock CanNotDelete, a operação falha mesmo se não houver lock nos recursos individuais dentro do RG. O lock no RG protege contra a exclusão do próprio RG e implicitamente protege todos os recursos dentro (já que deletar o RG deletaria tudo).
No entanto, um lock CanNotDelete no RG não impede a exclusão de recursos individuais dentro dele. Para proteção completa de recursos individuais, você precisa aplicar locks nos recursos ou no RG com ReadOnly.
Múltiplos locks no mesmo escopo
É possível ter múltiplos locks em um mesmo recurso ou escopo. O lock mais restritivo prevalece. Se um recurso tem tanto um CanNotDelete quanto um ReadOnly (improvável, mas possível), o ReadOnly prevalece pois é mais restritivo.
6. Formas de Implementação
Portal do Azure
Quando usar: proteção manual de recursos críticos individuais, verificação visual rápida
Para criar um lock:
- Navegue até o recurso, Resource Group ou Subscription
- No menu lateral, clique em Locks (dentro de Settings)
- Clique em + Add
- Defina o nome, tipo (CanNotDelete ou ReadOnly) e notas opcionais
- Clique em OK
Para remover um lock:
- Acesse a mesma tela de Locks
- Clique no ícone de exclusão ao lado do lock
- Confirme a remoção
Vantagem: rápido, visual, fácil para verificação Limitação: não escala, não é reproduzível, sem controle de versão
Azure CLI
# Criar lock CanNotDelete em um Resource Group
az lock create \
--name "rg-prod-nodelete" \
--resource-group "rg-producao" \
--lock-type CanNotDelete \
--notes "Proteção contra exclusão acidental - Aprovado por: CTO"
# Criar lock ReadOnly em um Resource Group
az lock create \
--name "rg-network-readonly" \
--resource-group "rg-networking" \
--lock-type ReadOnly \
--notes "Rede de produção - não modificar sem Change Request"
# Criar lock em um recurso específico
az lock create \
--name "keyvault-prod-lock" \
--resource-group "rg-seguranca" \
--resource-type "Microsoft.KeyVault/vaults" \
--resource "kv-prod-001" \
--lock-type CanNotDelete \
--notes "Key Vault de produção - CRÍTICO"
# Criar lock em uma Subscription inteira
az lock create \
--name "sub-prod-nodelete" \
--lock-type CanNotDelete \
--scope "/subscriptions/<sub-id>" \
--notes "Subscription de produção"
# Listar locks em um Resource Group (incluindo herdados)
az lock list \
--resource-group "rg-producao" \
--output table
# Listar TODOS os locks da subscription
az lock list \
--output table
# Remover um lock (requer Owner ou User Access Administrator)
az lock delete \
--name "rg-prod-nodelete" \
--resource-group "rg-producao"
# Verificar locks em um recurso específico
az lock list \
--resource-group "rg-seguranca" \
--resource-type "Microsoft.KeyVault/vaults" \
--resource "kv-prod-001" \
--output table
Atenção: o comando
az lock listcom--resource-groupmostra os locks aplicados naquele RG e em recursos dentro dele, mas não mostra locks herdados de níveis superiores (Subscription). Para auditoria completa, inclua tambémaz lock listsem filtros para ver todos.
Azure PowerShell
# Criar lock CanNotDelete em RG
New-AzResourceLock `
-LockName "rg-prod-nodelete" `
-LockLevel CanNotDelete `
-ResourceGroupName "rg-producao" `
-Notes "Proteção contra exclusão acidental"
# Criar lock ReadOnly em RG
New-AzResourceLock `
-LockName "rg-network-readonly" `
-LockLevel ReadOnly `
-ResourceGroupName "rg-networking" `
-Notes "Rede de produção - somente leitura"
# Criar lock em recurso específico
New-AzResourceLock `
-LockName "storage-critical-lock" `
-LockLevel CanNotDelete `
-ResourceGroupName "rg-dados" `
-ResourceName "stgcritico01" `
-ResourceType "Microsoft.Storage/storageAccounts" `
-Notes "Storage com dados de backup"
# Listar todos os locks em um RG
Get-AzResourceLock -ResourceGroupName "rg-producao"
# Listar locks em um recurso específico
Get-AzResourceLock `
-ResourceGroupName "rg-seguranca" `
-ResourceName "kv-prod-001" `
-ResourceType "Microsoft.KeyVault/vaults"
# Remover lock
Remove-AzResourceLock `
-LockName "rg-prod-nodelete" `
-ResourceGroupName "rg-producao" `
-Force
ARM Templates / Bicep
Locks podem ser incluídos em templates para garantir que toda vez que um ambiente é provisionado, os locks sejam criados automaticamente.
Bicep para lock em um recurso dentro do mesmo template:
// Criar o Key Vault
resource keyVault 'Microsoft.KeyVault/vaults@2023-02-01' = {
name: 'kv-prod-001'
location: resourceGroup().location
properties: {
sku: { family: 'A', name: 'standard' }
tenantId: subscription().tenantId
enableSoftDelete: true
}
}
// Criar lock no Key Vault
resource kvLock 'Microsoft.Authorization/locks@2020-05-01' = {
name: 'kv-prod-nodelete'
scope: keyVault
properties: {
level: 'CanNotDelete'
notes: 'Key Vault de producao - nao deletar'
}
}
Bicep para lock no Resource Group (usando módulo com targetScope):
// arquivo: rg-lock.bicep
targetScope = 'resourceGroup'
resource rgLock 'Microsoft.Authorization/locks@2020-05-01' = {
name: 'rg-prod-nodelete'
properties: {
level: 'CanNotDelete'
notes: 'Resource Group de producao - protegido'
}
}
Quando usar templates: ambientes provisionados via IaC onde o lock deve existir desde o início e ser recriado caso o ambiente seja redeploy.
Terraform
# Lock CanNotDelete em Resource Group
resource "azurerm_management_lock" "rg_lock" {
name = "rg-prod-nodelete"
scope = azurerm_resource_group.prod.id
lock_level = "CanNotDelete"
notes = "Protecao contra exclusao acidental"
}
# Lock ReadOnly em recurso específico
resource "azurerm_management_lock" "kv_lock" {
name = "kv-prod-readonly"
scope = azurerm_key_vault.prod.id
lock_level = "ReadOnly"
notes = "Key Vault de producao - somente leitura"
}
Atenção com Terraform e locks: se você aplicar um lock CanNotDelete em um RG via Terraform e depois tentar fazer
terraform destroy, o destroy falhará porque o Terraform tentará deletar os recursos, incluindo o próprio RG. Você precisará remover o lock primeiro. Isso é esperado e é exatamente a proteção que o lock oferece.
7. Controle e Segurança
Quem pode gerenciar locks: detalhe das permissões
As operações de lock são:
| Operação | Permissão necessária |
|---|---|
| Criar lock | Microsoft.Authorization/locks/write |
| Deletar lock | Microsoft.Authorization/locks/delete |
| Ler locks | Microsoft.Authorization/locks/read |
As roles built-in que incluem essas permissões são Owner e User Access Administrator. Contributor explicitamente não inclui Microsoft.Authorization/locks/write.
Se você precisa delegar apenas gerenciamento de locks sem dar Owner completo, pode criar uma Custom Role com apenas as permissões de lock:
{
"Name": "Lock Manager",
"Actions": [
"Microsoft.Authorization/locks/read",
"Microsoft.Authorization/locks/write",
"Microsoft.Authorization/locks/delete"
],
"AssignableScopes": ["/subscriptions/<sub-id>"]
}
Locks e Azure Policy
Locks e Policy são complementares. Uma estratégia robusta usa Policy para garantir que locks existam:
Existe uma built-in initiative no Azure Policy chamada "Append a lock of type CanNotDelete to resource groups" que usa o efeito Append para garantir que todo novo Resource Group criado receba automaticamente um lock CanNotDelete.
Isso resolve o problema de esquecer de aplicar locks manualmente em novos RGs.
8. Tomada de Decisão
CanNotDelete vs. ReadOnly
| Situação | Lock recomendado | Motivo |
|---|---|---|
| Banco de dados de produção que precisa operar | CanNotDelete | ReadOnly bloquearia operações do próprio serviço |
| VNet e recursos de rede que raramente mudam | CanNotDelete | Permite manutenção de rede, impede exclusão |
| Resource Group de produção completo | CanNotDelete no RG | Proteção abrangente sem impactar operações |
| Infraestrutura de identidade (DNS, AD) | ReadOnly | Não deve ser modificada; qualquer mudança deve ser deliberada e requer remover o lock |
| Key Vault com segredos críticos | CanNotDelete | ReadOnly impediria rotação de segredos |
| Subscription de produção inteira | CanNotDelete na Sub | Camada adicional para toda a subscription |
| Ambiente de laboratório/dev | Nenhum | Locks impedem agilidade em ambientes de teste |
Onde aplicar o lock: recurso vs. Resource Group
| Cenário | Nível do lock | Motivo |
|---|---|---|
| Proteger um recurso específico dentro de um RG com outros recursos mutáveis | Resource | Granularidade necessária |
| Proteger todos os recursos de produção em um RG | Resource Group | Um lock cobre tudo, mais simples de gerenciar |
| Proteger infraestrutura de rede inteira | Resource Group de rede | Tudo no RG de rede é crítico |
| Proteção organizacional máxima | Subscription | Cobre todos os RGs, mas use com cuidado |
9. Boas Práticas
Aplique locks em Resource Groups de produção como regra padrão. Todo Resource Group de produção deve ter no mínimo um lock CanNotDelete. Esta deve ser uma checklist obrigatória no processo de go-live de qualquer ambiente.
Use IaC para garantir locks desde o provisionamento. Inclua a criação de locks nos seus templates Terraform ou Bicep. Assim, o lock é criado junto com o ambiente e não depende de um passo manual que pode ser esquecido.
Documente locks com o campo "Notes". O campo de notas do lock deve conter: quem aprovou, por quê o lock existe, e o que deve ser feito antes de removê-lo. Por exemplo: "Produção - Remover apenas com aprovação do CTO via ticket de change".
Combine locks com Azure Policy para cobertura automática. Use a Policy de Append para garantir que novos RGs sempre recebam locks. Isso elimina o risco humano de esquecer.
Prefira CanNotDelete a ReadOnly para recursos operacionais. ReadOnly deve ser reservado para infraestrutura verdadeiramente estática. Para a maioria dos recursos de produção que precisam operar normalmente, CanNotDelete é a escolha correta.
Revise locks periodicamente. Audite regularmente quais locks existem, se ainda fazem sentido, e se o campo de notas está atualizado. Locks "esquecidos" sem documentação causam confusão operacional.
Nunca use ReadOnly em uma Subscription inteira de produção ativa. O impacto é catastrófico: bloqueia praticamente todas as operações de gerenciamento de todos os recursos. Se precisar proteger a Subscription, use CanNotDelete.
10. Erros Comuns
| Erro | Por que acontece | Como evitar |
|---|---|---|
| Aplicar ReadOnly em RG com VMs em execução | Não testar o impacto antes | Testar em ambiente de dev, documentar impactos por tipo de recurso |
| Tentar remover lock com conta de Contributor | Não saber que Contributor não gerencia locks | Usar conta Owner ou criar role específica de lock manager |
| Acreditar que Contributor não pode usar recursos com lock CanNotDelete | Confundir lock com restrição de uso | CanNotDelete só impede DELETE; Contributor ainda pode criar, ler e modificar |
| Não documentar o motivo do lock | Pressa no momento de criação | Tornar o campo "Notes" obrigatório no processo |
| Criar lock no recurso sem perceber que o RG já tem lock | Gerenciamento fragmentado | Sempre verificar locks em todos os escopos ancestrais |
| Esquecer de criar lock em novos RGs de produção | Processo manual sujeito a erro humano | Usar Azure Policy com Append para automatizar |
| Confundir o lock com proteção de acesso | Lock e RBAC são camadas diferentes | Lembrar: lock bloqueia operações específicas; RBAC controla quem pode operar |
| Tentar deletar RG via portal e não entender o erro 409 | Não associar o erro ao lock | Verificar sempre a aba Locks antes de reportar problema de permissão |
O erro mais custoso: ReadOnly em ambiente ativo
Aplicar ReadOnly em um Resource Group com serviços em execução pode derrubar serviços imediatamente. VMs não respondem a comandos, App Services podem falhar em operações internas, runbooks do Automation podem parar. A correção (remover o lock) é imediata, mas o downtime já terá ocorrido.
11. Operação e Manutenção
Auditoria de locks existentes
# Listar todos os locks em toda a subscription (visão completa)
az lock list --output table
# Filtrar apenas locks de um tipo específico
az lock list \
--query "[?properties.level=='ReadOnly']" \
--output table
# Verificar locks em um RG específico
az lock list \
--resource-group "rg-producao" \
--output table
# Exportar todos os locks para JSON (para auditoria)
az lock list --output json > locks-audit-$(date +%Y%m%d).json
Monitorar criação e remoção de locks
Mudanças em locks são registradas no Activity Log:
# Ver criação e remoção de locks no Activity Log
az monitor activity-log list \
--resource-provider "Microsoft.Authorization" \
--query "[?operationName.value=='Microsoft.Authorization/locks/write' || operationName.value=='Microsoft.Authorization/locks/delete']" \
--output table
Configure um Activity Log Alert para ser notificado quando locks são removidos em escopos críticos:
az monitor activity-log alert create \
--name "Alerta-Lock-Removido-Prod" \
--resource-group "rg-monitoramento" \
--condition category=Administrative \
and operationName=Microsoft.Authorization/locks/delete \
--scope "/subscriptions/<sub-id>/resourceGroups/rg-producao" \
--action-group "/subscriptions/<sub-id>/resourceGroups/rg-monitoramento/providers/microsoft.insights/actionGroups/ag-alertas-criticos"
Este alerta é especialmente importante: se alguém remover um lock de produção sem seguir o processo de change management, você será notificado imediatamente.
Limites importantes
| Limite | Valor |
|---|---|
| Locks por recurso | 20 |
| Locks por Resource Group | 20 |
| Locks por Subscription | 20 |
Na prática, esses limites são raramente atingidos. Uma estratégia de lock bem projetada usa um único lock bem documentado por escopo.
12. Integração e Automação
Pipeline de proteção de ambiente de produção
Um padrão comum é incluir a criação de locks como etapa final de um pipeline de deploy de produção:
Processo de Change Management com locks
Em organizações com processos maduros de change management, a remoção de um lock de produção é parte do processo de mudança:
O alerta de remoção de lock configurado no Activity Log serve como evidência e auditoria desse processo.
Integração com Azure Blueprints
Azure Blueprints (apesar de estar em processo de depreciação em favor de Deployment Stacks e Bicep) usava locks para proteger recursos deployados via Blueprint. O conceito de Blueprint lock era mais restritivo que locks normais: nem mesmo Owner conseguia removê-lo sem primeiro remover a atribuição do Blueprint.
O sucessor moderno é o Deployment Stacks, que oferece capacidade similar de bloquear recursos deployados em conjunto.
13. Resumo Final
Pontos essenciais:
- Resource Locks são uma camada de proteção independente de RBAC, aplicada no nível do recurso pelo ARM
- Existem exatamente dois tipos: CanNotDelete (bloqueia DELETE) e ReadOnly (bloqueia DELETE e PUT/PATCH)
- Contributor não pode criar ou remover locks; apenas Owner e User Access Administrator podem
- Locks são herdados de cima para baixo: um lock no RG afeta todos os recursos dentro
- Locks bloqueiam operações retornando HTTP 409 Conflict com código
ScopeLocked - Um lock em um RG não aparece na lista de locks dos recursos individuais dentro do RG
Diferenças críticas:
- CanNotDelete vs. ReadOnly: CanNotDelete permite operações normais exceto exclusão; ReadOnly bloqueia qualquer modificação, incluindo start/stop de VMs e listagem de chaves de storage
- Lock vs. RBAC: Lock age independente de permissões; mesmo Owner tem suas operações bloqueadas por um lock (mas pode removê-lo)
- Lock no recurso vs. no RG: lock no RG protege tudo dentro, mas não aparece na aba Locks dos recursos individuais; é preciso verificar escopos ancestrais
- Remover lock vs. não ter lock: remover um lock requer Owner/UAA; um Contributor pode usar um recurso com lock CanNotDelete normalmente (exceto deletar)
O que precisa ser lembrado para o AZ-104:
- O limite de locks por escopo é 20
- A aba Locks fica em Settings de qualquer recurso, RG ou Subscription no portal
- Locks são recursos do tipo
Microsoft.Authorization/locksgerenciados pelo ARM - ReadOnly em uma Storage Account bloqueia a operação
listKeys, quebrando aplicações que dependem de listar chaves - A combinação recomendada para produção é: CanNotDelete no RG + Activity Log Alert para remoção de locks
- Azure Policy pode usar efeito Append para garantir que locks sejam criados automaticamente em novos Resource Groups