> ## Content Index
> Fetch the complete content index at: https://www.azurebrasil.cloud/llms.txt
> Use this file to discover other available public pages before exploring further.

# Quando uma Mudança Simples no GitOps Causa a Perda de Discos no Azure — E Por Que Ter um Parceiro Faz Toda a Diferença
- URL: https://www.azurebrasil.cloud/blog/quando-uma-mudanca-simples-no-gitops-causa-a-perda-de-discos-no-azure-e-por-que-ter-um-parceiro-faz-toda-a-diferenca/
- Published: 2026-03-09T12:00:11.000Z
- Updated: 2026-03-09T12:00:11.000Z
- Description: Quem trabalha com AKS sabe que o GitOps revolucionou o gerenciamento de infraestrutura. Com ferramentas como ArgoCD, o estado desejado do cluster fica declarado no Git e qualquer desvio é corrigido automaticamente. Mas e quando a automação interpreta uma mudança estrutural como ordem de destruição?
- Author: Rafael dos Santos
- Tags: case

> Era pra ser uma reestruturação simples de pastas no repositório Git. Minutos depois, os discos persistentes tinham sido removidos do Azure.

Quem trabalha com Kubernetes em produção sabe que o GitOps trouxe uma revolução na forma como gerenciamos infraestrutura. Ferramentas como o ArgoCD permitem que o estado desejado do cluster seja declarado em um repositório Git, e qualquer desvio é automaticamente corrigido. **Mas o que acontece quando essa automação interpreta uma mudança estrutural como uma instrução de destruição?**

Esse é o relato de um incidente real que vivenciamos com um cliente, onde uma cadeia de fatores — cada um aparentemente inofensivo isoladamente — culminou na remoção de discos persistentes no Azure. E mais importante: como a resposta rápida, possibilitada por uma parceria sólida, transformou o que poderia ter sido um desastre em um incidente controlado.

## O Cenário

O cliente operava um cluster **Azure Kubernetes Service (AKS)** com **ArgoCD** como ferramenta de GitOps para gerenciamento de configuração e deploy contínuo. A estrutura do repositório Git era organizada da seguinte forma:

```
cluster-configuration/
├── namespaces/
├── secrets/
├── storage-classes/
└── ...

```

Uma pipeline de CD (`ContinuousDelivery`) era responsável por acionar a sincronização do ArgoCD sempre que havia alterações no repositório. Essa pipeline existia como **contorno para um bug conhecido do ArgoCD**: quando o repositório é configurado via protocolo `git` (em vez de `https`), o WebHook do Azure DevOps não consegue notificar corretamente o ArgoCD sobre atualizações.

**O motivo?** O WebHook do Azure DevOps envia o caminho completo do repositório incluindo o protocolo HTTPS:

```
https://dev.azure.com/customer/Customer.Infra.ContinuousDelivery

```

Enquanto o ArgoCD, por ter clonado o repositório via protocolo `git`, espera algo como:

```
git@dev.azure.com/customer/Customer.Infra.ContinuousDelivery

```

O uso do protocolo `git` é **obrigatório** neste caso para permitir a associação de credenciais não pessoais no ArgoCD — uma boa prática de segurança que, ironicamente, criou a necessidade do workaround que contribuiu para o incidente.

### O Objetivo da Mudança

O time precisava adaptar o ArgoCD para suportar **dois clusters AKS**. A mudança consistia em reorganizar a estrutura de pastas, adicionando um nível com o nome do cluster:

```
cluster-configuration/
├── customer-brasilsouth/
│   ├── namespaces/
│   ├── secrets/
│   └── ...
└── customer-brasilsouth2/
    ├── namespaces/
    ├── secrets/
    └── ...

```

Além disso, o arquivo `argocd/applicationsets/cluster-addons.yaml` foi editado para interpretar o primeiro nível da estrutura de diretórios como o nome do cluster alvo de cada manifesto.

Uma mudança estrutural. Sem alteração em nenhum recurso do Kubernetes. **O que poderia dar errado?**

## A Cadeia de Eventos

O que aconteceu a seguir foi resultado de **cinco fatores independentes** que, combinados, criaram uma tempestade perfeita:

### 1\. A Pipeline Executou `sync` em Vez de `refresh`

Após o commit com a reestruturação, a pipeline `ContinuousDelivery` foi acionada. O mecanismo de sincronização dessa pipeline lista **todas** as Applications do ArgoCD e força um `sync` em cada uma delas.

> O comportamento adequado nesse cenário teria sido apenas um `refresh` — que atualiza o estado desejado sem forçar a reconciliação imediata de todos os recursos.

A diferença é crítica:

- **`refresh`**: o ArgoCD atualiza sua visão do estado desejado a partir do Git, mas não força alterações imediatas
- **`sync` forçado**: o ArgoCD aplica imediatamente todas as diferenças entre o estado atual do cluster e o estado desejado no Git

### 2\. Prune Resources e Self Heal Estavam Habilitados

A Application `argocd-configuration`, responsável por concentrar a configuração do ambiente, estava com as opções **Prune Resources** e **Self Heal** habilitadas.

- **Prune Resources**: quando um recurso existe no cluster mas não existe mais no Git, o ArgoCD o **remove**
- **Self Heal**: o ArgoCD corrige automaticamente qualquer desvio entre o cluster e o Git

Quando essa Application foi criada inicialmente via script, **essas opções não estavam ativas**. Até o momento, não há registros que indiquem quando essa configuração foi alterada — um ponto crítico de auditoria.

### 3\. StorageClasses com `ReclaimPolicy: Delete`

Os drivers de storage do AKS estavam configurados com `ReclaimPolicy: Delete`. Isso significa que, ao remover um **PVC (Persistent Volume Claim)**, o **disco correspondente também é removido do Azure**.

```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: managed-premium
provisioner: disk.csi.azure.com
reclaimPolicy: Delete    # <-- O problema está aqui

```

Caso estivesse configurado como `Retain`, o disco permaneceria no Azure mesmo após a exclusão do PVC — sem estar em uso pelo AKS, mas **recuperável**.

### 4\. O ArgoCD Interpretou a Reestruturação como "Deletar e Recriar"

Aqui está o ponto central do incidente. O comportamento **esperado** era:

> O ArgoCD interpretaria a nova estrutura de pastas no Git como o estado desejado atual do cluster e, portanto, não executaria nenhuma ação destrutiva.

O comportamento **observado** foi diferente — possivelmente em razão da ordem de processamento interno dos manifestos:

1. **Remoção** de todos os recursos anteriormente localizados em `cluster-configuration/*` — incluindo namespaces, secrets, e demais objetos
2. **Recriação** desses mesmos recursos a partir da nova estrutura em `cluster-configuration/customer-brasilsouth/`

### 5\. A Cascata: Namespace → PVCs → Discos

A remoção do namespace foi o gatilho que desencadeou a exclusão de **todos os recursos contidos nele**, incluindo os PVCs. E como a `ReclaimPolicy` era `Delete`, os discos no Azure foram permanentemente removidos.

```
Reestruturação de pastas no Git
    └── Pipeline força sync em todas as Applications
        └── ArgoCD com Prune + Self Heal detecta "recursos órfãos"
            └── Remove namespaces antigos
                └── Kubernetes remove todos os recursos do namespace (incluindo PVCs)
                    └── ReclaimPolicy: Delete remove os discos do Azure
                        └── 💥 Dados perdidos

```

## Por Que Isso Aconteceu?

Nenhum dos fatores isoladamente teria causado o incidente. Foi a **combinação** deles que gerou o cenário destrutivo:

| Fator                          | Impacto Isolado                                                                  | Impacto Combinado                                                            |
| ------------------------------ | -------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| Pipeline com forced sync       | Sincronização agressiva, mas sem efeitos destrutivos se Prune estiver desativado | Forçou a reconciliação imediata de todas as mudanças                         |
| **Prune Resources** habilitado | Remove recursos órfãos — útil em cenários controlados                            | Instruiu o ArgoCD a deletar recursos que "não existiam mais" no novo caminho |
| **Self Heal** habilitado       | Corrige drift automaticamente — desejável em operação normal                     | Impediu qualquer intervenção manual durante o processo                       |
| ReclaimPolicy: Delete          | Padrão do AKS — limpa discos não utilizados                                      | Transformou a exclusão temporária de PVCs em perda permanente de dados       |
| Bug do WebHook (git vs https)  | Necessidade de pipeline manual como workaround                                   | Criou o mecanismo que acionou o sync forçado                                 |

A lição mais importante aqui é que **sistemas complexos falham de formas complexas**. Cada configuração fazia sentido individualmente. Foi a interação entre elas que criou o comportamento destrutivo.

## Ações Imediatas

Assim que o incidente foi identificado, as seguintes ações foram tomadas:

1. **Suspensão da pipeline** com comportamento inadequado, para que o processo fosse ajustado e passasse a executar `refresh` em vez de `forced sync`
2. **Desativação do Prune e Self Heal** na Application `argocd-configuration` — a mais crítica do ambiente — para evitar ações destrutivas automáticas
3. **Criação de novas StorageClasses** com `ReclaimPolicy: Retain`, garantindo que futuros cenários de exclusão de PVCs não resultem na remoção dos discos no Azure:

```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: managed-premium-retain
provisioner: disk.csi.azure.com
reclaimPolicy: Retain    # Disco permanece no Azure mesmo após exclusão do PVC

```

1. **Abertura de chamado junto à Microsoft** para tentativa de recuperação dos discos removidos
2. **Migração das aplicações** para utilização dos novos drivers de storage configurados com `ReclaimPolicy: Retain`
3. **Desenvolvimento de script de migração de dados** para montagem simultânea do PVC antigo e do novo PVC, seguido da sincronização dos arquivos entre ambos — reproduzindo no novo PVC (já com `ReclaimPolicy: Retain`) o mesmo conteúdo existente no volume anterior

## Por Que Ter um Parceiro Azure Faz Toda a Diferença

Aqui entra a parte da história que muitas vezes é subestimada até o momento em que você **realmente precisa dela**.

### O Tempo é Tudo

Quando os discos foram removidos, o relógio começou a contar. A possibilidade de recuperação de discos no Azure depende de ação rápida — e cada minuto de atraso reduz as chances.

Veja a timeline do atendimento a este incidente:

| Etapa                                  | Horário (GMT-3 Brasília) | Tempo decorrido |
| -------------------------------------- | ------------------------ | --------------- |
| Abertura do ticket com a INGRAM BRASIL | **15:40**                | —               |
| Primeira resposta e ação               | **17:21**                | 1h41min         |
| Resolução do chamado                   | **19:57**                | 4h17min         |

**Pouco mais de 4 horas** entre a abertura do chamado e a resolução. Em um cenário de perda de dados em produção, essa velocidade pode ser a diferença entre **recuperar tudo** e **perder tudo**.

### O Cenário Sem um Parceiro

Já recebemos no passado contatos de empresas que **não eram nossos clientes**, buscando ajuda desesperadamente em situações críticas:

- **Exclusão acidental de banco de dados** em produção
- **Perda de acesso** a subscriptions inteiras do Azure
- **Corrupção de dados** sem backup recente

Sem um parceiro, o caminho dessas empresas era:

1. Descobrir que precisam de um **plano de suporte do Azure** (que não tinham)
2. Contratar um plano **on-demand** — processo que leva tempo e burocracia
3. Abrir o chamado e aguardar o atendimento **sem prioridade** estabelecida
4. Tentar explicar todo o contexto do ambiente para um engenheiro que nunca o viu antes

O resultado? **Horas ou dias** de atraso em situações onde **minutos** fazem diferença.

### O Que um Solutions Partner Oferece

Como **Microsoft Solutions Partner** — com especialização em 5 das 6 áreas de competência — oferecemos aos nossos clientes:

- **Suporte Premier 24x7**: acesso direto a engenheiros Microsoft com SLAs agressivos
- **Relacionamento pré-estabelecido**: quando o incidente acontece, não precisamos explicar quem somos ou configurar processos — tudo já está pronto
- **Conhecimento do ambiente**: entendemos a arquitetura do cliente, o que acelera drasticamente o diagnóstico
- **Canal direto com distribuidores**: a parceria com a **INGRAM BRASIL** nos permitiu escalar o chamado com velocidade e prioridade

### Agradecimento Especial: INGRAM BRASIL

Um agradecimento especial à equipe da **INGRAM BRASIL**, distribuidora que atua conosco neste cliente e foi **fundamental** para a resolução rápida deste incidente.

A INGRAM BRASIL foi essencial não apenas na abertura ágil do ticket com a Microsoft, mas em todo o acompanhamento até a resolução. A capacidade de resposta e o comprometimento da equipe demonstram por que ter um **ecossistema de parceiros sólido** — Partner + Distribuidor + Microsoft — é indispensável para quem roda workloads críticos no Azure.

> **A diferença entre um incidente e um desastre muitas vezes é o tempo de resposta. E tempo de resposta depende de relacionamentos construídos antes da crise.**

## Lições Aprendidas

1. **Sempre use `ReclaimPolicy: Retain` para dados críticos** — O padrão `Delete` é conveniente para ambientes efêmeros, mas em produção, um disco removido pode significar dados irrecuperáveis. Configure `Retain` e gerencie a limpeza de discos órfãos manualmente ou via automação controlada.
2. **Nunca habilite Prune e Self Heal em Applications críticas sem salvaguardas** — Essas opções são poderosas e úteis, mas em Applications que gerenciam a configuração base do cluster, o risco de ações destrutivas automáticas supera os benefícios. Se precisar habilitá-las, implemente políticas de proteção como `argocd.argoproj.io/sync-options: Prune=false` em recursos sensíveis.
3. **Use `refresh` em vez de `forced sync` em pipelines de CI/CD** — Um `refresh` permite que o ArgoCD atualize seu entendimento do estado desejado sem forçar a reconciliação imediata. Isso dá tempo para revisão e intervenção manual quando necessário.
4. **Audite configurações do ArgoCD regularmente** — A ativação do Prune e Self Heal na Application crítica aconteceu em algum momento sem registro. Implemente alertas ou políticas (por exemplo, via OPA/Gatekeeper) que detectem mudanças em configurações sensíveis de Applications.
5. **Teste mudanças de infraestrutura em ambientes não produtivos** — Reestruturações no repositório Git que afetam o mapeamento de Applications devem ser validadas em um cluster de staging antes de serem aplicadas em produção.
6. **Tenha um Solutions Partner antes de precisar de suporte emergencial** — Contratar suporte sob demanda durante uma crise é como tentar fazer seguro depois do acidente. O relacionamento, os processos e os canais de comunicação precisam estar estabelecidos **antes** do incidente.
7. **Documente todas as mudanças de configuração** — A ausência de registros sobre quando o Prune e Self Heal foram habilitados dificultou a análise de causa raiz. Mantenha um changelog auditável para configurações críticas de infraestrutura.

## Referências

### Kubernetes — Storage e ReclaimPolicy

- [Persistent Volumes — Reclaim Policy](https://kubernetes.io/docs/concepts/storage/persistent-volumes/?ref=azurebrasil.cloud#reclaiming) — Documentação oficial sobre as políticas de recuperação de volumes persistentes
- [Storage Classes](https://kubernetes.io/docs/concepts/storage/storage-classes/?ref=azurebrasil.cloud) — Como configurar StorageClasses com diferentes ReclaimPolicies
- [Azure Disk CSI Driver](https://learn.microsoft.com/en-us/azure/aks/azure-disk-csi?ref=azurebrasil.cloud) — Driver de disco gerenciado para AKS

### ArgoCD — Sync e Application Configuration

- [Sync Options](https://argo-cd.readthedocs.io/en/stable/user-guide/sync-options/?ref=azurebrasil.cloud) — Opções de sincronização incluindo Prune e Self Heal
- [Application Declaration](https://argo-cd.readthedocs.io/en/stable/user-guide/application-specification/?ref=azurebrasil.cloud) — Especificação de Applications e suas opções de sync policy
- [Webhooks](https://argo-cd.readthedocs.io/en/stable/operator-manual/webhook/?ref=azurebrasil.cloud) — Configuração de webhooks com provedores Git

### Azure — Suporte e Parceiros

- [Microsoft Solutions Partner](https://learn.microsoft.com/en-us/partner-center/introduction-to-pcs?ref=azurebrasil.cloud) — Programa de parceiros Microsoft e áreas de especialização
- [Planos de Suporte do Azure](https://azure.microsoft.com/en-us/support/plans/?ref=azurebrasil.cloud) — Comparação entre os planos de suporte disponíveis
- [INGRAM Micro Brasil](https://www.ingrammicro.com/pt-br/home?ref=azurebrasil.cloud) — Distribuidor parceiro Microsoft

*Você já passou por um incidente onde a resposta rápida de um parceiro fez a diferença? Ou já enfrentou uma situação crítica no Azure sem suporte adequado? Compartilhe sua experiência nos comentários — histórias reais ajudam toda a comunidade a se preparar melhor.*