Processo de Criação, Manutenção e Deploy de Infraestrutura para Clientes (Whitelabel) – csbbenk/infra
Documentação Oficial
Section titled “Documentação Oficial”Esta documentação descreve, de ponta a ponta, como iniciar, configurar e fazer o deploy de um novo cliente (whitelabel) na infraestrutura do CSBBenk. Cobre a criação de ambientes (staging e production), configuração de secrets, integrações externas (Resend, Castle, Celcoin), domínios e o processo de deploy via AWS CDK.
Repositórios envolvidos:
- CSBBenk/infra: infraestrutura como código (AWS CDK).
- CSBBenk/api: backend (deploy com App Runner).
- CSBBenk/ib: Internet Banking (front-end, deploy com Amplify).
- CSBBenk/admin: Admin (front-end, deploy com Amplify).
Pré-requisitos
Section titled “Pré-requisitos”- Acesso à conta AWS com permissões apropriadas para CDK, App Runner, Amplify, RDS, ElastiCache, IAM, Route 53, ACM e Secrets Manager.
- Acesso aos repositórios no GitHub para criar um app oauth com permissão: CSBBenk/infra, CSBBenk/api, CSBBenk/ib, CSBBenk/admin.
- Contas/credenciais ativas nos serviços externos: Resend(com o dominio configurado), Castle, Celcoin.
- Ferramentas locais:
- Node.js LTS (recomendado ≥ 18.x) e npm.
- AWS CLI v2 configurado com SSO ou chaves de acesso.
- AWS CDK CLI (npx cdk ou instalação global).
- Git.
- Domínio e hosted zone configurados no Route 53 (ou acesso para criar registros DNS).
Visão geral do fluxo
Section titled “Visão geral do fluxo”- Preparar repositório e dependências.
- Criar conexão do App Runner com o GitHub para o backend (CSBBenk/api).
- Criar os arquivos de configuração JSON por ambiente (configs/).
- Configurar segredos/envs (Resend, Castle, Celcoin, JWTs etc.) no Secrets Manager.
- Autenticar na AWS (SSO) e setar variáveis de ambiente locais (CLIENT_ID, ENVIRONMENT, etc.).
- Realizar o bootstrap do CDK (uma vez por conta/região).
- Fazer deploy das stacks na ordem recomendada.
- Fazer upload do ZIP de assets (file-public.zip) no S3.
- Configurar domínios customizados no Amplify e App Runner (Route 53/ACM).
- Pós-seed: liberar IP no SG do RDS e atualizar a tabela systems (branding).
- Submeter PR de brand do aplicativo.
1) Preparar o repositório de infraestrutura
Section titled “1) Preparar o repositório de infraestrutura”- Clone o repositório CSBBenk/infra e instale as dependências:
Terminal window git clone git@github.com:CSBBenk/infra.gitcd infranpm install
2) Criar conexão no AWS App Runner (GitHub → API)
Section titled “2) Criar conexão no AWS App Runner (GitHub → API)”Para permitir que o App Runner atualize a API automaticamente a partir do GitHub:
- Acesse AWS Console > App Runner > Connections.
- Crie uma nova conexão com o GitHub autorizando o acesso ao repositório CSBBenk/api (inclua permissões para criação de webhooks).
- Copie o ARN da conexão gerada.
- Esse ARN será usado no arquivo de configuração JSON em application.repository.connectionArn.
3) Arquivos de configuração por ambiente (configs/)
Section titled “3) Arquivos de configuração por ambiente (configs/)”Se os arquivos de configuração para os ambientes (ex: csbbenk-staging.json e csbbenk-production.json) já existirem na pasta infra/configs/, você pode pular esta etapa.
Caso contrário, crie um arquivo JSON para cada ambiente. A maneira mais fácil é copiar um arquivo existente de outro cliente ou usar o exemplo abaixo como base, ajustando os valores para o novo cliente.
Importante:
- O campo application.repository.connectionArn deve ser atualizado com a conexão criada no App Runner.
- Ajuste dominios, instâncias, região, CORS, segurança e budgets de acordo com staging vs production.
- Em networking.domains, “app” refere-se ao front-end do Internet Banking (ib).
Exemplo (staging):
{ "client": { "id": "csbbenk", "name": "CSBBenk Financial", "description": "Digital banking platform for CSBBenk" }, "environment": { "type": "staging", "region": "us-east-1" }, "infrastructure": { "database": { "instanceClass": "db.t4g.medium", "instanceCount": 1, "storageEncrypted": true, "backupRetentionDays": 7, "enablePerformanceInsights": false }, "redis": { "serverless": true, "numCacheNodes": 1, "enableTls": true, "enableBackup": false }, "apprunner": { "cpu": "1 vCPU", "memory": "2 GB", "autoScaling": { "minSize": 1, "maxSize": 3, "maxConcurrency": 50 } }, "vpc": { "cidr": "10.0.0.0/16", "maxAzs": 2, "enableNatGateway": true, "enableVpcEndpoints": false } }, "networking": { "domains": { "api": "api.benk.csbpatreon.dev", "admin": "admin.benk.csbpatreon.dev", "app": "ib.benk.csbpatreon.dev" }, "certificates": { "autoCreate": true }, "cors": { "allowedOrigins": [ "https://admin.benk.csbpatreon.dev", "https://ib.benk.csbpatreon.dev", "http://localhost:3000", "http://localhost:5173" ], "allowCredentials": true } }, "security": { "enableWaf": false, "enableVpcFlowLogs": false, "enableCloudTrail": false, "accessControl": { "enableMfa": false } }, "application": { "features": { "enableCastle": true, "enableResend": true, "enableNotifications": true, "enableMobileApp": true }, "repository": { "url": "https://github.com/CSBBenk/api", "branch": "refactor/develop", "connectionArn": "arn:aws:apprunner:us-east-1:000000000000:connection/REPLACE_ME/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" } }, "monitoring": { "enableCloudWatch": true, "enableXRay": false, "logRetentionDays": 14, "enableAlerting": false }, "billing": { "budgetLimit": 200, "enableBillingAlerts": true, "costAllocationTags": { "Environment": "staging", "Client": "csbbenk", "Project": "digital-banking", "CostCenter": "engineering" } }, "backup": { "enableCrossRegionBackup": false, "retentionDays": 7 }}4) Configuração de segredos e envs
Section titled “4) Configuração de segredos e envs”Os envs devem ser mantidos seguros (não comitar esses arquivos). O ideal é gerenciá-los via AWS Secrets Manager. Caso use arquivos locais, mantenha-os fora do Git e armazene suas versões definitivas como secrets na AWS.
Estrutura sugerida local (apenas para preparo):
config/ production.admin.env production.api.env production.ib.env staging.admin.env staging.api.env staging.ib.envExemplos de variáveis (adapte aos serviços):
Internet Banking (ib.env):
API_URL=https://api.exemplo.comCASTLE_API_KEY=pk_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXJWT_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxTOKEN_REGISTER=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXAMPLIFY_APP_NAME=my-appX_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxGITHUB_REPOSITORY=https://github.com/usuario/repositorioGITHUB_TOKEN=ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXAdmin (admin.env):
VITE_API_URL=https://api.exemplo.comVITE_X_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxGITHUB_REPOSITORY=https://github.com/usuario/adminGITHUB_TOKEN=ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXAMPLIFY_APP_NAME=my-adminAPI (api.env):
AXIOM_DATASET=my-app-stagingAXIOM_ORG_ID=org-XXXXXXAXIOM_TOKEN=xaat-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxCASTLE_API_SECRET=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXRESEND_API_KEY=re_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXTOTP_SECRET_ENCRYPTION_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxMARKET_PLACE_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxJWT_SECRET=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9....XXXXXXXXJWT_SECRET_ADMIN=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXJWT_REFRESH_TOKEN_SECRET=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXJWT_REFRESH_TOKEN_SECRET_ADMIN=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXJWT_SELECT_ACCOUNT_SECRET=select-account-secretCertificados da Celcoin (Secrets Manager)
Section titled “Certificados da Celcoin (Secrets Manager)”Crie um secret por ambiente:
- Nome: credential-celcoin-staging ou credential-celcoin-production.
- Campos:
- CELCOIN_CERT (conteúdo PEM do certificado; escape de quebras de linha com \n se armazenar como string JSON)
- CELCOIN_CERT_KEY
- CELCOIN_CERT_PASSPHRASE
- CELCOIN_CLIENT_SECRET
- CELCOIN_CLIENT_ID
Como adicionar:
- AWS Console > Secrets Manager > Store a new secret.
- Escolha “Other type of secret”.
- Adicione os pares chave-valor.
- Nomeie seguindo o padrão do ambiente.
- Garanta que o conteúdo do certificado esteja em PEM válido.
5) Autenticação na AWS e variáveis locais
Section titled “5) Autenticação na AWS e variáveis locais”Antes de interagir com o CDK, você precisa autenticar sua máquina na AWS e definir variáveis de ambiente que informarão ao CDK qual cliente e ambiente você está deployando.
Primeiro, autentique-se usando AWS SSO. Este comando abrirá seu navegador para que você possa fazer login na sua conta AWS.
aws configure ssoDurante o processo, você será solicitado a dar um nome ao seu “profile”. Um profile é um conjunto de credenciais salvas localmente. Por exemplo, csbbenk.
Depois de configurar o profile, exporte as seguintes variáveis de ambiente no seu terminal. Elas são essenciais para que os comandos do CDK funcionem corretamente.
# Substitua "csbbenk" pelo ID do cliente que você está configurando.export CLIENT_ID=csbbenk
# Defina o ambiente: "staging" ou "production".export ENVIRONMENT=staging
# A região da AWS onde a infraestrutura será criada.export AWS_REGION=us-east-1
# O ID da conta AWS. Certifique-se de que corresponde à conta onde você está autenticado.export AWS_ACCOUNT_ID=908027413685
# O nome do profile que você configurou com "aws configure sso".# Este nome deve existir no seu arquivo ~/.aws/config.export AWS_PROFILE=csbbenk
# Apenas para verificaçãoecho "Deploying for: ${CLIENT_ID}-${ENVIRONMENT}-${AWS_PROFILE} in ${AWS_REGION}"6) Bootstrap do CDK (uma vez por conta/região)
Section titled “6) Bootstrap do CDK (uma vez por conta/região)”npx cdk bootstrap aws://${AWS_ACCOUNT_ID}/${AWS_REGION} \ --context clientId=${CLIENT_ID} \ --context environment=${ENVIRONMENT} \ --profile ${AWS_PROFILE}Isso cria recursos base (S3 assets, roles IAM) usados pelo CDK.
7) Deploy das stacks (ordem recomendada)
Section titled “7) Deploy das stacks (ordem recomendada)”Use o contexto para carregar o JSON correto: —context clientId e —context environment. Você pode inspecionar stacks com npx cdk ls.
- VPC e networking
npx cdk deploy ${CLIENT_ID}-${ENVIRONMENT}-VpcStack \ --context clientId=${CLIENT_ID} --context environment=${ENVIRONMENT} \ --region ${AWS_REGION} --profile ${AWS_PROFILE}- Segredos
npx cdk deploy ${CLIENT_ID}-${ENVIRONMENT}-SecretsStack \ --context clientId=${CLIENT_ID} --context environment=${ENVIRONMENT} \ --region ${AWS_REGION} --profile ${AWS_PROFILE}- Banco de dados (RDS/Aurora)
npx cdk deploy ${CLIENT_ID}-${ENVIRONMENT}-RdsStack \ --context clientId=${CLIENT_ID} --context environment=${ENVIRONMENT} \ --region ${AWS_REGION} --profile ${AWS_PROFILE}- Redis (ElastiCache)
npx cdk deploy ${CLIENT_ID}-${ENVIRONMENT}-ElastiCacheStack \ --context clientId=${CLIENT_ID} --context environment=${ENVIRONMENT} \ --region ${AWS_REGION} --profile ${AWS_PROFILE}- IAM
npx cdk deploy ${CLIENT_ID}-${ENVIRONMENT}-IamStack \ --context clientId=${CLIENT_ID} --context environment=${ENVIRONMENT} \ --region ${AWS_REGION} --profile ${AWS_PROFILE}- Bucket de assets
npx cdk deploy ${CLIENT_ID}-${ENVIRONMENT}-AssetsBucketStack \ --context clientId=${CLIENT_ID} --context environment=${ENVIRONMENT} \ --region ${AWS_REGION} --profile ${AWS_PROFILE}- Backend API (App Runner)
npx cdk deploy ${CLIENT_ID}-${ENVIRONMENT}-AppRunnerStack \ --context clientId=${CLIENT_ID} --context environment=${ENVIRONMENT} \ --region ${AWS_REGION} --profile ${AWS_PROFILE}- Front-ends (Amplify: ib e admin)
npx cdk deploy ${CLIENT_ID}-${ENVIRONMENT}-AmplifyStack \ --context clientId=${CLIENT_ID} --context environment=${ENVIRONMENT} \ --region ${AWS_REGION} --profile ${AWS_PROFILE}Após cada deploy, revise os outputs exibidos (URLs, ARNs, nomes de recursos).
Observação importante (App Runner + VPC): Se a API acessar RDS/Redis privados, o serviço do App Runner deve estar conectado à VPC e com regras de Security Group permitindo tráfego nas portas necessárias (ex.: 5432 para Postgres, 6379 para Redis). Verifique se a AppRunnerStack cria o VPC Connector e as regras adequadas.
8) Upload de assets no S3 (file-public.zip)
Section titled “8) Upload de assets no S3 (file-public.zip)”Os assets do brand do cliente ficam centralizados em um único arquivo ZIP. No seu workspace, o arquivo está em /file-public.zip. No aplicativo, apenas o splash e o ícone permanecem offline no bundle; todos os demais assets serão carregados do S3 a partir desse ZIP.
- Arquivo de exemplo: file-public.zip
Onde enviar:
- Bucket: criado pela AssetsBucketStack (ver outputs).
- Caminho recomendado no bucket:
- brands/<CLIENT_ID>/
/file-public.zip
- brands/<CLIENT_ID>/
Como descobrir o bucket:
# via CloudFormationaws cloudformation describe-stacks \ --stack-name ${CLIENT_ID}-${ENVIRONMENT}-AssetsBucketStack \ --profile ${AWS_PROFILE} \ --query "Stacks[0].Outputs[?OutputKey=='AssetsBucketName'].OutputValue" \ --output textUpload via Console (S3):
- AWS Console > S3 > abra o bucket de assets.
- Upload > Add files > selecione /file-public.zip.
- Destination: brands/<CLIENT_ID>/
/file-public.zip - Mantenha o bucket privado (sem ACL pública).
- Use criptografia padrão do S3 (SSE-S3).
- Conclua o upload.
Upload via CLI:
ASSETS_BUCKET=$(aws cloudformation describe-stacks \ --stack-name ${CLIENT_ID}-${ENVIRONMENT}-AssetsBucketStack \ --profile ${AWS_PROFILE} \ --query "Stacks[0].Outputs[?OutputKey=='AssetsBucketName'].OutputValue" \ --output text)
aws s3 cp /file-public.zip s3://${ASSETS_BUCKET}/brands/${CLIENT_ID}/${ENVIRONMENT}/file-public.zip --profile ${AWS_PROFILE}9) Domínios e certificados
Section titled “9) Domínios e certificados”Amplify (ib e admin):
Section titled “Amplify (ib e admin):”- AWS Console > Amplify > selecione a app (ib/admin) criada pela AmplifyStack.
- Domain management > Add domain.
- Insira o domínio do seu config JSON (ex.: ib.benk.csbpatreon.dev ou admin.benk.csbpatreon.dev).
- O Amplify orienta a criação de registros DNS (CNAME/ALIAS). Se o hosted zone estiver no Route 53 da mesma conta, ele pode criar automaticamente; caso contrário, adicione manualmente.
- Certificados ACM:
- Quando você adiciona o domínio no Amplify, ele pode provisionar/validar o certificado automaticamente (verifique status).
- Confirme a validação no ACM (região us-east-1 para CloudFront/Amplify).
App Runner (API):
Section titled “App Runner (API):”- AWS Console > App Runner > selecione o serviço da API.
- Custom domains > Add custom domain.
- Informe o domínio do config (ex.: api.benk.csbpatreon.dev).
- O App Runner exibirá registros CNAME para validação/provisionamento de certificado.
- Adicione os CNAMEs no Route 53.
- Aguarde a validação e propagação DNS (até 48 horas, normalmente bem menos).
Dicas:
- Use a mesma região onde os serviços estão para evitar conflitos de ACM.
- Em produção, habilite WAF onde aplicável (API e front-ends).
10) Pós-seed: liberação de IP e ajustes na tabela systems (DB)
Section titled “10) Pós-seed: liberação de IP e ajustes na tabela systems (DB)”Após o App Runner rodar as seeds, execute:
-
Liberar temporariamente seu IP no Security Group (RDS):
- RDS > cluster/instância > anote o Security Group (SG).
- EC2 > Security Groups > selecione o SG do RDS.
- Inbound rules > Add rule:
- Type: PostgreSQL, Port: 5432, Source: My IP (ou IP autorizado).
- Salve. Esta liberação é temporária.
-
Conectar ao banco:
# Obtenha o secret do DB (credenciais)aws secretsmanager get-secret-value --secret-id <DbSecretArn> --profile ${AWS_PROFILE}
# Conecte (exemplo com psql)psql "host=<RDS_ENDPOINT> port=5432 dbname=<DB_NAME> user=<DB_USER> password=<DB_PASSWORD> sslmode=require"- Atualizar a tabela systems com branding e referência do ZIP:
- As seeds criam um registro base. Ajuste conforme o schema real. Para um guia detalhado sobre as chaves e valores, consulte a Documentação da Tabela ‘systems’. Observação:
- Prefira URLs HTTPS (CloudFront/API) quando o consumo for via navegador.
- Somente splash e ícone ficam offline no bundle do app; todo o restante deve vir do S3.
- Remover a liberação do IP:
- Volte ao SG do RDS e remova a regra “My IP”.
11) Brand do aplicativo (PR obrigatória)
Section titled “11) Brand do aplicativo (PR obrigatória)”Além do upload do ZIP no S3 e das configurações na tabela systems, é obrigatório submeter uma PR com o brand do aplicativo.
- Guia: Criação de Nova Marca (Whitelabel) – App Mobile
- O guia cobre estrutura de arquivos, nomes e validação.
- Regra: apenas splash e ícone permanecem embarcados no app; todos os demais assets ficam no ZIP do S3 (file-public.zip).
- Conclua o deploy somente após a PR ser aprovada e mergeada.
Troubleshooting
Section titled “Troubleshooting”- App Runner “unhealthy” e rollback:
- Verifique logs no CloudWatch.
- Cheque a conexão com o GitHub (Connection ativa, branch correto, Dockerfile ou runtime configurados).
- Porta de escuta do container compatível com a configuração do App Runner.
- Variáveis de ambiente/Secrets presentes no serviço.
- Conectividade à VPC (se acessa RDS/Redis).
- Erros de IAM:
- Confirme o profile usado e permissões para CDK, App Runner, Amplify, RDS, ElastiCache, ACM, Route 53, Secrets Manager.
- Falhas de banco/Redis:
- Security Groups e sub-redes corretas.
- Parâmetros de conexão (host, porta, usuário, senha) carregados via secrets.
- CORS:
- Permita apenas domínios front-end (remova o domínio da própria API da lista de allowedOrigins).
- CDK diffs e validação:
- Use npx cdk diff antes de deploys impactantes.
- Se uma stack falhar e ficar inconsistente, considere npx cdk destroy
e redeploy.
Operação, manutenção e atualizações
Section titled “Operação, manutenção e atualizações”- Mudanças de configuração:
- Atualize o JSON no diretório configs/ e redeploy apenas as stacks afetadas.
- Rotação de secrets:
- Atualize no Secrets Manager e, se necessário, reinicie serviços (App Runner) para recarregar envs.
- Migrations de banco:
- Planeje e rode migrations antes/apos o deploy conforme a estratégia do backend (CI/CD).
- Observabilidade:
- CloudWatch (logs, métricas), X-Ray (se habilitado), alarmes de custo (Billing) e orçamentos (Budget).
- Custos:
- Monitore o uso de NAT Gateways, RDS e ElastiCache — são os maiores vilões de custo em staging/production.
Destruição do ambiente (cuidado)
Section titled “Destruição do ambiente (cuidado)”Para remover recursos:
npx cdk destroy --all \ --context clientId=${CLIENT_ID} \ --context environment=${ENVIRONMENT} \ --profile ${AWS_PROFILE}Atenção:
- Remova domínios customizados no Amplify e App Runner antes, para evitar conflitos no ACM/Route 53.
- Elimine/backup de dados críticos (RDS snapshots) antes de destruir.
- Operação irreversível.
Checklist final (para cada novo whitelabel)
Section titled “Checklist final (para cada novo whitelabel)”- Repositórios acessíveis (infra, api, ib, admin).
- Conexão App Runner → GitHub criada e ARN atualizado no JSON.
- Arquivo de configuração por ambiente em configs/ validado.
- Secrets criados no Secrets Manager (Resend, Castle, Celcoin, JWTs, etc.).
- Autenticação AWS (SSO) e variáveis de ambiente exportadas.
- CDK bootstrap executado (se primeira vez na conta/região).
- Stacks deployadas na ordem recomendada.
- Upload do ZIP de assets no S3: brands/<CLIENT_ID>/
/file-public.zip. - Domínios configurados no Amplify e App Runner (certificados válidos).
- Pós-seed: IP liberado temporariamente no SG do RDS e tabela systems atualizada (cores, banners, brand_zip_url/URLs).
- PR de brand criada conforme docs/BRANDING_GUIDE.md (apenas splash e ícone offline) e aprovada.
- Testes finais (API, ib, admin) e logs verificados no CloudWatch.
- Alertas de custo/monitoramento ativados.
- Documentação interna do cliente atualizada (domínios, acessos, budgets).