# Deployment na AWS (EKS)

Guia para deploy do Monetarie PIX na Amazon Web Services usando EKS (Elastic Kubernetes Service), RDS PostgreSQL, ElastiCache Redis e NATS em instancias EC2.

## Pre-requisitos

- Conta AWS com permissoes para criar EKS, RDS, ElastiCache, EC2
- AWS CLI v2 instalado e configurado (`aws configure`)
- eksctl 0.170+ instalado
- kubectl 1.28+ instalado
- Helm 3.14+ instalado
- Dominio configurado no Route 53 (ou outro DNS)

Verifique os pre-requisitos:

```bash
aws --version
# Esperado: aws-cli/2.x.x ...

eksctl version
# Esperado: 0.170.0 ou superior

aws sts get-caller-identity
# Esperado: JSON com Account, UserId, Arn
```

## Arquitetura AWS

```mermaid
graph TB
    subgraph VPC["VPC (10.0.0.0/16)"]
        subgraph PublicSubnet["Subnets Publicas"]
            ALB[Application Load Balancer<br/>HTTPS :443]
        end

        subgraph PrivateSubnet["Subnets Privadas"]
            subgraph EKS["EKS Cluster"]
                BACKEND[Backend Pods x2-10<br/>:4003]
                ADMIN[Admin Pods x2-5<br/>:80]
            end

            subgraph DataLayer["Camada de Dados"]
                RDS[(RDS PostgreSQL 16<br/>Multi-AZ)]
                REDIS[(ElastiCache Redis 7<br/>Cluster Mode)]
            end

            subgraph Messaging["Mensageria"]
                NATS1[EC2 NATS Node 1]
                NATS2[EC2 NATS Node 2]
                NATS3[EC2 NATS Node 3]
            end
        end
    end

    subgraph External["Externo"]
        ACM[ACM Certificate]
        ECR[ECR<br/>Container Registry]
        CW[CloudWatch<br/>Monitoring]
        S3[S3<br/>Backups]
    end

    ALB --> BACKEND
    ALB --> ADMIN
    BACKEND --> RDS
    BACKEND --> REDIS
    BACKEND --> NATS1
    ALB -.-> ACM
    EKS -.-> ECR
    BACKEND -.-> CW
```

## Passo 1: Criar Cluster EKS

```bash
eksctl create cluster \
  --name monetarie-pix \
  --region sa-east-1 \
  --version 1.29 \
  --nodegroup-name pix-nodes \
  --node-type t3.xlarge \
  --nodes 3 \
  --nodes-min 2 \
  --nodes-max 6 \
  --managed \
  --with-oidc \
  --vpc-cidr 10.0.0.0/16
```

::: tip REGIAO
Para instituicoes financeiras brasileiras, use `sa-east-1` (Sao Paulo) para menor latencia e conformidade com requisitos de residencia de dados.
:::

Saida esperada (leva ~15-20 minutos):
```
2026-02-13 10:00:00 [i]  eksctl version 0.170.0
2026-02-13 10:00:01 [i]  using region sa-east-1
...
2026-02-13 10:18:00 [✔]  EKS cluster "monetarie-pix" in "sa-east-1" region is ready
```

Configurar kubectl:

```bash
aws eks update-kubeconfig --name monetarie-pix --region sa-east-1

kubectl get nodes
# Esperado: 3 nodes Ready
```

## Passo 2: Criar RDS PostgreSQL 16

### Criar Subnet Group

```bash
aws rds create-db-subnet-group \
  --db-subnet-group-name monetarie-pix-db \
  --db-subnet-group-description "Monetarie PIX Database" \
  --subnet-ids <SUBNET_PRIVADA_1> <SUBNET_PRIVADA_2>
```

### Criar Parameter Group

```bash
aws rds create-db-parameter-group \
  --db-parameter-group-name monetarie-pix-pg16 \
  --db-parameter-group-family postgres16 \
  --description "Monetarie PIX PostgreSQL 16"

# Configurar parametros de performance
aws rds modify-db-parameter-group \
  --db-parameter-group-name monetarie-pix-pg16 \
  --parameters \
    "ParameterName=max_connections,ParameterValue=3000,ApplyMethod=pending-reboot" \
    "ParameterName=shared_buffers,ParameterValue={DBInstanceClassMemory/4},ApplyMethod=pending-reboot" \
    "ParameterName=effective_cache_size,ParameterValue={DBInstanceClassMemory*3/4},ApplyMethod=pending-reboot"
```

### Criar Instancia RDS

```bash
aws rds create-db-instance \
  --db-instance-identifier monetarie-pix-db \
  --db-instance-class db.r6g.xlarge \
  --engine postgres \
  --engine-version 16 \
  --master-username postgres \
  --master-user-password "<SENHA_SEGURA>" \
  --allocated-storage 100 \
  --storage-type gp3 \
  --storage-encrypted \
  --multi-az \
  --db-name monetarie \
  --db-subnet-group-name monetarie-pix-db \
  --db-parameter-group-name monetarie-pix-pg16 \
  --vpc-security-group-ids <SG_DATABASE> \
  --backup-retention-period 30 \
  --preferred-backup-window "03:00-04:00" \
  --no-publicly-accessible
```

Aguarde a instancia ficar disponivel:

```bash
aws rds wait db-instance-available --db-instance-identifier monetarie-pix-db

# Obter endpoint
aws rds describe-db-instances \
  --db-instance-identifier monetarie-pix-db \
  --query 'DBInstances[0].Endpoint.Address' \
  --output text
# Esperado: monetarie-pix-db.xxxxxx.sa-east-1.rds.amazonaws.com
```

## Passo 3: Criar ElastiCache Redis

```bash
aws elasticache create-replication-group \
  --replication-group-id monetarie-pix-redis \
  --replication-group-description "Monetarie PIX Redis" \
  --engine redis \
  --engine-version 7.1 \
  --cache-node-type cache.r6g.large \
  --num-cache-clusters 3 \
  --cache-subnet-group-name monetarie-pix-cache \
  --security-group-ids <SG_REDIS> \
  --automatic-failover-enabled \
  --at-rest-encryption-enabled \
  --transit-encryption-enabled \
  --snapshot-retention-limit 7
```

Obter endpoint:

```bash
aws elasticache describe-replication-groups \
  --replication-group-id monetarie-pix-redis \
  --query 'ReplicationGroups[0].NodeGroups[0].PrimaryEndpoint.Address' \
  --output text
# Esperado: monetarie-pix-redis.xxxxxx.sa-east-1.cache.amazonaws.com
```

## Passo 4: Configurar NATS em EC2

Crie 3 instancias EC2 para o cluster NATS:

```bash
for i in 1 2 3; do
  aws ec2 run-instances \
    --image-id ami-xxxxxxxxx \
    --instance-type t3.large \
    --key-name monetarie-key \
    --subnet-id <SUBNET_PRIVADA> \
    --security-group-ids <SG_NATS> \
    --tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=nats-$i}]" \
    --user-data file://nats-install.sh
done
```

Conteudo do `nats-install.sh`:

```bash
#!/bin/bash
curl -L https://github.com/nats-io/nats-server/releases/download/v2.10.22/nats-server-v2.10.22-linux-amd64.tar.gz | tar xz
mv nats-server-v2.10.22-linux-amd64/nats-server /usr/local/bin/

cat > /etc/nats-server.conf <<'CONF'
port: 4222
monitor_port: 8222
jetstream {
  store_dir: /var/nats/jetstream
  max_mem: 2G
  max_file: 20G
}
cluster {
  name: monetarie-pix
  port: 6222
  routes: [
    nats-route://10.0.1.10:6222
    nats-route://10.0.1.11:6222
    nats-route://10.0.1.12:6222
  ]
}
CONF

mkdir -p /var/nats/jetstream
nats-server -c /etc/nats-server.conf &
```

## Passo 5: Configurar Container Registry (ECR)

```bash
# Criar repositorios
aws ecr create-repository --repository-name monetarie/pix-backend --region sa-east-1
aws ecr create-repository --repository-name monetarie/pix-admin --region sa-east-1

# Login no ECR
aws ecr get-login-password --region sa-east-1 | \
  docker login --username AWS --password-stdin \
  <ACCOUNT_ID>.dkr.ecr.sa-east-1.amazonaws.com

# Build e push do backend
docker build -t <ACCOUNT_ID>.dkr.ecr.sa-east-1.amazonaws.com/monetarie/pix-backend:latest \
  backend/
docker push <ACCOUNT_ID>.dkr.ecr.sa-east-1.amazonaws.com/monetarie/pix-backend:latest

# Build e push do admin
docker build -t <ACCOUNT_ID>.dkr.ecr.sa-east-1.amazonaws.com/monetarie/pix-admin:latest \
  frontend/admin/
docker push <ACCOUNT_ID>.dkr.ecr.sa-east-1.amazonaws.com/monetarie/pix-admin:latest
```

## Passo 6: Instalar AWS Load Balancer Controller

```bash
# Instalar o AWS Load Balancer Controller para ALB Ingress
helm repo add eks https://aws.github.io/eks-charts
helm repo update

helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
  --namespace kube-system \
  --set clusterName=monetarie-pix \
  --set serviceAccount.create=true
```

## Passo 7: Criar Secrets no EKS

```bash
kubectl create namespace pix

# Secret do banco de dados
kubectl create secret generic db-credentials \
  --namespace pix \
  --from-literal=database-url="ecto://postgres:<SENHA>@monetarie-pix-db.xxxxxx.sa-east-1.rds.amazonaws.com:5432/monetarie"

# Secret do PIX
kubectl create secret generic pix-secrets \
  --namespace pix \
  --from-literal=secret-key-base="$(openssl rand -base64 64 | tr -d '\n')"

# Secret JWT compartilhado
kubectl create secret generic monetarie-shared-jwt-secret \
  --namespace pix \
  --from-literal=secret="<GUARDIAN_SECRET_KEY>"
```

## Passo 8: Deploy com Helm

```bash
helm install monetarie-pix deploy/kubernetes/helm/pix \
  --namespace pix \
  -f deploy/kubernetes/helm/pix/values-aws.yaml \
  --set backend.image.repository=<ACCOUNT_ID>.dkr.ecr.sa-east-1.amazonaws.com/monetarie/pix-backend \
  --set admin.image.repository=<ACCOUNT_ID>.dkr.ecr.sa-east-1.amazonaws.com/monetarie/pix-admin \
  --set redis.host="monetarie-pix-redis.xxxxxx.sa-east-1.cache.amazonaws.com" \
  --set nats.host="10.0.1.10" \
  --set "nats.cluster[0]=10.0.1.10:4222" \
  --set "nats.cluster[1]=10.0.1.11:4222" \
  --set "nats.cluster[2]=10.0.1.12:4222" \
  --set "ingress.annotations.alb\.ingress\.kubernetes\.io/certificate-arn=arn:aws:acm:sa-east-1:<ACCOUNT_ID>:certificate/<CERT_ID>"
```

## Passo 9: Migrations e Seeds

```bash
kubectl exec -n pix deployment/monetarie-pix-backend -- \
  bin/monetarie_pix eval "Shared.Release.migrate()"

kubectl exec -n pix deployment/monetarie-pix-backend -- \
  bin/monetarie_pix eval "Shared.Release.seed()"
```

## Passo 10: Verificar

```bash
# Pods
kubectl get pods -n pix

# ALB Ingress
kubectl get ingress -n pix
# Esperado: ADDRESS com o DNS do ALB

# Health check via ALB
curl -s https://pixapi.seudominio.com/health
# Esperado: {"status":"ok"}
```

## Certificados com ACM

```bash
# Solicitar certificado
aws acm request-certificate \
  --domain-name pixapi.seudominio.com \
  --subject-alternative-names pixadmin.seudominio.com \
  --validation-method DNS \
  --region sa-east-1

# Obter ARN do certificado
aws acm list-certificates --region sa-east-1 \
  --query 'CertificateSummaryList[?DomainName==`pixapi.seudominio.com`].CertificateArn' \
  --output text
```

Adicione os registros CNAME de validacao no Route 53 conforme indicado pelo ACM.

## CloudWatch Monitoring

### Metricas do EKS

O Container Insights do CloudWatch e habilitado automaticamente. Para metricas customizadas do Monetarie PIX:

```bash
# Instalar CloudWatch agent
kubectl apply -f https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonSet/container-insights-monitoring/cloudwatch-namespace.yaml
```

### Alarmes Recomendados

| Alarme | Metrica | Threshold | Descricao |
|--------|---------|-----------|-----------|
| DB CPU | RDS CPUUtilization | > 80% | CPU do PostgreSQL |
| DB Connections | RDS DatabaseConnections | > 2000 | Conexoes ativas |
| Redis Memory | ElastiCache BytesUsedForCache | > 80% capacity | Uso de memoria Redis |
| Pod Restarts | k8s pod restart count | > 5 em 5min | Pods reiniciando |

## Security Groups

| Security Group | Inbound | Outbound | Descricao |
|---------------|---------|----------|-----------|
| SG_EKS | ALB:4003, ALB:80 | All | Nodes EKS |
| SG_DATABASE | EKS:5432 | None | RDS PostgreSQL |
| SG_REDIS | EKS:6379 | None | ElastiCache |
| SG_NATS | EKS:4222, NATS:6222 | NATS:6222 | Cluster NATS |
| SG_ALB | 0.0.0.0/0:443 | EKS:4003, EKS:80 | Load Balancer |

## Resultado Esperado

Ao final deste guia, voce tera:

- Cluster EKS com 3 nodes em `sa-east-1` (Sao Paulo)
- RDS PostgreSQL 16 Multi-AZ com encryption at rest
- ElastiCache Redis 7 com automatic failover
- Cluster NATS de 3 nos em instancias EC2
- ALB com certificado ACM para terminacao TLS
- Monetarie PIX rodando com 2+ backend pods e 2+ admin pods
- Monitoramento via CloudWatch Container Insights
