🚀 Setup de Infraestrutura Azure - Audissey
Este guia contém os comandos necessários para configurar a infraestrutura Azure que ainda não está automatizada no pipeline.
📋 Pré-requisitos
- Azure CLI instalado e autenticado (
az login) - Permissões de Contributor no Resource Group
audissey-rg - Subscription:
Azure subscription 1
1️⃣ **CRÍTICO**: Cosmos DB (MongoDB API)
Nota: no Cosmos DB (Mongo API), algumas queries com
ORDER BY/.sort()podem falhar com400 BadRequest(ex:The index path corresponding to the specified order-by item is excluded.) quando o campo usado para ordenação não está indexado (ou foi excluído por policy).Nesses casos, o backend pode precisar de:
- garantir index para o campo ordenado (ex:
createdAt) ou- implementar fallback (buscar sem sort e ordenar em memória) para manter o endpoint funcional.
No caso específico de
favorites, a API tenta ordenar porcreatedAte tem fallback seguro para ordenação por_idse o Cosmos rejeitar oORDER BY. Também tenta criar indexes relevantes no arranque (best-effort).
# Criar Cosmos DB com MongoDB API
az cosmosdb create \
--name audissey-cosmos \
--resource-group audissey-rg \
--kind MongoDB \
--server-version 7.0 \
--locations regionName=westeurope failoverPriority=0 isZoneRedundant=false \
--default-consistency-level Session \
--enable-automatic-failover true \
--enable-free-tier false
# Criar database
az cosmosdb mongodb database create \
--account-name audissey-cosmos \
--resource-group audissey-rg \
--name audissey
# Obter connection string
az cosmosdb keys list \
--name audissey-cosmos \
--resource-group audissey-rg \
--type connection-strings \
--query "connectionStrings[0].connectionString" -o tsv
# Guardar no Key Vault
MONGO_URI=$(az cosmosdb keys list --name audissey-cosmos --resource-group audissey-rg --type connection-strings --query "connectionStrings[0].connectionString" -o tsv)
az keyvault secret set \
--vault-name audissey-kv-production \
--name MONGO-URI \
--value "$MONGO_URI"
Custo estimado: ~€30-50/mês (depende do throughput)
2️⃣ **CRÍTICO**: Azure Cache for Redis
# Criar Redis Cache (Standard C1 = 1GB)
az redis create \
--name audissey-redis \
--resource-group audissey-rg \
--location westeurope \
--sku Standard \
--vm-size C1 \
--enable-non-ssl-port false
# Obter connection string
REDIS_HOST=$(az redis show --name audissey-redis --resource-group audissey-rg --query hostName -o tsv)
REDIS_KEY=$(az redis list-keys --name audissey-redis --resource-group audissey-rg --query primaryKey -o tsv)
# Guardar no Key Vault
az keyvault secret set \
--vault-name audissey-kv-production \
--name REDIS-HOST \
--value "$REDIS_HOST"
az keyvault secret set \
--vault-name audissey-kv-production \
--name REDIS-KEY \
--value "$REDIS_KEY"
Custo estimado: ~€70/mês (Standard C1)
3️⃣ **IMPORTANTE**: App Services Staging/Dev
# Criar App Service para Staging
az webapp create \
--name audissey-api-staging \
--resource-group audissey-rg \
--plan audissey-plan \
--runtime "NODE:18-lts"
# Criar App Service para Development
az webapp create \
--name audissey-api-dev \
--resource-group audissey-rg \
--plan audissey-plan \
--runtime "NODE:18-lts"
# Configurar HTTPS Only
az webapp update \
--name audissey-api-staging \
--resource-group audissey-rg \
--https-only true
az webapp update \
--name audissey-api-dev \
--resource-group audissey-rg \
--https-only true
Custo: Incluído no plano existente (audissey-plan)
4️⃣ **IMPORTANTE**: Container Registry (ACR)
# ACR oficial (shared): audissey.azurecr.io (RG: audissey-shared-rg)
# Nota: o Admin User está desativado.
# Verificar o registry
az acr show \
--name audissey \
--resource-group audissey-shared-rg \
--query "{name:name, loginServer:loginServer, adminUserEnabled:adminUserEnabled}" \
-o jsonc
# Login (local) via Azure AD
az acr login --name audissey
# Exemplo: build/push
docker build -f Dockerfile.worker -t audissey.azurecr.io/audissey-worker:<tag> .
docker push audissey.azurecr.io/audissey-worker:<tag>
# App Service pull deve ser via Managed Identity + role AcrPull.
Custo estimado: ~€5/mês (Basic tier)
5️⃣ **IMPORTANTE**: Key Vault Secrets
# Adicionar secrets essenciais ao Key Vault de produção
VAULT_NAME="audissey-kv-production"
# JWT Secret
az keyvault secret set \
--vault-name $VAULT_NAME \
--name JWT-SECRET \
--value "$(openssl rand -base64 32)"
# Podcast Index API
az keyvault secret set \
--vault-name $VAULT_NAME \
--name PODCAST-INDEX-API-KEY \
--value "your_api_key_here"
az keyvault secret set \
--vault-name $VAULT_NAME \
--name PODCAST-INDEX-API-SECRET \
--value "your_api_secret_here"
# Repetir para staging e dev vaults
VAULT_NAME="audissey-kv-staging"
# ... (mesmos comandos)
VAULT_NAME="audissey-kv-dev"
# ... (mesmos comandos)
6️⃣ **IMPORTANTE**: Configurar App Service com Key Vault References
# Configurar Managed Identity no App Service
az webapp identity assign \
--name audissey-api \
--resource-group audissey-rg
# Obter o Principal ID
PRINCIPAL_ID=$(az webapp identity show \
--name audissey-api \
--resource-group audissey-rg \
--query principalId -o tsv)
# Dar permissões ao Key Vault
az keyvault set-policy \
--name audissey-kv-production \
--object-id $PRINCIPAL_ID \
--secret-permissions get list
# Configurar App Settings com referências ao Key Vault
az webapp config appsettings set \
--name audissey-api \
--resource-group audissey-rg \
--settings \
MONGO_URI="@Microsoft.KeyVault(SecretUri=https://audissey-kv-production.vault.azure.net/secrets/MONGO-URI/)" \
REDIS_HOST="@Microsoft.KeyVault(SecretUri=https://audissey-kv-production.vault.azure.net/secrets/REDIS-HOST/)" \
REDIS_KEY="@Microsoft.KeyVault(SecretUri=https://audissey-kv-production.vault.azure.net/secrets/REDIS-KEY/)" \
JWT_SECRET="@Microsoft.KeyVault(SecretUri=https://audissey-kv-production.vault.azure.net/secrets/JWT-SECRET/)" \
PODCAST_INDEX_API_KEY="@Microsoft.KeyVault(SecretUri=https://audissey-kv-production.vault.azure.net/secrets/PODCAST-INDEX-API-KEY/)" \
PODCAST_INDEX_API_SECRET="@Microsoft.KeyVault(SecretUri=https://audissey-kv-production.vault.azure.net/secrets/PODCAST-INDEX-API-SECRET/)" \
NODE_ENV="production" \
API_PORT="8080" \
LOG_LEVEL="info"
# Repetir para staging e dev
7️⃣ **DESEJÁVEL**: Azure Monitor Alerts
# Criar action group para notificações
az monitor action-group create \
--name audissey-alerts \
--resource-group audissey-rg \
--short-name audissey \
--email-receiver \
name=admin \
email-address=teu-email@example.com
# Alert: CPU > 80%
az monitor metrics alert create \
--name "API CPU High" \
--resource-group audissey-rg \
--scopes $(az webapp show --name audissey-api --resource-group audissey-rg --query id -o tsv) \
--condition "avg Percentage CPU > 80" \
--window-size 5m \
--evaluation-frequency 1m \
--action audissey-alerts
# Alert: Memory > 85%
az monitor metrics alert create \
--name "API Memory High" \
--resource-group audissey-rg \
--scopes $(az webapp show --name audissey-api --resource-group audissey-rg --query id -o tsv) \
--condition "avg MemoryPercentage > 85" \
--window-size 5m \
--evaluation-frequency 1m \
--action audissey-alerts
# Alert: Response Time > 2s
az monitor metrics alert create \
--name "API Slow Response" \
--resource-group audissey-rg \
--scopes $(az webapp show --name audissey-api --resource-group audissey-rg --query id -o tsv) \
--condition "avg ResponseTime > 2000" \
--window-size 5m \
--evaluation-frequency 1m \
--action audissey-alerts
8️⃣ **DESEJÁVEL**: Auto-scaling
# Configurar auto-scale no App Service Plan
az monitor autoscale create \
--resource-group audissey-rg \
--resource $(az appservice plan show --name audissey-plan --resource-group audissey-rg --query id -o tsv) \
--resource-type Microsoft.Web/serverfarms \
--name audissey-autoscale \
--min-count 1 \
--max-count 3 \
--count 1
# Scale out when CPU > 70%
az monitor autoscale rule create \
--resource-group audissey-rg \
--autoscale-name audissey-autoscale \
--condition "Percentage CPU > 70 avg 5m" \
--scale out 1
# Scale in when CPU < 30%
az monitor autoscale rule create \
--resource-group audissey-rg \
--autoscale-name audissey-autoscale \
--condition "Percentage CPU < 30 avg 5m" \
--scale in 1
9️⃣ **DESEJÁVEL**: Backup Automático
# Configurar backup do Cosmos DB
az cosmosdb backup create \
--account-name audissey-cosmos \
--resource-group audissey-rg \
--backup-type Continuous
# Configurar backup do App Service (requer Premium plan)
az webapp config backup create \
--resource-group audissey-rg \
--webapp-name audissey-api \
--container-url "<storage-account-url>" \
--backup-name daily-backup \
--frequency 1d \
--retain-one true
🔟 **Verificação Final**
# Listar todos os recursos criados
az resource list --resource-group audissey-rg --output table
# Verificar custos estimados
az consumption usage list \
--start-date $(date -u -d '30 days ago' '+%Y-%m-%dT%H:%M:%SZ') \
--end-date $(date -u '+%Y-%m-%dT%H:%M:%SZ') \
--query "[?contains(instanceId, 'audissey')].{Name:instanceName, Cost:pretaxCost}" \
--output table
📊 Resumo de Custos Mensais Estimados
| Recurso | SKU | Custo/mês |
|---|---|---|
| App Service Plan | B1 | €10-15 |
| Cosmos DB | 400 RU/s | €30-50 |
| Redis Cache | Standard C1 | €70 |
| Container Registry | Basic | €5 |
| Application Insights | 5GB/mês | €0 (free tier) |
| Container Apps (Worker) | Consumption | variável (dep. de CPU/mem/execução) |
| TOTAL | €145-180 |
🚨 Próximos Passos Críticos
- ✅ Executar scripts de infraestrutura (pontos 1-6)
- ✅ Fazer commit das alterações no pipeline
- ✅ Criar service connection para Container Registry no Azure DevOps
- ✅ Fazer push da branch
stagingedeveloppara testar multi-environment - ✅ Verificar que os secrets estão no Key Vault
- ⏳ Testar deployment completo