Skip to content

Processo de Criação, Manutenção e Deploy de Infraestrutura para Clientes (Whitelabel) – csbbenk/infra

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).
  • 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).

  1. Preparar repositório e dependências.
  2. Criar conexão do App Runner com o GitHub para o backend (CSBBenk/api).
  3. Criar os arquivos de configuração JSON por ambiente (configs/).
  4. Configurar segredos/envs (Resend, Castle, Celcoin, JWTs etc.) no Secrets Manager.
  5. Autenticar na AWS (SSO) e setar variáveis de ambiente locais (CLIENT_ID, ENVIRONMENT, etc.).
  6. Realizar o bootstrap do CDK (uma vez por conta/região).
  7. Fazer deploy das stacks na ordem recomendada.
  8. Fazer upload do ZIP de assets (file-public.zip) no S3.
  9. Configurar domínios customizados no Amplify e App Runner (Route 53/ACM).
  10. Pós-seed: liberar IP no SG do RDS e atualizar a tabela systems (branding).
  11. 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.git
    cd infra
    npm 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
}
}

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.env

Exemplos de variáveis (adapte aos serviços):

Internet Banking (ib.env):

API_URL=https://api.exemplo.com
CASTLE_API_KEY=pk_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
JWT_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TOKEN_REGISTER=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
AMPLIFY_APP_NAME=my-app
X_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
GITHUB_REPOSITORY=https://github.com/usuario/repositorio
GITHUB_TOKEN=ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Admin (admin.env):

VITE_API_URL=https://api.exemplo.com
VITE_X_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
GITHUB_REPOSITORY=https://github.com/usuario/admin
GITHUB_TOKEN=ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
AMPLIFY_APP_NAME=my-admin

API (api.env):

AXIOM_DATASET=my-app-staging
AXIOM_ORG_ID=org-XXXXXX
AXIOM_TOKEN=xaat-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
CASTLE_API_SECRET=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
RESEND_API_KEY=re_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
TOTP_SECRET_ENCRYPTION_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
MARKET_PLACE_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
JWT_SECRET=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9....XXXXXXXX
JWT_SECRET_ADMIN=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
JWT_REFRESH_TOKEN_SECRET=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
JWT_REFRESH_TOKEN_SECRET_ADMIN=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
JWT_SELECT_ACCOUNT_SECRET=select-account-secret

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.

Terminal window
aws configure sso

Durante 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.

Terminal window
# 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ção
echo "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)”
Terminal window
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.


Use o contexto para carregar o JSON correto: —context clientId e —context environment. Você pode inspecionar stacks com npx cdk ls.

  1. VPC e networking
Terminal window
npx cdk deploy ${CLIENT_ID}-${ENVIRONMENT}-VpcStack \
--context clientId=${CLIENT_ID} --context environment=${ENVIRONMENT} \
--region ${AWS_REGION} --profile ${AWS_PROFILE}
  1. Segredos
Terminal window
npx cdk deploy ${CLIENT_ID}-${ENVIRONMENT}-SecretsStack \
--context clientId=${CLIENT_ID} --context environment=${ENVIRONMENT} \
--region ${AWS_REGION} --profile ${AWS_PROFILE}
  1. Banco de dados (RDS/Aurora)
Terminal window
npx cdk deploy ${CLIENT_ID}-${ENVIRONMENT}-RdsStack \
--context clientId=${CLIENT_ID} --context environment=${ENVIRONMENT} \
--region ${AWS_REGION} --profile ${AWS_PROFILE}
  1. Redis (ElastiCache)
Terminal window
npx cdk deploy ${CLIENT_ID}-${ENVIRONMENT}-ElastiCacheStack \
--context clientId=${CLIENT_ID} --context environment=${ENVIRONMENT} \
--region ${AWS_REGION} --profile ${AWS_PROFILE}
  1. IAM
Terminal window
npx cdk deploy ${CLIENT_ID}-${ENVIRONMENT}-IamStack \
--context clientId=${CLIENT_ID} --context environment=${ENVIRONMENT} \
--region ${AWS_REGION} --profile ${AWS_PROFILE}
  1. Bucket de assets
Terminal window
npx cdk deploy ${CLIENT_ID}-${ENVIRONMENT}-AssetsBucketStack \
--context clientId=${CLIENT_ID} --context environment=${ENVIRONMENT} \
--region ${AWS_REGION} --profile ${AWS_PROFILE}
  1. Backend API (App Runner)
Terminal window
npx cdk deploy ${CLIENT_ID}-${ENVIRONMENT}-AppRunnerStack \
--context clientId=${CLIENT_ID} --context environment=${ENVIRONMENT} \
--region ${AWS_REGION} --profile ${AWS_PROFILE}
  1. Front-ends (Amplify: ib e admin)
Terminal window
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.

Onde enviar:

  • Bucket: criado pela AssetsBucketStack (ver outputs).
  • Caminho recomendado no bucket:
    • brands/<CLIENT_ID>//file-public.zip

Como descobrir o bucket:

Terminal window
# via CloudFormation
aws cloudformation describe-stacks \
--stack-name ${CLIENT_ID}-${ENVIRONMENT}-AssetsBucketStack \
--profile ${AWS_PROFILE} \
--query "Stacks[0].Outputs[?OutputKey=='AssetsBucketName'].OutputValue" \
--output text

Upload via Console (S3):

  1. AWS Console > S3 > abra o bucket de assets.
  2. Upload > Add files > selecione /file-public.zip.
  3. Destination: brands/<CLIENT_ID>//file-public.zip
  4. Mantenha o bucket privado (sem ACL pública).
  5. Use criptografia padrão do S3 (SSE-S3).
  6. Conclua o upload.

Upload via CLI:

Terminal window
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}

  • 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).
  • 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:

  1. 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.
  2. Conectar ao banco:

Terminal window
# 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"
  1. 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.
  1. Remover a liberação do IP:
  • Volte ao SG do RDS e remova a regra “My IP”.

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.
  • 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.

  • 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.

Para remover recursos:

Terminal window
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).