Skip to content

Disaster Recovery e Continuidade

Plano de recuperação de desastres e continuidade de negócio para o site UNICEF Portugal.

1. Identificação de Riscos

Risco Probabilidade Impacto Mitigação
App Service crash/hang Alta (atual) Alto Always On + Auto Heal + Health Check
SQL Database corrupção Baixa Crítico Backups automáticos Azure (PITR)
SQL DTU throttling Média Alto Monitorização + escalamento
Storage account indisponível Muito baixa Alto Redundância LRS
Front Door/CDN falha Muito baixa Alto Failover automático Azure
Perda de código fonte Muito baixa Crítico Azure DevOps + GitHub mirror
Credential leak Baixa Crítico Key Vault + rotação

2. Backup e Restauro

Azure SQL (PITR - Point In Time Restore)

O Azure SQL Standard tier oferece 14 dias de retenção de backups automáticos. É possível restaurar a base de dados para qualquer ponto nos últimos 14 dias.

# Restaurar para um ponto no tempo
az sql db restore \
  --dest-name uncdb-prd-restored \
  --edition Standard \
  --service-objective S1 \
  --time "2026-04-13T12:00:00Z" \
  --resource-group unc-prd \
  --server uncsqlsrv-prd \
  --name uncdb-prd \
  --subscription 2e6c7ed6-c6f8-4058-901c-c3113a4df82a

Nota

Após o restore, a nova base de dados terá o nome uncdb-prd-restored. Será necessário atualizar a connection string do App Service para apontar para a nova BD, ou renomear as bases de dados.

Blob Storage

Propriedade Valor
Storage account uncstorageprd
Redundância LRS (Locally Redundant Storage)
Conteúdo Media e imagens do Umbraco

Para backup manual do blob storage:

az storage blob download-batch \
  --destination ./backup \
  --source <container> \
  --account-name uncstorageprd \
  --subscription 2e6c7ed6-c6f8-4058-901c-c3113a4df82a

Recomendação

Ativar soft delete e versioning no blob storage para proteção adicional contra eliminação acidental.

Codigo fonte

Localização URL
Azure DevOps (principal) https://dev.azure.com/double-pt/Unicef/_git/Unicef
GitHub (mirror) https://github.com/BetacodeTech/UNC.PublicPortal.git

Importante

Garantir que ambos os repositórios estão sincronizados. Verificar periodicamente que o mirror no GitHub está atualizado.

3. Procedimento de Recuperação Total

flowchart TD A[Incidente detetado] --> B{Identificar o problema} B -->|App Service| C[Restart do App Service] B -->|Base de dados| D[Verificar SQL Server] B -->|Storage| E[Verificar Blob Storage] B -->|DNS/Rede| F[Verificar Azure DNS] C --> C1{Resolveu?} C1 -->|Sim| Z[Monitorizar e documentar] C1 -->|Nao| C2[Redeploy do staging slot] C2 --> C3{Resolveu?} C3 -->|Sim| Z C3 -->|Nao| C4[Escalar App Service Plan] C4 --> C5{Resolveu?} C5 -->|Sim| Z C5 -->|Nao| X[Escalar para equipa dev] D --> D1{SQL acessivel?} D1 -->|Nao| D2[Verificar firewall e estado do servidor] D1 -->|Sim mas lento| D3[DTU throttling?] D3 -->|Sim| D4[Escalar tier SQL temporariamente] D1 -->|Dados corrompidos| D5[PITR Restore] D5 --> D6[Criar BD restaurada] D6 --> D7[Atualizar connection string] D7 --> D8[Restart App Service] D8 --> Z D4 --> Z D2 --> Z E --> E1{Container acessivel?} E1 -->|Nao| E2[Verificar estado do storage account] E1 -->|Ficheiros em falta| E3[Restaurar de backup] E2 --> Z E3 --> Z F --> F1[Verificar registos DNS Azure] F1 --> F2{DNS correto?} F2 -->|Nao| F3[Corrigir registos DNS] F2 -->|Sim| F4[Verificar Front Door / CDN] F3 --> Z F4 --> Z X --> Z

Passo a passo detalhado

Se o problema é o App Service

  1. Restart: Ver Runbook de Restart
  2. Redeploy: Swap com staging slot
  3. Escalar: Aumentar tier do App Service Plan temporariamente

Se o problema é a base de dados

  1. Verificar acesso:

    az sql db show \
      --name uncdb-prd \
      --server uncsqlsrv-prd \
      --resource-group unc-prd \
      --subscription 2e6c7ed6-c6f8-4058-901c-c3113a4df82a
    

  2. PITR Restore (se necessário):

    az sql db restore \
      --dest-name uncdb-prd-restored \
      --edition Standard \
      --service-objective S1 \
      --time "2026-04-13T12:00:00Z" \
      --resource-group unc-prd \
      --server uncsqlsrv-prd \
      --name uncdb-prd \
      --subscription 2e6c7ed6-c6f8-4058-901c-c3113a4df82a
    

  3. Atualizar connection string do App Service:

    az webapp config connection-string set \
      --name uncwebprd \
      --resource-group unc-prd \
      --connection-string-type SQLAzure \
      --settings umbracoDbDSN="Server=tcp:uncsqlsrv-prd.database.windows.net,1433;Database=uncdb-prd-restored;..." \
      --subscription 2e6c7ed6-c6f8-4058-901c-c3113a4df82a
    

Se o problema é o storage

  1. Verificar estado:

    az storage account show \
      --name uncstorageprd \
      --resource-group unc-prd \
      --subscription 2e6c7ed6-c6f8-4058-901c-c3113a4df82a
    

  2. Listar containers:

    az storage container list \
      --account-name uncstorageprd \
      --subscription 2e6c7ed6-c6f8-4058-901c-c3113a4df82a
    

Se o problema é DNS

  1. Verificar registos DNS no Azure Portal
  2. Confirmar que o dominio www.unicef.pt aponta para o App Service correto
  3. Verificar certificado SSL

4. Monitorização Proativa (A IMPLEMENTAR)

As seguintes medidas de monitorização devem ser implementadas para detetar problemas antes que afetem os utilizadores.

Application Insights

Ativar Application Insights no App Service para recolha de telemetria:

  • Tempo de resposta dos pedidos
  • Taxa de erros
  • Exceções do servidor
  • Utilização de memória e CPU

Availability Tests (Testes de Disponibilidade)

Configurar testes automáticos de disponibilidade:

Teste 1 - Homepage Ping:

  • URL: https://www.unicef.pt
  • Frequência: A cada 5 minutos
  • Localizações: 5 regiões diferentes
  • Timeout: 120 segundos
az monitor app-insights web-test create \
  --web-test-name "Homepage-Ping" \
  --resource-group unc-prd \
  --location northeurope \
  --defined-web-test-name "Homepage Ping Test" \
  --web-test-kind "ping" \
  --subscription 2e6c7ed6-c6f8-4058-901c-c3113a4df82a \
  --urls "https://www.unicef.pt" \
  --frequency 300 \
  --timeout 120 \
  --enabled true

Teste 2 - API Ping:

  • URL: https://www.unicef.pt/umbraco/Api/ContentApi/GetData/?url=/
  • Frequência: A cada 5 minutos
  • Validação: Resposta HTTP 200 com conteúdo JSON
az monitor app-insights web-test create \
  --web-test-name "API-Ping" \
  --resource-group unc-prd \
  --location northeurope \
  --defined-web-test-name "API Ping Test" \
  --web-test-kind "ping" \
  --subscription 2e6c7ed6-c6f8-4058-901c-c3113a4df82a \
  --urls "https://www.unicef.pt/umbraco/Api/ContentApi/GetData/?url=/" \
  --frequency 300 \
  --timeout 120 \
  --enabled true

Alert Rules (Regras de Alerta)

Configurar os seguintes alertas:

Métrica Condição Ação
Response time > 10s durante 5 minutos Email equipa
Failed requests > 10% durante 5 minutos Email equipa
Server exceptions > 0 Email equipa
Memory > 80% Email equipa
Health Check failures Consecutivas Auto restart (via Auto Heal)

Monitorização externa

Recomenda-se complementar a monitorização Azure com um serviço externo independente como backup:

  • Serviços recomendados: UptimeRobot, Better Stack ou Checkly
  • Endpoints a monitorizar:
    • https://www.unicef.pt — homepage carrega
    • https://www.unicef.pt/umbraco/Api/ContentApi/GetData/?url=/ — API responde com JSON
  • Alertas: Via Slack ou email se indisponível por mais de 2 minutos
  • Vantagem: Funciona mesmo que toda a infraestrutura Azure tenha problemas

5. RPO e RTO

Metrica Valor Notas
RPO (Recovery Point Objective) ~5 minutos Azure SQL PITR com backups contínuos
RTO - App crash ~3-5 minutos Restart simples do App Service
RTO - DB restore ~30-60 minutos PITR restore + atualização de connection string
RTO - Full redeploy ~1-2 horas Rebuild + deploy + configuração

O que significa

  • RPO de 5 minutos: Em caso de perda de dados, perdem-se no máximo os últimos 5 minutos de alterações na base de dados
  • RTO de 3-5 minutos: Para o cenário mais comum (app crash), o site pode ser restaurado em 3-5 minutos com um restart
  • RTO de 1-2 horas: No pior cenário (perda total), o site pode ser reconstruído em 1-2 horas a partir do código fonte e backups

Checklist de verificação periódica

Executar mensalmente:

  • [ ] Verificar que o mirror GitHub está sincronizado com Azure DevOps
  • [ ] Confirmar que os backups SQL estão ativos (14 dias de retenção)
  • [ ] Testar que o staging slot tem uma versão funcional
  • [ ] Verificar que o soft delete está ativo no blob storage
  • [ ] Rever os alertas configurados e confirmar que os emails estão atualizados
  • [ ] Testar o procedimento de restart documentado