Pular para o conteúdo principal

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​

100%
Scroll para zoom · Arraste para mover · 📱 Pinch para zoom no celular

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 version nas 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.

100%
Scroll para zoom · Arraste para mover · 📱 Pinch para zoom no celular

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çãoCria 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)SimVersão atual vira versão anterior; novo conteúdo vira versão atual
Modificação de metadadosSimVersão com metadados antigos vira versão anterior
Modificação de tags de índiceNãoTags não criam nova versão
Set Blob Tier (mudança de camada)NãoTier muda na versão atual
Delete BlobSim (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.

100%
Scroll para zoom · Arraste para mover · 📱 Pinch para zoom no celular

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:

  1. Blob Versioning habilitado
  2. Soft Delete habilitado
  3. 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​

100%
Scroll para zoom · Arraste para mover · 📱 Pinch para zoom no celular

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.

100%
Scroll para zoom · Arraste para mover · 📱 Pinch para zoom no celular

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: daysAfterCreationGreaterThan no contexto de version refere-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çãoRole mínima
Listar versõesStorage Blob Data Reader
Ler conteúdo de uma versãoStorage Blob Data Reader
Deletar uma versão específicaStorage Blob Data Contributor
Promover versão para atual (copy)Storage Blob Data Contributor
Habilitar/desabilitar versioningStorage 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​

AspectoBlob VersioningSnapshots manuais
AutomatismoAutomático em cada escritaManual (você decide quando criar)
GranularidadePor operação de escritaApenas quando você cria
GestãoRequer lifecycle policyRequer processo manual de limpeza
CustoPotencialmente alto sem lifecycleControlável (você controla quando cria)
RecuperaçãoPor Version ID específicoPor timestamp do snapshot
Uso recomendadoProteção contínua contra sobrescritaBackup antes de operação específica

8.2 Quando habilitar Versioning​

SituaçãoHabilitar Versioning?Motivo
Dados críticos modificados frequentementeSimProteção automática contra sobrescrita
Blobs write-once (logs, backups)Não necessariamenteDados nunca são sobrescritos; Soft Delete é suficiente
Requisito de Object ReplicationSim (obrigatório)Pré-requisito
Requisito de Point-in-time RestoreSim (obrigatório)Pré-requisito
Conta Premium Block BlobNão disponívelPremium não suporta versioning
Conta com grande volume e alto custoAvaliarLifecycle policy é obrigatória para controlar custo

8.3 Configuração complementar recomendada​

FuncionalidadeHabilitar junto com Versioning?Motivo
Soft Delete de blobSimProtege versões deletadas individualmente
Soft Delete de containerSimProtege container e todas as versões
Change FeedSim para PITRNecessário para Point-in-time Restore
Lifecycle policy para versõesSempreControle de custo obrigatório
Immutability PolicyPara complianceTorna 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 tierToCool após 30 dias e delete apó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​

ErroPor que aconteceComo evitar
Custo explosivo após habilitar versioningSem lifecycle policy para versões; blobs modificados frequentementeSempre criar lifecycle policy para version simultaneamente
Blob "deletado" ainda aparece nos custosDelete com versioning não remove versões anterioresDeletar explicitamente cada versão após deletar o blob atual
Restauração cria versão extra indesejadaCopy de versão anterior cria nova versão atualComportamento esperado; documentar e incluir na lifecycle policy
Versioning não funciona em conta PremiumPremium Block Blob não suporta versioningUsar Standard GPv2 para dados que precisam de versioning
Object Replication falhaVersioning não habilitado em uma das contasHabilitar versioning em ambas as contas antes de configurar replicação
PITR não disponívelVersioning, Soft Delete ou Change Feed não habilitadosHabilitar os três simultaneamente
Versões em Hot não incluídas em lifecycleLifecycle policy sem seção versionSempre incluir seção version nas regras de lifecycle
Version ID difícil de encontrarNão documentado após operação de uploadCapturar 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​

AspectoLimite
Tipos de blob suportadosApenas Block Blobs
Tipos de conta suportadosStandard GPv2
Número máximo de versões por blobSem limite documentado (prático: controlar via lifecycle)
Version IDTimestamp com precisão de 100ns; único por blob
Desabilitação do versioningPossí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 version ao 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.