Passo a passo para automatizar Azure Backup em VMs via Azure Policy usando a definição built-in “Configure backup on virtual machines with a given tag”, com Managed Identity e parâmetros de TAG.
Fala, pessoal! Nas últimas semanas venho revisando o desenho de proteção de dados de VMs em ambientes Azure com escala razoável (dezenas a algumas centenas de máquinas) e a mesma dor apareceu em mais de um cliente: backup ainda depende de alguém lembrar de “clicar” na VM depois que ela nasce. Este artigo que escrevi mostra como resolver isso de forma nativa, usando Azure Policy e a definição built-in Configure backup on virtual machines with a given tag to an existing recovery services vault in the same location.
Por que automatizar backup por TAG
Ambientes cloud crescem por delegação: times de aplicação sobem VMs, esteiras de IaC provisionam recursos por Pull Request, workloads sobem em janelas de 3h da manhã. Delegar a decisão “essa VM entra no backup?” para um humano depois da criação é a receita clássica de VM em produção sem restore point — e a descoberta costuma ser feita no pior dia possível.
A abordagem baseada em Azure Policy resolve isso invertendo a lógica: em vez de proteger a VM depois, o ambiente já garante que qualquer VM que nasça com a TAG certa (por exemplo, Ambiente=Prod) seja automaticamente associada a um cofre e a uma política de backup pré-definidos. É governança contínua, não campanha de conformidade.
Comparação de abordagens
| Abordagem | Escala | Auditável | Risco de gap | Quando usar |
|---|---|---|---|---|
| Portal — associação manual | Baixa | Não | Alto | Ambiente pequeno, poucas VMs |
| Runbook / script pós-criação | Média | Parcial | Médio | Já existe automação central madura |
| Azure Policy + TAG (este artigo) | Alta | Sim (Compliance) | Baixo | Padrão para ambientes governados |
| IaC (Terraform/Bicep) — módulo padrão | Alta | Sim (código) | Baixo | Ambientes 100% IaC, sem criação de VM via portal |
Na prática, Azure Policy + IaC não competem — se complementam. A Policy é a rede de segurança para tudo que escapa do módulo IaC (VMs criadas via portal, ARM, ou por times sem acesso ao repositório).
Pré-requisitos
| Item | Detalhe |
|---|---|
| Permissões na Subscription | Resource Policy Contributor (para criar a Policy Assignment) e User Access Administrator ou Owner (para atribuir roles à Managed Identity). |
| Permissões no Recovery Services Vault | Backup Contributor — será concedida à Managed Identity da Policy Assignment. |
| Recovery Services Vault (RSV) | Já existente, na mesma região das VMs que serão protegidas. O parâmetro vaultLocation da política é rígido nisso. |
| Backup Policy no cofre | Standard ou Enhanced — o subtipo precisa ser compatível com o cenário (ver seção sobre subtipo). |
| Padronização de TAG | A TAG que vai disparar a proteção (ex.: Ambiente) precisa ter governança — idealmente com uma policy de Deny ou Append garantindo que VMs nasçam com o valor correto. |
| Ferramentas | Azure CLI 2.60+ ou PowerShell 7 com módulos Az e Az.RecoveryServices. Portal também funciona. |
Um detalhe que muita gente pula: Standard vs. Enhanced
Quando você cria a Backup Policy no cofre, precisa escolher o subtipo:
- Standard: backup diário, retenção até 9999 dias, cenário clássico para VMs de produção com RPO de 24h.
- Enhanced: permite backup múltiplas vezes ao dia (frequência Hourly), suporta Trusted Launch VMs, Ultra Disks, discos compartilhados. Habilita também o Vault-Standard Tier archive.
Uma vez criada a policy como Standard ou Enhanced, não dá para converter. Se você vai precisar de RPO menor que 24h ou usa Trusted Launch, comece com Enhanced.
Passo a passo
Passo 1 — Preparar o Recovery Services Vault e a Backup Policy
No portal, navegue até Recovery Services vaults › Create e provisione o cofre na região das VMs alvo (ex.: brazilsouth). Nomeie de forma que já indique o cenário: rsv-vms-prod. Depois, dentro do cofre, vá em Manage › Backup policies › Add e crie a policy que a Azure Policy vai referenciar. Você pode criar um RSV para vms para homologação/dev e sua politica em separado para melhor governança.
Exemplo de configuração para bkp-vms-prod (Enhanced, RPO de 4h):
- Policy sub type:
Enhanced - Backup frequency:
Hourly - Schedule: Start
10:00Pm, Every4 Hours, Duration12 Hours, Timezone(UTC-03:00) Brasília - Instant restore snapshot retention:
1 dia - Retention of daily backup point:
7 dias - Retention of weekly backup point:
4 semanas(ajustar por RTO/RPO) - Retention of monthly backup point:
12 meses



Demais segue como padrão, dependendo das configurações de compliance da sua organização.
Figura 1 — Criação da Backup Policy Enhanced no cofre, com frequência Hourly a cada 4 horas.
Passo a criação da política:
01

02 –



Alternativa via CLI (útil para IaC e para documentar em runbook):
# Criar o Recovery Services Vaultaz backup vault create \ --resource-group rg-backup \ --name rsv-vms-prod \ --location brazilsouth# Listar policies existentes no cofre (as built-in DefaultPolicy e EnhancedPolicy já vêm)az backup policy list \ --resource-group rg-backup \ --vault-name rsv-vms-prod \ --output table# Recuperar o ID de uma policy específica (será usado no parâmetro backupPolicyId da Azure Policy)az backup policy show \ --resource-group rg-backup \ --vault-name rsv-vms-prod \ --name bkp-vms-prod \ --query id -o tsv
Guarde o
idcompleto da Backup Policy — ele é obrigatório no parâmetrobackupPolicyIdda Azure Policy. Copiar só o nome não funciona.
Passo 2 — Criar a Azure Policy Assignment
No portal: Policy › Definitions e busque por “Configure backup on virtual machines with a given tag to an existing recovery services vault“. A definição built-in tem o ID 345fa903-145c-4fe1-8bcd-93ec2adccde8.
Clique em Assign e preencha:
- Scope:
SubscriptionouResource Group. Nunca Management Group — a política built-in não suporta esse escopo (voltamos a isso na seção de armadilhas). - Assignment name: algo descritivo, ex.:
backup-vms-prod-por-tag. - Policy enforcement:
Enabledse você quer que o DeployIfNotExists atue;Disabled(DoNotEnforce) para rodar em modo auditoria inicial.


Figura 2 — Aba Basics do Assignment: escopo em Subscription e enforcement habilitado.
Na aba Parameters, preencha:
| Parâmetro | Valor de exemplo | Observação |
|---|---|---|
effect | DeployIfNotExists | Padrão. É o que cria a proteção automaticamente. |
vaultLocation | brazilsouth | Precisa ser igual à região das VMs. A Policy só age em VMs da mesma região. |
backupPolicyId | /subscriptions/<sub>/resourceGroups/rg-backup/providers/Microsoft.RecoveryServices/vaults/rsv-vms-prod/backupPolicies/bp-vms-prod | ID completo. Cole o output do az backup policy show --query id. |
tagName (Inclusion Tag Name) | Ambiente | Nunca deixe vazio. Ver armadilha #3. |
tagValues (Inclusion Tag Value) | ["Prod"] | Array. Aceita múltiplos valores, ex.: ["Prod","Producao"]. |




Figura — Parâmetros preenchidos: tagName=Ambiente, tagValues=[“Prod”].
Na aba Remediation:
- Marque Create a Managed Identity (System-assigned, na mesma região do cofre).
- Marque Create a remediation task se você já tem VMs pré-existentes que devem ser protegidas nesta rodada. Para VMs futuras (novas), essa opção é irrelevante — o DeployIfNotExists age automaticamente na criação.

Figura 4 — Aba Remediation com Managed Identity System-assigned selecionada.
⚠️ Ponto crítico: RBAC da Managed Identity
Ao finalizar o Assignment, o portal promete conceder as roles automaticamente. Na prática, em vários casos que já vi, essa concessão demora ou falha silenciosamente. Não confie — valide manualmente:
- No cofre, vá em Access control (IAM) › Role assignments e confirme que a Managed Identity da Policy tem a role
Backup Contributor. - Na Subscription ou RG do escopo, confirme que a mesma identidade tem
Virtual Machine Contributor(precisa dessa role para ler as VMs e disparar o registro no cofre).
Se faltar qualquer uma, atribua manualmente:
# Recuperar o principalId da Managed Identity do AssignmentPRINCIPAL_ID=$(az policy assignment show \ --name backup-vms-prod-por-tag \ --scope "/subscriptions/<sub>" \ --query identity.principalId -o tsv)# Backup Contributor no cofreaz role assignment create \ --assignee-object-id $PRINCIPAL_ID \ --assignee-principal-type ServicePrincipal \ --role "Backup Contributor" \ --scope "/subscriptions/<sub>/resourceGroups/rg-backup/providers/Microsoft.RecoveryServices/vaults/rsv-vms-prod"# Virtual Machine Contributor no escopo da Policyaz role assignment create \ --assignee-object-id $PRINCIPAL_ID \ --assignee-principal-type ServicePrincipal \ --role "Virtual Machine Contributor" \ --scope "/subscriptions/<sub>"
Faça isso imediatamente após criar o Assignment. A razão está na próxima seção — se a role só aparecer 20 minutos depois, você perdeu a janela automática e vai depender de remediation manual para qualquer VM criada nesse intervalo.
Após a criação da policy, localize a mesma e vamos editá-la:



Agora salve a policy

Passo 3 — Testar com uma VM nova
Crie uma VM de teste na região configurada, com a TAG Ambiente – Prod que dispara a proteção:
az vm create \ --resource-group rg-servidores \ --name vm-teste-backup \ --image Ubuntu2204 \ --location brazilsouth \ --size Standard_B2s \ --admin-username azureuser \ --generate-ssh-keys \ --tags Ambiente=Prod


Tags aplicadas

Aguarde de 10 a 20 minutos. Depois:

- Em Policy › Compliance, filtre pelo Assignment. A VM deve estar como
Compliant.
Figura 5 — VM aparecendo em Protected items automaticamente após a janela de avaliação.

E se a janela passou e a VM ficou como Non-compliant?
Isso normalmente significa que a Managed Identity não tinha as roles no exato momento da avaliação. Depois de corrigir o RBAC, dispare uma Remediation Task:
Via portal: Policy › Remediation › Remediate policy › selecione o Assignment › Remediate.
Via CLI:
az policy remediation create \ --name remediate-backup-vms-prod-$(date +%Y%m%d) \ --policy-assignment "/subscriptions/<sub>/providers/Microsoft.Authorization/policyAssignments/backup-vms-prod-por-tag" \ --resource-group rg-lab
Acompanhe em Policy › Remediation › Remediation tasks até o status ficar Succeeded.
Deep-dive técnico
| Elemento | O que faz |
|---|---|
effect: DeployIfNotExists | Avalia se a VM já está protegida no cofre alvo. Se não, dispara um deployment ARM que faz o enable-protection. Só age quando o recurso é criado ou atualizado — não é um scan contínuo. |
| Janela de avaliação | Após um PUT no Resource Provider da VM, a Policy dispara em ~10 minutos. Se a Managed Identity não tem role naquele instante, o deployment falha silenciosamente e a VM cai em Non-compliant nas avaliações periódicas subsequentes — sem retry automático. |
| Managed Identity (System-assigned) | É o “usuário” que a Policy usa para executar o deployment. Precisa de Backup Contributor no cofre e Virtual Machine Contributor no escopo. Sem isso, DeployIfNotExists vira DoNotDeploy. |
tagName + tagValues | Filtro de inclusão. Só VMs com tags[tagName] IN tagValues são elegíveis. Case-sensitive nos valores. |
vaultLocation | Filtro geográfico. Se a VM está em outra região do cofre, é ignorada. |
| Remediation Task | Aplica o efeito retroativamente em recursos que já existem no escopo. Útil para: (a) VMs criadas antes da Policy; (b) VMs que perderam a janela por falha de RBAC. |
Armadilhas de campo (as que doeram)
Armadilha #1 — Management Group não é escopo suportado
A definição built-in with a given tag só aceita Subscription ou Resource Group como escopo. Se você tentar criar o Assignment em um Management Group, o portal aceita a criação, o Compliance mostra tudo como Compliant, e nenhuma VM recebe backup. É uma falha silenciosa.
Isso está na documentação oficial da definição, mas passa batido em toda revisão de desenho que fiz. Se você governa um Landing Zone com dezenas de subscriptions, precisa criar um Assignment por Subscription — o que é ruim de manter à mão, mas gerenciável via IaC ou script.
Solução prática: mantenha a definição de Backup Policy centralizada em um cofre de hub ou padronizada por IaC, e escreva um script que faça
foreach subscriptioncriando o Assignment com os mesmos parâmetros.
Armadilha #2 — Condição de corrida entre RBAC e avaliação
Cronologia típica que causa o problema:
- Você cria o Assignment às 14:00 e o portal “promete” atribuir as roles à Managed Identity.
- Uma esteira de IaC cria uma VM às 14:03.
- Às 14:13, a Policy tenta o DeployIfNotExists — mas as roles só apareceram às 14:20.
- A VM fica Non-compliant. Como não há retry automático em DeployIfNotExists após a criação, apenas remediation manual protege essa VM específica.
Como evitar: crie o Assignment em janela de manutenção, valide RBAC na hora (Passo 2 acima), e só então libere a criação de VMs no escopo. Em ambiente já rodando, agende uma Remediation Task semanal para varrer o que a janela automática eventualmente perde.
Armadilha #3 — TAG ou valor vazio protege ZERO VMs
Aqui é onde muita gente que migrou da política antiga without a given tag se queima. Comportamento:
| Política | tagName ou tagValues vazio | Efeito |
|---|---|---|
| without a given tag (exclusão) | Vazio | Todas as VMs viram elegíveis (nada é excluído). |
| with a given tag (inclusão) — este artigo | Vazio | Nenhuma VM vira elegível (nada bate o filtro). |
Ou seja: no with a given tag, esquecer de preencher a TAG não gera VMs protegidas em excesso — gera VMs sem proteção alguma. E o Compliance vai mostrar 100% Compliant, porque não há VM elegível para ficar Non-compliant. É a pior categoria de falha silenciosa possível em backup.
Troubleshooting
| Sintoma | Diagnóstico | Ação |
|---|---|---|
| VM criada com a TAG certa não aparece em Backup items após 20min | Managed Identity sem Backup Contributor no cofre, ou sem Virtual Machine Contributor no escopo, no momento da criação da VM. | Confirmar roles (aba IAM do cofre e da Subscription), rodar Remediation Task manual, validar novamente. |
| VM aparece como Non-compliant sem detalhes | Provável mismatch de região entre VM e cofre (vaultLocation). | Confirmar que a VM está na mesma região do cofre. Não há workaround — cofre é regional. |
| Nenhuma VM elegível, apesar de haver dezenas com a TAG | Assignment criado em Management Group (não suportado), ou tagValues com case diferente (prod vs Prod). | Recriar Assignment em Subscription/RG. Verificar case exato dos valores. |
| Remediation Task fica em Failed | Erro no deployment ARM — geralmente permissão ou lock em RG. | Abrir a Remediation Task › Deployments › ver mensagem do provider. Corrigir e rerodar. |
| Backup Policy exibe erro ao reduzir retenção | Cofre marcado como imutável (Immutable Vault). | Comportamento esperado — reduções seguem processo específico documentado pela Microsoft. |
| Last backup status = Failed em VM específica | Problema no agente da VM, lock em disco, ou snapshot travado. | Cofre › Backup jobs › abrir o job com erro. Ações comuns: reiniciar agente, liberar snapshot pendente, verificar espaço. |
Boas práticas para produção
- Governança de TAG antes da Policy de backup. Se a TAG
Ambientenão é obrigatória, a proteção fica furada. Combine com uma policy deDenyna criação de VM sem a TAG, ouAppendaplicando um valor default. - Immutable Vault. Habilite imutabilidade nos cofres de produção. Bloqueia reduções acidentais de retenção e é uma barreira concreta contra cenários de ransomware que tentam apagar restore points.
- Soft Delete. Mantenha habilitado (padrão 14 dias). Complementa a imutabilidade.
- Cross-Region Restore. Para workloads críticos, habilite CRR no cofre — permite restaurar em região secundária em cenário de desastre regional.
- Modo auditoria antes de enforcement. Suba o Assignment como
DoNotEnforceprimeiro, avalie o Compliance por alguns dias, corrija VMs órfãs, só então promova paraDefault. - Remediation Task periódica. Agende (via Automation Runbook ou pipeline) uma remediation semanal para pegar VMs que porventura perderam a janela.
- Monitoramento. Integre Backup jobs com Log Analytics/Azure Monitor e crie alerta para Failed ou Warning nas últimas 24h. Backup sem monitoramento é ficção de compliance.
Fecho
Automatizar Azure Backup por TAG via Azure Policy é uma das mudanças de maior impacto e menor custo em governança de nuvem: elimina a decisão humana no caminho crítico da proteção, gera evidência auditável via Compliance, e escala junto com a esteira de provisionamento. Mas depende de três coisas darem certo ao mesmo tempo: escopo correto (não é MG), RBAC da Managed Identity no lugar antes da primeira VM, e TAG realmente preenchida — nenhuma delas grita quando falha.
O código-fonte dos exemplos deste artigo (comandos CLI, exemplos de assignment JSON, script de bulk assignment por Subscription) está no GitHub. Se este material te ajudou, deixa uma estrelinha ⭐ no repositório — ajuda a chegar em mais gente do time de Cloud.
E se você tem uma armadilha diferente das que listei — daquelas que só descobriu tomando na cara — conta nos comentários. Governança de backup é área em que a comunidade aprende junto.
Forte abraço pessoal 👊


