Arte abstrata de destaque sobre um fundo azul-marinho escuro: um painel de comando arredondado com barras de texto abstratas situa-se no canto superior esquerdo, uma barra realçada em âmbar, e uma única linha âmbar desce a partir dela até ao mosaico da esquerda de uma ampla grelha de mosaicos de infraestrutura. Os mosaicos mantêm-se intactos no centro-esquerda e desfazem-se em fragmentos âmbar dispersos em direção ao bordo direito. Não aparecem textos, pessoas nem logótipos de organizações. O logótipo OrcaRouter está composto no canto inferior direito.
AI Safety Incidents

Claude Code executou terraform destroy na produção do DataTalks.Club

Autor

Alistair Wren

Data de publicação

Modelos mais recentes · 20Ver todos os modelos →
Benchmarks: Artificial Analysis · atualizado diariamente
Voltar para todas as publicações

Pouco antes das 23h de 26 de fevereiro de 2026, um agente do Claude Code executou terraform destroy na conta da AWS por trás da plataforma de cursos do DataTalks.Club e excluiu a stack de produção: a VPC, o cluster ECS, os balanceadores de carga, o host bastion e o banco de dados PostgreSQL no Amazon RDS. A plataforma continha 2,5 anos de submissões de alunos, tarefas de casa, projetos e entradas de ranking de todos os cursos realizados por meio dela, e os backups automatizados do RDS desapareceram no mesmo instante, sem deixar nada visível no console para restaurar. Alexey Grigorev, que administra o DataTalks.Club e publicou um post-mortem em primeira pessoa em 6 de março de 2026, recuperou os dados cerca de 24 horas depois apenas porque o suporte da AWS encontrou um snapshot interno que a própria conta dele não conseguia ver. O registro completo, incluindo sua lista de fontes e grau de confiança, está no Orca AI Incident Archive ao lado dos outros incidentes de infraestrutura causados por agentes que ele indexa.

A base de evidências é mais estreita do que os relatos sugerem, e vale declarar isso abertamente antes da sequência. Tudo o que é específico aqui remonta a Grigorev. O AI Incident Database traz dois relatos sobre o incidente — a publicação dele no Substack, "How I Dropped Our Production Database and Now Pay 10% More for AWS", e a matéria do Tom's Hardware de 7 de março de 2026, de Bruno Ferreira — e o segundo é um resumo do primeiro. Uma entrevista publicada pela empresa de gestão de incidentes Rootly acrescenta detalhes nas próprias palavras de Grigorev. Não foi publicada nenhuma declaração da Anthropic, nenhuma declaração da AWS nem nenhuma conclusão de órgão regulador sobre o evento. Sobre o que foi excluído, todos os relatos concordam; quando a história, tal como circulou, se afasta do que ele realmente escreveu, este artigo indica qual é qual.

Duas decisões que prepararam o terreno

A migração era um trabalho comum. Grigorev queria tirar o site do AI Shipping Labs do GitHub Pages e colocá-lo na AWS, com uma reescrita em Django na sequência. Em vez de construir um segundo ambiente, ele adicionou o site à configuração do Terraform que já geria a plataforma do curso por trás dos cursos Zoomcamp do DataTalks.Club — um sistema que guarda submissões, lições de casa, projetos e registros de leaderboard que remontam a 2,5 anos. Em seu post, ele estima a economia em $5 a $10 por mês e registra que o agente argumentou contra o arranjo: "Claude estava tentando me dissuadir, dizendo que eu deveria mantê-lo separado". Ele ordenou que ele colocasse tudo na VPC existente mesmo assim, porque não queria outra.

A segunda decisão foi mais silenciosa. O arquivo de estado do Terraform é o registro do que já existe. Grigorev havia se mudado recentemente para um computador novo e não tinha migrado esse arquivo, então, quando o deploy começou por volta das 22h de 26 de fevereiro, o plano assumiu uma conta vazia e começou a criar uma duplicata da infraestrutura. Ele viu a longa lista de recursos sendo criados, interrompeu o apply e perguntou por quê. A resposta do agente, segundo ele conta, foi que o Terraform acreditava que nada existia.

O destruir

O que se seguiu foi uma limpeza que se transformou no incidente. Grigorev pediu ao agente que descobrisse, por meio da AWS CLI, quais recursos eram duplicados recém-criados e quais eram de produção, e que excluísse apenas os novos. Enquanto isso rodava, ele voltou à máquina antiga, arquivou a pasta do Terraform com o arquivo de estado dentro dela e copiou o arquivo compactado para o outro lado, depois apontou o agente para ele para que os dois conjuntos de recursos pudessem ser comparados. Segundo o relato dele, ele não percebeu que o agente descompactou o arquivo, nem que substituiu o arquivo de estado ativo pelo mais antigo que havia dentro — aquele que descrevia os recursos de produção.

Com esse estado em vigor, a próxima proposta do agente seguiu sua própria lógica. No post, Grigorev o cita: “Não posso fazer isso. Vou executar um terraform destroy. Como os recursos foram criados por meio do Terraform, destruí-los por meio do Terraform seria mais limpo e simples do que pela AWS CLI.” Ele concordou e disse ao Rootly: “Sim, o Claude executou terraform destroy, eu vi e não o impedi.” Ele também disse, sobre a troca de estado: “Eu não sabia que o estado havia sido trocado.” O comando foi executado com auto-approve por volta das 23h, então nada pausou para perguntar uma segunda vez.

Os dois relatos apresentam a proposta do agente de maneiras diferentes — a entrevista da Rootly a traz como “é entediante excluir esses um por um, que tal eu simplesmente executar terraform destroy?” —, mas ambos descrevem a mesma estrutura: o destroy oferecido como uma limpeza, e um operador que acreditava que apenas as duplicatas estavam no escopo deixando-o rodar. O mecanismo da falha não é que o agente tenha entendido mal o comando. É que o agente estava raciocinando corretamente a partir de um arquivo de estado que descrevia a produção, e seu operador não tinha como ver que o arquivo havia mudado.

HTML card headed 'The night of 26 to 27 February 2026, as Grigorev records it'. A vertical timeline lists: about 10:00 PM on Thursday 26 February, Terraform deploy begins without the state file, which was still on the old laptop; about 11:00 PM, a terraform command with auto-approve deletes the production infrastructure including the RDS database; about 12:00 AM, a support ticket is opened and the account is upgraded to AWS Business Support; about 12:30 AM, AWS support confirms a snapshot exists on their side; about 1 to 2 AM, a phone call is escalated to an internal AWS team; during Friday, backups, deletion protection and S3 state are put in place; about 10:00 PM on Friday 27 February, the database is restored and the platform is back online. A note at the foot reads 'Times are approximate and are the operator's own; all of them are local to him.'

O que foi destruído

O arquivo de estado a partir do qual o agente estava agora trabalhando descrevia a produção, então o destroy planejou a exclusão da produção. Grigorev lista o que foi destruído:

• A VPC que abrigava todo o ambiente.

• O cluster ECS que executa a aplicação.

• Os balanceadores de carga à sua frente.

• O host bastion usado para acessar a rede privada.

• O banco de dados Amazon RDS que armazena os dados da plataforma do curso.

• Os snapshots automatizados do RDS que deveriam tornar tudo o que foi mencionado acima recuperável.

O último item é o que transformou uma indisponibilidade em um susto de perda de dados. Na entrevista à Rootly, a explicação de Grigorev é que excluir um banco de dados gerenciado na AWS também remove seus backups automatizados associados; na publicação, o suporte da AWS confirmou a ele que seu banco de dados e todos os snapshots haviam sido excluídos e que "a solicitação de API claramente dizia à AWS para excluir tudo". Qualquer que tenha sido a forma como a exclusão se propagou, o efeito às 23h foi o que importou: a cópia na qual ele vinha confiando foi removida pela mesma operação que o original.

HTML card headed 'What the destroy removed, and what it did not'. The left column, headed 'Deleted', lists the VPC, the ECS cluster, the load balancers, the bastion host, the Amazon RDS PostgreSQL database and the automated RDS snapshots. The right column, headed 'Not deleted', reads: no report of data being copied or exposed, this was deletion rather than disclosure; and the data itself, recovered from an AWS internal snapshot roughly 24 hours later. A strip below reads '2.5 years of submissions, homework, projects and leaderboard entries for every course run through the platform', and a highlighted line reads '1,943,200 rows in the courses_answer table when the restore was verified — one table, used as a completeness check, not a count of the whole database.'

A recuperação de 24 horas

O primeiro problema era que os backups pareciam ter desaparecido, e o segundo era que um deles não tinha. Grigorev sabia que um snapshot era feito todas as noites às 2 da manhã. No console do RDS, não encontrou nenhum, mas a lista de Eventos do RDS ainda mostrava que um backup havia sido criado; clicar nele não abria nada. Ele não conseguia dizer se o snapshot havia sido excluído ou se simplesmente havia se tornado invisível.

Ele abriu um chamado de suporte por volta da meia-noite e depois fez upgrade da conta para o AWS Business Support após notar o compromisso de resposta em uma hora para incidentes de produção. O upgrade acrescentou cerca de 10 por cento à fatura da AWS, que é a origem do título do post dele. O suporte respondeu em cerca de 40 minutos, confirmou a exclusão e disse que existia um snapshot do lado da AWS que ele não conseguia ver no console. Seguiu-se uma chamada de 40 a 60 minutos, que foi escalada para uma equipe interna. Exatamente 24 horas após a exclusão do banco de dados, a AWS restaurou o snapshot e ele apareceu no console dele; ele reconstruiu a instância a partir dele via Terraform. Enquanto esperava, ele havia reconstruído a infraestrutura ao redor e consolidado vários balanceadores de carga em um só.

O banco de dados restaurado continha 1.943.200 linhas na courses_answer tabela, que ele cita como a verificação de que a restauração estava completa. Esse número é frequentemente repetido como o tamanho da perda. É a contagem de linhas de uma tabela, usada como evidência de que os dados voltaram — não um total do banco de dados, e não uma contagem de alunos afetados, que nenhuma das fontes fornece.

O alerta que nunca houve

Várias recontagens trazem a afirmação de que Claude alertou Grigorev de antemão e foi ignorado. O que as fontes sustentam é mais restrito, e a diferença muda aquilo de que este caso é exemplo. O agente de fato argumentou contra a configuração compartilhada do Terraform antes de qualquer destruição, e esse conselho foi rejeitado. Nenhum dos relatos de Grigorev descreve o agente alertando que o destroy atingiria a produção. Ele diz que não sabia que o arquivo de estado tinha sido trocado, e em ambos os relatos a proposta do agente é apresentada como uma limpeza, e não como um risco sinalizado e dispensado. O alerta que foi ignorado era sobre arquitetura, mais cedo na migração, não sobre o comando.

Essa distinção separa duas falhas diferentes. Um agente que percebe o perigo e é anulado por uma decisão superior é uma questão de governança sobre uma decisão humana. Um agente que não sabe que o perigo existe, porque o arquivo que descreve o mundo mudou por baixo dele, é uma questão de ferramental sobre estado, permissões e portões de aprovação. O relato de Grigorev é o segundo caso, e a própria classificação do arquivo reflete isso: o registro carrega a tag ROGUE do arquivo para uma ação de agente que se desviou do que seu operador pretendia, e a entrada do AI Incident Database subjacente a ele classifica a intenção como não intencional, sob a taxonomia MIT 7.3, falta de capacidade ou robustez, no domínio de risco de segurança, falhas e limitações de sistemas de IA, no estágio pós-implantação. O banco de dados prefixa sua lista de entidades com “alleged”, seu enquadramento padrão para um caso autorrelatado que nenhuma autoridade julgou.

Onde a culpa recaiu

Grigorev não o distribui. “Este incidente foi culpa minha”, ele escreve, listando três causas: ele tratou plan, apply e destroy como delegáveis; confiou em backups que nunca havia testado restaurar; e o banco de dados era fácil demais de excluir. Ele observa que, enquanto esperava pela AWS, teve de considerar que os dados poderiam ter desaparecido permanentemente — para o curso de Engenharia de Dados, então em seus módulos finais, ele já planejava uma recuperação, e para cursos mais antigos, uma restauração malsucedida teria sido o fim deles.

A avaliação do Tom's Hardware, publicada no dia seguinte ao post dele, é substancialmente a mesma: "os erros podem ser atribuídos a supervisão inadequada". A crítica dela vai mais longe que a dele, apontando para credenciais amplas concedidas ao agente e permissões que nunca foram restringidas para um ambiente de produção. Nenhum regulador, órgão de normalização ou fornecedor se pronunciou. Não há CVE aqui, nem divulgação de vulnerabilidade, nem jailbreak de modelo: o agente não foi enganado, recebeu confiança excessiva.

O que mudou depois

Grigorev implementou as salvaguardas enquanto a AWS ainda trabalhava na restauração, e as publicou como uma lista. Nas palavras dele e na ordem dele:

• Backups que o Terraform não gerencia, além de cópias baseadas em S3 armazenadas separadamente do banco de dados e do estado da infraestrutura.

• Teste de restauração noturno: o backup automatizado das 2h é usado por volta das 3h para criar uma nova instância de banco de dados, o que leva de 20 a 30 minutos, e então uma Lambda orquestrada pelo Step Functions verifica, com uma consulta de leitura simples, se ela está utilizável, antes que a instância seja parada em vez de excluída. A cópia de ontem é removida, de modo que sempre há uma réplica recente disponível.

• Proteção contra exclusão em dois níveis, na configuração do Terraform e na própria AWS. Ele observa que essas proteções ainda podem ser removidas por qualquer pessoa que as desative explicitamente, mas que isso adiciona atrito.

• Versionamento nos backups do S3, de modo que a exclusão mantém versões anteriores e esvaziar um bucket exige excluir seu conteúdo primeiro.

O estado do Terraform foi movido para o S3, o que elimina a condição que deu origem a isso — um arquivo de estado que existia apenas em um laptop e desapareceu quando ele trocou de máquina.

• O agente não executa mais o Terraform de forma alguma. “Todas as permissões estão desativadas. Nenhuma execução automática. Nenhuma gravação em arquivo”, escreve ele. O fluxo de trabalho agora é gerar um plano, revisá-lo manualmente e executar os comandos ele mesmo. O novo projeto também recebeu sua própria configuração separada do Terraform.

Nem toda recomendação foi acatada. Na entrevista à Rootly, ele diz que manteve uma única conta da AWS, considerando que contas separadas de desenvolvimento e produção e um pipeline de aprovação como o Atlantis eram mais do que um operador individual precisa. Essa é a forma honesta do rescaldo: as correções são reais, e são as correções que uma pessoa consegue manter sozinha.

O que este registro é, e o que não é

É um incidente operacional documentado e autorrelatado, com danos reais financeiros e de disponibilidade, e é incomumente legível porque a pessoa a quem aconteceu registrou toda a sequência, incluindo as partes que foram erro dela mesma. Não é evidência de que um modelo tenha perseguido um objetivo próprio, e a etiqueta ROGUE do arquivo deve ser lida como descrevendo a divergência entre a ação do agente e a intenção de seu operador, e não qualquer intenção por parte do agente.

O detalhe que vale a pena levar é o que salvou os dados. Os backups do próprio Grigorev foram excluídos junto com o banco de dados que protegiam, e seu snapshot noturno era invisível para ele, mesmo com o log de eventos insistindo que existia. O que restaurou dois anos e meio de trabalhos de curso foi uma cópia mantida do lado da AWS sobre a qual ele nunca soubera e que não teria podido testar. Um backup do qual você nunca restaurou é uma crença, não um controle — e, neste caso, a crença acabou sendo verdadeira apenas porque outra pessoa mantinha uma segunda cópia.

Abstract closing artwork on a dark navy field: on the left, a wide rectangle of infrastructure tiles sits collapsed into broken segments and scattered fragments; on the right, outside the boundary of that rectangle, a single small tile glows intact on its own, connected to nothing. Thin amber lines from the wreckage reach toward it but stop short. No text, no people and no organisation logos appear. The OrcaRouter logo is composited in the bottom-right corner.