Recuperando Arquivos Deletados no S3 com Versionamento
Você deletou um arquivo no S3 e só percebeu depois. Se o bucket tinha versionamento habilitado no momento da deleção, o objeto não foi destruído — ele foi ocultado por um delete marker. Este guia mostra exatamente como localizar e restaurar a versão anterior usando AWS CLI e Console.
TL;DR — Recuperando Arquivos Deletados no S3
| Situação | O que aconteceu | Como recuperar |
|---|---|---|
| Versionamento ativo, DELETE simples | Delete marker criado, versão anterior intacta | Remover o delete marker via CLI ou Console |
| Versionamento ativo, DELETE com version ID | Versão específica permanentemente removida | Restaurar a versão imediatamente anterior |
| Versionamento nunca habilitado | Objeto destruído permanentemente | Não há recuperação nativa |
| Versionamento suspenso | Comportamento misto — depende do histórico do objeto | Verificar se existe versão com ID não-null |
Como o Versionamento do S3 Funciona na Prática
Antes de executar qualquer comando de recuperação, é essencial entender o mecanismo — caso contrário, você pode deletar a versão errada e tornar a recuperação impossível.
Quando o versionamento está ativo, o S3 não sobrescreve nem apaga objetos. Cada operação de escrita gera uma nova versão com um ID único. Uma operação DELETE sem especificar um version ID não remove nenhuma versão — ela insere um objeto especial chamado delete marker, que passa a ser a versão atual da chave.
- PUT inicial: objeto criado com version ID
v1. - PUT subsequente: nova versão
v2criada;v1permanece armazenada. - DELETE simples: um delete marker é inserido como versão atual. As versões
v1ev2continuam no bucket, apenas ocultas. - GET após DELETE: o S3 encontra o delete marker como versão atual e retorna HTTP 404 Not Found — não um erro de método, mas de recurso não encontrado.
Recuperar o arquivo significa, na maioria dos casos, apenas remover esse delete marker.
Pense no delete marker como um post-it colado na frente do arquivo numa gaveta. O arquivo continua lá — você só precisa tirar o post-it.
Comportamento com Versionamento Suspenso
Um bucket com versionamento suspenso tem comportamento misto. Objetos que já possuíam versões com IDs não-null antes da suspensão continuam com esse histórico preservado — uma operação DELETE nesses objetos ainda cria um delete marker. Já objetos criados após a suspensão recebem version ID null, e uma operação DELETE neles remove permanentemente essa versão null sem criar delete marker. Se você opera em um bucket suspenso, verifique o histórico de versões antes de assumir que a recuperação é possível.
Pré-requisito: Confirmar que o Versionamento Estava Ativo
Antes de qualquer tentativa de recuperação, confirme o estado atual do versionamento. Um bucket pode estar Enabled, Suspended, ou nunca ter sido configurado.
aws s3api get-bucket-versioning \
--bucket nome-do-seu-bucket
Se a resposta retornar {} (objeto vazio), o versionamento nunca foi habilitado e não há versões anteriores para recuperar. Se retornar "Status": "Enabled", prossiga com os passos abaixo.
Passo 1 — Localizar o Delete Marker e as Versões Anteriores
Liste todas as versões e delete markers da chave deletada. Esse comando retorna o histórico completo do objeto, incluindo o delete marker inserido pela operação DELETE.
aws s3api list-object-versions \
--bucket nome-do-seu-bucket \
--prefix caminho/para/seu-arquivo.txt
A saída terá duas seções relevantes: Versions (versões reais do objeto) e DeleteMarkers. Identifique e anote dois valores:
- O
VersionIddo delete marker (emDeleteMarkers, com"IsLatest": true). - O
VersionIdda versão que você quer restaurar (emVersions, geralmente a mais recente antes do delete marker).
🔽 Exemplo de saída do list-object-versions (clique para expandir)
{
"DeleteMarkers": [
{
"Owner": { "DisplayName": "...", "ID": "..." },
"Key": "caminho/para/seu-arquivo.txt",
"VersionId": "abc123XYZdeleteMarkerID",
"IsLatest": true,
"LastModified": "2024-01-15T10:30:00.000Z"
}
],
"Versions": [
{
"ETag": "\"d41d8cd98f00b204e9800998ecf8427e\"",
"Size": 204800,
"StorageClass": "STANDARD",
"Key": "caminho/para/seu-arquivo.txt",
"VersionId": "xyz789ABCversionID",
"IsLatest": false,
"LastModified": "2024-01-14T08:00:00.000Z"
}
]
}
Passo 2 — Remover o Delete Marker para Recuperar Arquivos Deletados no S3
Remover o delete marker é o que efetivamente restaura o objeto. Quando o delete marker é deletado, a versão anterior mais recente volta a ser a versão atual da chave — sem necessidade de copiar ou mover nada.
aws s3api delete-object \
--bucket nome-do-seu-bucket \
--key caminho/para/seu-arquivo.txt \
--version-id abc123XYZdeleteMarkerID
Substitua abc123XYZdeleteMarkerID pelo VersionId do delete marker identificado no Passo 1. Note que você está usando delete-object para deletar o próprio delete marker — é contra-intuitivo, mas é o mecanismo correto.
Após executar o comando, verifique se o objeto está acessível novamente:
aws s3api head-object \
--bucket nome-do-seu-bucket \
--key caminho/para/seu-arquivo.txt
Uma resposta HTTP 200 com os metadados do objeto confirma a restauração bem-sucedida.
Passo 3 — Restaurar uma Versão Específica (Alternativa)
Se você precisa restaurar uma versão específica que não é a mais recente — por exemplo, o arquivo foi sobrescrito várias vezes e você quer uma versão de dois dias atrás — o processo é diferente. Em vez de remover o delete marker, você copia a versão desejada sobre a chave atual, tornando-a a nova versão mais recente.
aws s3api copy-object \
--bucket nome-do-seu-bucket \
--copy-source nome-do-seu-bucket/caminho/para/seu-arquivo.txt?versionId=xyz789ABCversionID \
--key caminho/para/seu-arquivo.txt
Esse comando cria uma nova versão do objeto com o conteúdo da versão xyz789ABCversionID. O histórico anterior permanece intacto. Substitua xyz789ABCversionID pelo VersionId da versão que você quer restaurar, identificado no Passo 1.
Permissões IAM Necessárias
Para executar os comandos acima, a identidade IAM precisa das seguintes permissões no bucket e nos objetos. Aplique o princípio do menor privilégio — restrinja ao bucket e prefixo específicos.
🔽 Política IAM mínima para recuperação (clique para expandir)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListVersions",
"Effect": "Allow",
"Action": [
"s3:ListBucketVersions",
"s3:GetBucketVersioning"
],
"Resource": "arn:aws:s3:::nome-do-seu-bucket"
},
{
"Sid": "RestoreObject",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion",
"s3:DeleteObjectVersion",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::nome-do-seu-bucket/caminho/para/*"
}
]
}
A ação s3:DeleteObjectVersion é necessária especificamente para remover o delete marker no Passo 2. Sem ela, o comando retorna AccessDenied mesmo que a identidade tenha permissão de s3:DeleteObject.
Diagnóstico: Quando a Recuperação Não Funciona Como Esperado
Esse é o tipo de situação que aparece às 2h da manhã: você executou os passos, o head-object retorna 200, mas o conteúdo está errado. Ou pior — o list-object-versions não mostra nenhuma versão anterior ao delete marker.
Sintoma → Diagnóstico incorreto → Causa real:
O erro mais comum é assumir que qualquer DELETE cria um delete marker recuperável. A suposição falha quando o objeto foi criado em um bucket com versionamento suspenso — nesse caso, a versão tem ID null e um DELETE a remove permanentemente, sem criar delete marker. O list-object-versions vai mostrar a seção DeleteMarkers vazia para essa chave.
Outros cenários que bloqueiam a recuperação:
- Lifecycle Policy com
NoncurrentVersionExpiration: versões antigas podem ter sido expiradas automaticamente. Verifique comaws s3api get-bucket-lifecycle-configuration --bucket nome-do-seu-bucket. - DELETE com version ID explícito: se o DELETE original especificou um version ID, aquela versão foi permanentemente removida — não há delete marker, e não há recuperação para essa versão específica.
- Object Lock com modo COMPLIANCE: versões bloqueadas não podem ser deletadas antes do período de retenção, mas também não podem ser restauradas por cima se o lock estiver ativo.
Recuperação pelo Console AWS (Alternativa Visual)
Se preferir o Console, o processo é equivalente:
- Acesse o bucket no Console do S3.
- Ative a exibição de versões clicando em 'Mostrar versões' no topo da listagem de objetos.
- Localize o arquivo — ele aparecerá com uma entrada marcada como 'Marcador de exclusão' com ícone diferenciado.
- Selecione o delete marker e clique em 'Excluir'. Confirme a operação digitando o texto solicitado.
- O objeto original voltará a aparecer na listagem normal.
Próximos Passos e Prevenção
Recuperar o arquivo resolve o problema imediato. Para evitar a recorrência, considere as seguintes configurações:
- MFA Delete: exige autenticação multifator para deletar versões específicas ou alterar o estado do versionamento. Habilitado via
aws s3api put-bucket-versioningcomMFADelete: Enabled— requer credenciais root da conta. - S3 Object Lock: para objetos críticos, o modo GOVERNANCE ou COMPLIANCE impede deleção durante o período de retenção configurado.
- Lifecycle Policy para versões antigas: sem uma política, versões antigas acumulam indefinidamente e geram custo. Configure
NoncurrentVersionExpirationcom um período adequado ao seu RTO. - S3 Replication: replicação cross-region ou cross-account como camada adicional de proteção contra deleção acidental em nível de bucket.
Documentação oficial de referência: Restoring previous versions — Amazon S3 User Guide.
Glossário
| Termo | Definição |
|---|---|
| Delete Marker | Objeto especial inserido pelo S3 quando um DELETE é executado sem version ID em um bucket com versionamento ativo. Não contém dados — apenas sinaliza que a chave está 'deletada' para requisições sem version ID. |
| Version ID | Identificador único e imutável atribuído a cada versão de um objeto em um bucket com versionamento ativo. |
| Versionamento Suspenso | Estado em que o bucket para de gerar novos version IDs para objetos criados após a suspensão. Versões existentes com IDs não-null são preservadas. |
| MFA Delete | Camada adicional de proteção que exige autenticação multifator para operações de deleção de versões específicas ou alteração do estado de versionamento. |
| NoncurrentVersionExpiration | Regra de Lifecycle Policy que expira automaticamente versões não-atuais de objetos após um número configurável de dias. |
Comentários
Postar um comentário