Fundamentação Teórica: Configure Blob Versioning
1. Intuição Inicial​
Imagine que você edita um documento importante e salva por cima do arquivo original. Uma hora depois, percebe que a versão anterior era a correta. Sem histórico de versões, o dado está perdido.
Agora imagine que cada vez que você salva o arquivo, o sistema automaticamente guarda uma cópia numerada da versão anterior. Você pode voltar a qualquer versão anterior a qualquer momento. É exatamente assim que ferramentas como Git funcionam para código.
Blob Versioning aplica esse mesmo conceito ao Azure Blob Storage: cada vez que um blob é criado, modificado ou substituÃdo, o Azure automaticamente preserva a versão anterior. O histórico completo de modificações fica disponÃvel, e qualquer versão anterior pode ser recuperada com uma única operação.
A diferença fundamental em relação a snapshots (que vimos em Azure Files) é que versioning é automático: você não precisa lembrar de criar uma cópia antes de modificar. O sistema faz isso por você em cada operação de escrita.
2. Contexto​
2.1 Blob Versioning dentro da estratégia de proteção​
2.2 O que Blob Versioning é e o que não é​
É: Um sistema automático de versionamento de conteúdo para Block Blobs em Azure Blob Storage.
Não é:
- DisponÃvel para Append Blobs ou Page Blobs
- Uma substituição completa para backups
- Gratuito (cada versão ocupa espaço e é cobrada)
- DisponÃvel em contas Premium (apenas Standard GPv2)
2.3 Dependências crÃticas​
Blob Versioning é um pré-requisito para outras funcionalidades:
- Object Replication: Requer versioning habilitado em ambas as contas (origem e destino)
- Point-in-time Restore: Requer versioning + soft delete + change feed simultaneamente
- Lifecycle Management de versões: Requer versioning para ter seção
versionnas regras
3. Construção dos Conceitos​
3.1 Versão atual e versões anteriores​
Quando Blob Versioning está habilitado, cada blob tem:
Versão atual (current version): O estado mais recente do blob. É o que você acessa normalmente pela URL padrão do blob.
Versões anteriores (previous versions): Cópias somente leitura dos estados anteriores do blob. Cada versão tem um Version ID único, que é um timestamp no formato 2025-01-15T10:30:00.0000000Z.
3.2 O que gera uma nova versão​
Nem toda operação cria uma nova versão. É importante entender exatamente quais operações preservam a versão anterior:
| Operação | Cria versão anterior? | Resultado |
|---|---|---|
| Upload de novo blob (POST/PUT) | Não (blob não existia) | Cria versão atual |
| Substituição de blob existente (PUT) | Sim | Versão atual vira versão anterior; novo conteúdo vira versão atual |
| Modificação de metadados | Sim | Versão com metadados antigos vira versão anterior |
| Modificação de tags de Ãndice | Não | Tags não criam nova versão |
| Set Blob Tier (mudança de camada) | Não | Tier muda na versão atual |
| Delete Blob | Sim (especial) | Versão atual vira versão anterior; blob deixa de ter versão atual |
Comportamento não óbvio ao deletar com versioning: Quando você deleta um blob com versioning ativo, a versão atual não é destruÃda. Ela se torna uma versão anterior sem uma versão atual correspondente. O blob parece deletado (URL padrão retorna 404), mas todas as versões anteriores continuam existindo e são cobradas.
3.3 Version ID: o identificador único​
Cada versão tem um Version ID que é gerado automaticamente no momento da criação. O formato é um timestamp ISO 8601 com precisão de 100 nanossegundos:
2025-01-15T10:30:45.1234567Z
Para acessar uma versão especÃfica, adicione versionid como parâmetro à URL:
https://myaccount.blob.core.windows.net/container/relatorio.xlsx?versionid=2025-01-15T10:30:45.1234567Z
3.4 Interação entre Versioning e Soft Delete​
Quando ambos estão habilitados, o comportamento muda de forma significativa:
Sem Versioning, com Soft Delete:
- Deletar blob → blob vai para soft-deleted → pode ser restaurado
Com Versioning, com Soft Delete:
- Deletar blob → versão atual vira versão anterior → Soft Delete não é acionado para o blob em si
- O Soft Delete passa a proteger as versões anteriores quando elas são explicitamente deletadas
Esta é uma das interações mais importantes e mais cobradas no AZ-104.
3.5 Point-in-time Restore e Versioning​
Point-in-time Restore (PITR) é uma funcionalidade que permite restaurar o estado completo de todos os blobs de um container para um momento especÃfico no passado. Ela depende de:
- Blob Versioning habilitado
- Soft Delete habilitado
- Change Feed habilitado
Com PITR, você pode dizer: "restaure todos os blobs deste container para como estavam às 14:00 de ontem". O Azure usa o Change Feed e as versões para reconstruir esse estado.
4. Visão Estrutural​
5. Funcionamento na Prática​
5.1 Restaurando um blob para uma versão anterior​
O processo de restauração é uma operação de cópia: você copia uma versão anterior sobre a versão atual. Isso cria uma nova versão atual com o conteúdo da versão que você deseja restaurar, e a versão que estava como atual vira mais uma versão anterior.
A operação de cópia é feita com o comando Copy Blob ou az storage blob copy start especificando o Version ID de origem.
5.2 Promoção de versão anterior para versão atual​
A forma oficial de "restaurar" uma versão é usando Copy Blob from URL com o Version ID:
# Copiar versão anterior para torná-la a versão atual
az storage blob copy start \
--account-name myaccount \
--destination-container mycontainer \
--destination-blob relatorio.xlsx \
--source-uri "https://myaccount.blob.core.windows.net/mycontainer/relatorio.xlsx?versionid=2025-01-14T08:00:00.0000000Z&<SAS-TOKEN>" \
--auth-mode login
5.3 Comportamento de versioning com containers e blobs​
Versioning é configurado no nÃvel da Storage Account e se aplica a todos os blobs da conta. Não é possÃvel habilitar versioning apenas para containers ou blobs especÃficos.
6. Formas de Implementação​
6.1 Portal Azure​
Habilitando Blob Versioning:
Storage Account > Data Protection > Enable versioning for blobs
A opção está na mesma tela do Soft Delete e Change Feed, permitindo configurar todas as proteções de dados em um único lugar.
Listando versões no portal:
Storage Account > Containers > [container] > [blob] > Versions
O portal exibe uma lista de todas as versões do blob com Version ID, data e tamanho. Você pode baixar qualquer versão ou promovê-la para versão atual.
6.2 Azure CLI​
Habilitando Blob Versioning:
az storage account blob-service-properties update \
--account-name myaccount \
--resource-group myRG \
--enable-versioning true
Verificando se versioning está habilitado:
az storage account blob-service-properties show \
--account-name myaccount \
--resource-group myRG \
--query "isVersioningEnabled"
Listando todas as versões de um blob:
az storage blob list \
--account-name myaccount \
--container-name mycontainer \
--prefix "relatorio.xlsx" \
--include v \
--auth-mode login \
--output table
O parâmetro --include v instrui a incluir versões na listagem. A saÃda mostra o versionId de cada versão.
Baixando uma versão especÃfica:
az storage blob download \
--account-name myaccount \
--container-name mycontainer \
--name "relatorio.xlsx" \
--version-id "2025-01-14T08:00:00.0000000Z" \
--file "/local/path/relatorio-v1.xlsx" \
--auth-mode login
Deletando uma versão especÃfica:
az storage blob delete \
--account-name myaccount \
--container-name mycontainer \
--name "relatorio.xlsx" \
--version-id "2025-01-14T08:00:00.0000000Z" \
--auth-mode login
Deletando todas as versões de um blob:
# Deletar versão atual (blob principal)
az storage blob delete \
--account-name myaccount \
--container-name mycontainer \
--name "relatorio.xlsx" \
--auth-mode login
# Listar e deletar cada versão anterior
az storage blob list \
--account-name myaccount \
--container-name mycontainer \
--prefix "relatorio.xlsx" \
--include v \
--auth-mode login \
--query "[].versionId" \
--output tsv | while read VID; do
az storage blob delete \
--account-name myaccount \
--container-name mycontainer \
--name "relatorio.xlsx" \
--version-id "$VID" \
--auth-mode login
done
6.3 Azure PowerShell​
$ctx = New-AzStorageContext `
-StorageAccountName "myaccount" `
-UseConnectedAccount
# Listar versões de um blob
Get-AzStorageBlob `
-Container "mycontainer" `
-Prefix "relatorio.xlsx" `
-Context $ctx `
-IncludeVersion
# Obter versão especÃfica
$version = Get-AzStorageBlob `
-Container "mycontainer" `
-Blob "relatorio.xlsx" `
-VersionId "2025-01-14T08:00:00.0000000Z" `
-Context $ctx
# Promover versão anterior para versão atual
# (copia a versão especÃfica sobre o blob atual)
Start-AzStorageBlobCopy `
-SrcContainer "mycontainer" `
-SrcBlob "relatorio.xlsx" `
-SrcBlobSnapshotTime "2025-01-14T08:00:00.0000000Z" `
-DestContainer "mycontainer" `
-DestBlob "relatorio.xlsx" `
-Context $ctx
6.4 Bicep​
resource blobServiceProperties 'Microsoft.Storage/storageAccounts/blobServices@2023-01-01' = {
name: '${storageAccount.name}/default'
properties: {
isVersioningEnabled: true
// Habilitar em conjunto com as outras proteções
deleteRetentionPolicy: {
enabled: true
days: 7
}
containerDeleteRetentionPolicy: {
enabled: true
days: 30
}
changeFeed: {
enabled: true
retentionInDays: 7
}
}
}
6.5 Lifecycle Management para versões​
Este é um dos pontos mais crÃticos: versões antigas acumulam custo indefinidamente se não houver lifecycle policy para gerenciá-las.
{
"rules": [
{
"name": "version-management",
"enabled": true,
"type": "Lifecycle",
"definition": {
"filters": {
"blobTypes": ["blockBlob"]
},
"actions": {
"version": {
"tierToCool": {
"daysAfterCreationGreaterThan": 30
},
"tierToArchive": {
"daysAfterCreationGreaterThan": 90
},
"delete": {
"daysAfterCreationGreaterThan": 365
}
}
}
}
}
]
}
Atenção:
daysAfterCreationGreaterThanno contexto deversionrefere-se à data em que aquela versão especÃfica foi criada (o momento em que ela se tornou uma versão anterior), não à data de criação do blob original.
7. Controle e Segurança​
7.1 Permissões para acessar versões​
O acesso a versões especÃficas de um blob requer as mesmas permissões que o acesso ao blob atual:
| Operação | Role mÃnima |
|---|---|
| Listar versões | Storage Blob Data Reader |
| Ler conteúdo de uma versão | Storage Blob Data Reader |
| Deletar uma versão especÃfica | Storage Blob Data Contributor |
| Promover versão para atual (copy) | Storage Blob Data Contributor |
| Habilitar/desabilitar versioning | Storage Account Contributor |
7.2 Versioning e imutabilidade​
Quando Immutability Policy está ativa junto com Versioning:
- Versões protegidas pela policy não podem ser deletadas durante o perÃodo de imutabilidade
- Isso cria uma proteção muito robusta: cada modificação cria uma nova versão, e as versões não podem ser apagadas por atacantes
- Mesmo um administrador não consegue deletar versões imutáveis antes do prazo
Esta combinação é altamente recomendada para conformidade regulatória que exige histórico de modificações auditável.
7.3 Versioning e SAS tokens​
Para acessar uma versão especÃfica via SAS token, o SAS precisa incluir o versionid na URL ou o usuário precisa ter permissão para especificá-lo. SAS tokens de Service SAS e Account SAS suportam acesso a versões.
User Delegation SAS (gerado com credenciais Azure AD) é a opção mais segura e também suporta acesso a versões especÃficas.
7.4 O problema do custo com versioning​
Habilitar versioning sem lifecycle policy de controle de versões é uma receita para custo crescente. Cada modificação de blob cria uma versão anterior que:
- Ocupa espaço proporcional ao tamanho do blob
- É cobrada no tier em que está (geralmente Hot, pois versões herdam o tier do blob)
- Nunca é deletada automaticamente sem lifecycle policy
Para um blob de 1 GB modificado 10 vezes por dia, após 30 dias você pode ter 300 versões anteriores ocupando potencialmente 300 GB em Hot.
8. Tomada de Decisão​
8.1 Versioning vs Snapshots​
| Aspecto | Blob Versioning | Snapshots manuais |
|---|---|---|
| Automatismo | Automático em cada escrita | Manual (você decide quando criar) |
| Granularidade | Por operação de escrita | Apenas quando você cria |
| Gestão | Requer lifecycle policy | Requer processo manual de limpeza |
| Custo | Potencialmente alto sem lifecycle | Controlável (você controla quando cria) |
| Recuperação | Por Version ID especÃfico | Por timestamp do snapshot |
| Uso recomendado | Proteção contÃnua contra sobrescrita | Backup antes de operação especÃfica |
8.2 Quando habilitar Versioning​
| Situação | Habilitar Versioning? | Motivo |
|---|---|---|
| Dados crÃticos modificados frequentemente | Sim | Proteção automática contra sobrescrita |
| Blobs write-once (logs, backups) | Não necessariamente | Dados nunca são sobrescritos; Soft Delete é suficiente |
| Requisito de Object Replication | Sim (obrigatório) | Pré-requisito |
| Requisito de Point-in-time Restore | Sim (obrigatório) | Pré-requisito |
| Conta Premium Block Blob | Não disponÃvel | Premium não suporta versioning |
| Conta com grande volume e alto custo | Avaliar | Lifecycle policy é obrigatória para controlar custo |
8.3 Configuração complementar recomendada​
| Funcionalidade | Habilitar junto com Versioning? | Motivo |
|---|---|---|
| Soft Delete de blob | Sim | Protege versões deletadas individualmente |
| Soft Delete de container | Sim | Protege container e todas as versões |
| Change Feed | Sim para PITR | Necessário para Point-in-time Restore |
| Lifecycle policy para versões | Sempre | Controle de custo obrigatório |
| Immutability Policy | Para compliance | Torna versões auditáveis e imutáveis |
9. Boas Práticas​
- Sempre configure lifecycle policy para versões ao habilitar versioning. Nunca habilite versioning sem definir simultaneamente regras de expiração para
version. - Mova versões antigas para tiers mais baratos antes de deletá-las. Use
tierToCoolapós 30 dias edeleteapós 365 dias como ponto de partida. - Combine com Soft Delete para proteção em camadas: versioning protege contra sobrescrita, soft delete protege versões contra exclusão explÃcita.
- Habilite versioning junto com Change Feed se houver necessidade de Point-in-time Restore, pois PITR requer ambos.
- Use Version ID ao referenciar versões em scripts de restauração, nunca assuma qual versão é a "segunda mais recente" por posição.
- Restrinja quem pode deletar versões especÃficas usando RBAC granular. Apenas administradores designados devem ter permissão de deletar versões.
- Monitore o BlobCapacity por blob type separando versões do conteúdo ativo para entender o custo real do versioning.
- Documente o processo de restauração para a equipe: como listar versões, como identificar a versão correta e como promovê-la.
10. Erros Comuns​
| Erro | Por que acontece | Como evitar |
|---|---|---|
| Custo explosivo após habilitar versioning | Sem lifecycle policy para versões; blobs modificados frequentemente | Sempre criar lifecycle policy para version simultaneamente |
| Blob "deletado" ainda aparece nos custos | Delete com versioning não remove versões anteriores | Deletar explicitamente cada versão após deletar o blob atual |
| Restauração cria versão extra indesejada | Copy de versão anterior cria nova versão atual | Comportamento esperado; documentar e incluir na lifecycle policy |
| Versioning não funciona em conta Premium | Premium Block Blob não suporta versioning | Usar Standard GPv2 para dados que precisam de versioning |
| Object Replication falha | Versioning não habilitado em uma das contas | Habilitar versioning em ambas as contas antes de configurar replicação |
| PITR não disponÃvel | Versioning, Soft Delete ou Change Feed não habilitados | Habilitar os três simultaneamente |
| Versões em Hot não incluÃdas em lifecycle | Lifecycle policy sem seção version | Sempre incluir seção version nas regras de lifecycle |
| Version ID difÃcil de encontrar | Não documentado após operação de upload | Capturar o Version ID da resposta HTTP e armazenar em sistema de inventário |
11. Operação e Manutenção​
11.1 Monitorando versões e custo​
# Ver capacidade total de versões (no Azure Monitor)
az monitor metrics list \
--resource <storage-account-id> \
--metric BlobCapacity \
--dimension BlobType \
--interval P1D
Filtre por BlobType=BlockBlobPreviousVersions para ver apenas o espaço ocupado por versões anteriores.
Query no Log Analytics para acompanhar versões criadas:
StorageBlobLogs
| where OperationName == "PutBlob" and isnotempty(ResponseStatus)
| where ResponseStatus == "Success"
| extend VersionId = extract("versionid=([^&]+)", 1, RequestUri)
| where isnotempty(VersionId)
| summarize count() by bin(TimeGenerated, 1d)
11.2 Inventário de versões com Azure Storage Blob Inventory​
Para contas com grande volume de dados, use Blob Inventory para gerar um relatório CSV de todos os blobs e versões:
az storage account blob-inventory-policy create \
--account-name myaccount \
--resource-group myRG \
--policy '{
"enabled": true,
"rules": [{
"name": "version-inventory",
"enabled": true,
"destination": "inventory-container",
"definition": {
"format": "Csv",
"schedule": "Weekly",
"objectType": "Blob",
"schemaFields": ["Name", "VersionId", "IsCurrentVersion", "ContentLength", "BlobType", "AccessTier", "LastModified"],
"filters": {
"includeSnapshots": false,
"includeBlobVersions": true
}
}
}]
}'
O relatório é gerado semanalmente no container especificado e pode ser analisado com Azure Synapse ou Data Factory para identificar versões candidatas a limpeza.
11.3 Limites importantes​
| Aspecto | Limite |
|---|---|
| Tipos de blob suportados | Apenas Block Blobs |
| Tipos de conta suportados | Standard GPv2 |
| Número máximo de versões por blob | Sem limite documentado (prático: controlar via lifecycle) |
| Version ID | Timestamp com precisão de 100ns; único por blob |
| Desabilitação do versioning | PossÃvel, mas versões existentes permanecem |
Importante sobre desabilitação: Se você desabilitar versioning em uma conta que já tinha versões acumuladas, as versões existentes não são deletadas. Elas continuam existindo, continuam sendo cobradas, mas novas versões não são mais criadas. Para limpar as versões existentes, você precisa deletá-las explicitamente ou usar lifecycle policy que continuará se aplicando mesmo após desabilitar o versioning.
12. Integração e Automação​
12.1 Point-in-time Restore: habilitação completa​
PITR requer três funcionalidades simultâneas. Habilite todas via CLI:
# Habilitar versioning, soft delete e change feed (pré-requisitos de PITR)
az storage account blob-service-properties update \
--account-name myaccount \
--resource-group myRG \
--enable-versioning true \
--enable-delete-retention true \
--delete-retention-days 7 \
--enable-change-feed true \
--change-feed-retention-days 7
# Habilitar Point-in-time Restore com janela de 6 dias
az storage account blob-service-properties update \
--account-name myaccount \
--resource-group myRG \
--enable-restore-policy true \
--restore-days 6
O perÃodo de PITR deve ser menor que o perÃodo de soft delete. Se soft delete é 7 dias, PITR pode ser no máximo 6 dias.
Executando um restore:
az storage blob restore \
--account-name myaccount \
--resource-group myRG \
--time-to-restore "2025-01-14T10:00:00Z" \
--blob-ranges '[{"startRange": "", "endRange": ""}]'
O parâmetro blob-ranges com startRange e endRange vazios significa "restaurar todos os blobs". Você pode especificar prefixos para restaurar apenas parte do container.
12.2 Automação de inventário de versões com Azure Function​
import azure.functions as func
from azure.storage.blob import BlobServiceClient
from datetime import datetime, timedelta
def main(timer: func.TimerRequest):
"""
Executa semanalmente e identifica versões
mais antigas que 90 dias em tier Hot,
gerando relatório de candidatos para Archive.
"""
client = BlobServiceClient.from_connection_string(conn_str)
cutoff = datetime.utcnow() - timedelta(days=90)
candidates = []
for container in client.list_containers():
container_client = client.get_container_client(container['name'])
for blob in container_client.list_blobs(include=['versions']):
if (blob.get('version_id') and
not blob.get('is_current_version') and
blob.get('last_modified', datetime.utcnow()) < cutoff and
blob.get('blob_tier') == 'Hot'):
candidates.append({
'container': container['name'],
'blob': blob['name'],
'version_id': blob['version_id'],
'size_gb': blob['size'] / (1024**3),
'tier': blob['blob_tier']
})
# Salvar relatório como blob para análise
report_client = client.get_blob_client("reports", f"version-audit-{datetime.utcnow().date()}.json")
report_client.upload_blob(str(candidates), overwrite=True)
13. Resumo Final​
Conceitos essenciais:
- Blob Versioning preserva automaticamente cópias anteriores de um blob em cada operação de escrita, sobrescrita ou deleção.
- Cada versão tem um Version ID único (timestamp ISO 8601) usado para acessar ou restaurar a versão especÃfica.
- A versão atual é acessada pela URL padrão. Versões anteriores requerem
?versionid=na URL. - Versioning é uma configuração de Storage Account e se aplica a todos os Block Blobs da conta.
Diferenças crÃticas:
- Versioning vs Snapshots: Versioning é automático em cada escrita. Snapshots são manuais (você decide quando criar).
- Delete com Versioning: Deletar um blob com versioning ativo transforma a versão atual em versão anterior, mas não a destrói. O blob parece deletado mas as versões existem e são cobradas.
- Soft Delete com Versioning: O Soft Delete passa a proteger versões deletadas individualmente, não o blob em si (pois o blob "deletado" já se torna uma versão anterior com versioning).
- Versioning e custo: Sem lifecycle policy para
version, o custo cresce indefinidamente. Esta é a consequência operacional mais crÃtica.
O que precisa ser lembrado:
- Versioning só está disponÃvel em Standard GPv2. Contas Premium não suportam.
- Versioning só afeta Block Blobs. Append e Page Blobs não são suportados.
- Versioning é pré-requisito para Object Replication e Point-in-time Restore.
- Sempre configure lifecycle policy para a seção
versionao habilitar versioning. - Desabilitar versioning não deleta versões existentes; elas continuam existindo e sendo cobradas.
- A restauração de uma versão anterior é uma operação de cópia, que cria uma nova versão atual e adiciona mais uma entrada no histórico.
- Versões em tier Hot são cobradas como blobs normais em Hot. Use lifecycle para movê-las para Cool ou Archive conforme envelhecem.