> For the complete documentation index, see [llms.txt](https://docs.caf.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.caf.io/caf-api/caf-api-pt-br/all-id/production-guidance/ecs-terraform.md).

# AWS ECS (Terraform)

Guia completo para implantar o All ID no AWS ECS Fargate usando Terraform.

## Visão geral

Este guia explica como implantar o All ID usando Terraform Infrastructure as Code.

A implantação requer:

* **Terraform da aplicação All ID** (`src/terraform/allid/`) - Serviços da aplicação (ECS, RDS, ALB)
* **VPC existente** - Você deve fornecer uma VPC com a estrutura de sub-redes necessária

{% hint style="info" %}
**Requisitos de rede**: Os módulos Terraform do All ID exigem uma VPC existente com sub-redes públicas, privadas e isoladas. Se você ainda não tiver uma VPC, a Certta fornece um projeto Terraform de referência (`src/terraform/shared/`) que cria uma infraestrutura de rede pronta para produção.
{% endhint %}

{% hint style="success" %}
A Certta fornecerá um pacote contendo:

* Projeto Terraform do All ID (obrigatório)
* Projeto Terraform de infraestrutura de rede de referência (opcional, use se precisar criar uma nova VPC)
* Exemplos de configuração e documentação

**Observação**: O projeto usa um prefixo padrão `teste-tf` para nomeação de recursos. Você deve alterá-lo para o nome do seu projeto no `terraform.tfvars` arquivo por meio da `variável` .
{% endhint %}

## Pré-requisitos

Antes de implantar, verifique se você tem:

**Ferramentas**:

* Terraform >= 1.5
* AWS CLI configurado com credenciais

**Conta AWS**:

* Conta AWS com permissões adequadas
* Permissões para criar: ECS, RDS, ALB, CloudFormation, funções IAM, grupos de segurança
* Credenciais AWS configuradas (`aws configure`)

**Infraestrutura de rede** - Você tem três opções:

1. **Opção A (recomendada)**: Implantar uma nova VPC usando o projeto Terraform de referência da Certta (`src/terraform/shared/`)
2. **Opção B**: Use uma VPC existente criando manualmente os Parâmetros SSM (veja a etapa 2B)
3. **Já possui Parâmetros SSM**: Pule diretamente para a etapa 3 se os parâmetros já estiverem configurados

Estrutura de VPC necessária (independentemente da opção):

* Sub-redes públicas (mínimo 2 AZs) para o Application Load Balancer
* Sub-redes privadas com NAT (mínimo 2 AZs) para os serviços ECS
* Sub-redes isoladas (mínimo 2 AZs) para o banco de dados RDS
* Gateway de Internet e NAT Gateway configurados

**Imagens de contêiner**:

* Acesso ao registro privado de contêineres da Certta
* URIs dos repositórios ECR para as imagens Peer e Facematch
* Versões/tags de imagem a implantar

{% hint style="warning" %}
**Importante**: Entre em contato com seu gerente técnico de conta da Certta para obter:

* Arquivos do projeto Terraform (All ID + infraestrutura de rede opcional)
* Credenciais do registro de contêineres e URIs das imagens
* Certificados do Serviço Router para comunicação mTLS
  {% endhint %}

## Automação com Makefile

Este projeto inclui Makefiles que simplificam as operações do Terraform. Em vez de executar `terraform` comandos diretamente, você pode usar `make` comandos que lidam automaticamente com configurações específicas do ambiente.

**Benefícios**:

* ✅ **Execução consistente**: Os mesmos comandos funcionam em todos os ambientes
* ✅ **Navegação automática**: Não há necessidade de `cd` para os diretórios do ambiente
* ✅ **Segurança integrada**: Mensagens de confirmação para operações destrutivas
* ✅ **Fácil multiambiente**: Alterne entre ambientes com `ENV` parâmetro
* ✅ **Autoexplicativo**: Execute `make help` para ver todos os comandos disponíveis
* ✅ **Prevenção de erros**: Valida nomes de ambiente e parâmetros obrigatórios

{% hint style="info" %}
Ao longo deste guia, você verá `make` comandos em vez de `terraform` comandos. Esta é a abordagem recomendada para gerenciar esta infraestrutura.

**Alternativa**: Se preferir usar o Terraform diretamente, ainda poderá fazer isso navegando até o diretório do ambiente (por exemplo, `cd environments/dev`) e executando comandos padrão `terraform` comandos.
{% endhint %}

**Exemplo rápido**:

```bash
# Em vez de:
cd environments/dev && terraform plan

# Use:
make plan ENV=dev
```

**Exemplo de segurança**:

```bash
# O comando destroy exige digitar o nome do ambiente para confirmar
make destroy ENV=dev
# Saída: "Tem certeza? Digite 'dev' para confirmar:"
```

## Estrutura do projeto

A Certta fornecerá os arquivos do projeto Terraform. A estrutura do pacote:

```
allid-ecs-quickstart/
│
├── src/terraform/allid/              # Aplicação All ID (obrigatória)
│   ├── modules/
│   │   ├── ecs-cluster/              # Cluster ECS + Service Discovery
│   │   ├── database/                 # Aurora MySQL Serverless v2
│   │   ├── load-balancer/            # Application Load Balancer
│   │   ├── peer-service/             # Serviço Peer (usado 3 vezes)
│   │   └── facematch-service/        # Serviço Facematch
│   ├── environments/
│   │   ├── dev/
│   │   │   ├── main.tf               # Configuração principal
│   │   │   ├── variables.tf          # Definições de variáveis
│   │   │   ├── outputs.tf            # Definições de saída
│   │   │   └── terraform.tfvars      # Valores específicos do ambiente
│   │   ├── stg/
│   │   └── prd/
│   ├── Makefile                      # Comandos de automação
│   └── README.md
│
└── src/terraform/shared/             # Infraestrutura de rede (opcional)
    ├── modules/
    │   └── network/                  # VPC, sub-redes, NAT, IGW
    ├── environments/
    │   ├── dev/
    │   ├── stg/
    │   └── prd/
    ├── Makefile                      # Comandos de automação
    └── README.md
```

{% hint style="info" %}
**A infraestrutura compartilhada é opcional**: Implante somente se precisar criar uma nova VPC. Se você já tiver uma VPC, pule o `src/terraform/shared/` projeto e configure as informações da VPC via Parâmetros SSM.
{% endhint %}

### Arquivos principais por ambiente

Cada diretório de ambiente contém:

* **`main.tf`**: Configuração principal com definições de provedor e invocações de módulos
* **`variables.tf`**: Todas as definições de variáveis com tipos e padrões
* **`outputs.tf`**: Saídas dos recursos criados (DNS do ALB, endpoint do banco de dados etc.)
* **`terraform.tfvars.example`**: Modelo com valores e comentários de exemplo
* **`terraform.tfvars`**: Valores reais (não versionado no git, contém segredos)
* **`ssm.tf`** (parte compartilhada apenas): Parâmetros SSM para referências entre projetos

## Etapa 1: Extrair o projeto Terraform

Extraia os arquivos do projeto Terraform fornecidos pela Certta:

```bash
# Extraia o pacote
tar -xzf allid-ecs-quickstart.tar.gz
cd allid-ecs-quickstart
```

## Etapa 2: Infraestrutura de rede (Opção A)

{% hint style="info" %}
**Escolha sua opção**:

* **Esta etapa (Opção A)**: Implante uma nova VPC usando o projeto Terraform de referência da Certta
* [**Etapa 2B (Opção B)**](#step-2b-using-existing-vpc-option-b): Use sua VPC existente criando Parâmetros SSM manualmente
  {% endhint %}

### Opção A: Implantar nova VPC com Terraform

Se precisar criar uma nova VPC, implante a infraestrutura de rede de referência:

```bash
# Navegue até o projeto compartilhado
cd src/terraform/shared

# Configure as variáveis (opcional, os padrões geralmente são suficientes)
cp environments/dev/terraform.tfvars.example environments/dev/terraform.tfvars
# Edite environments/dev/terraform.tfvars, se necessário

# Inicialize o Terraform
make init ENV=dev

# Defina as variáveis de ambiente
export AWS_REGION=us-east-1

# Revise o que será criado
make plan ENV=dev

# Implante a infraestrutura de rede
make apply ENV=dev
```

**O que é implantado**:

* VPC com blocos CIDR específicos do ambiente
* 2 sub-redes públicas (em 2 zonas de disponibilidade)
* 2 sub-redes privadas com NAT (em 2 zonas de disponibilidade)
* 2 sub-redes isoladas (em 2 zonas de disponibilidade) para bancos de dados
* Gateway de Internet para acesso à internet pública
* NAT Gateway para acesso de saída das sub-redes privadas
* Parâmetros SSM para referências entre projetos

**Tempo de implantação**: \~5-10 minutos

Após a implantação, as informações da VPC são armazenadas automaticamente nos Parâmetros SSM:

```bash
# Veja os Parâmetros SSM criados
make output ENV=dev

# Ou verifique diretamente
aws ssm get-parameter --name "/shared/dev/vpc-id" --query "Parameter.Value" --output text
```

Os seguintes Parâmetros SSM são criados:

* `/shared/dev/vpc-id` - ID da VPC
* `/shared/dev/vpc-cidr` - Bloco CIDR da VPC
* `/shared/dev/public-subnet-ids` - IDs das sub-redes públicas (separados por vírgula)
* `/shared/dev/private-egress-subnet-ids` - IDs das sub-redes privadas com NAT (separados por vírgula)
* `/shared/dev/private-isolated-subnet-ids` - IDs das sub-redes isoladas (separados por vírgula)

{% hint style="info" %}
O projeto Terraform do All ID lê esses Parâmetros SSM automaticamente - nenhuma configuração manual necessária!
{% endhint %}

## Etapa 2B: Usando VPC existente (Opção B)

{% hint style="info" %}
**Pule esta etapa se você escolheu a Opção A** (implantando uma nova VPC com terraform-shared).
{% endhint %}

Se você **já tiver uma VPC** e **não quiser usar terraform-shared**, você pode criar os Parâmetros SSM manualmente para que o projeto Terraform do All ID encontre sua VPC.

**Pré-requisitos**: Sua VPC deve ter:

* Sub-redes públicas (com rota para o Gateway de Internet)
* Sub-redes privadas com saída (com rota para o NAT Gateway)
* Sub-redes privadas isoladas (sem rota para a internet, para bancos de dados)

### Obtenha os IDs da sua VPC e das sub-redes

Use a AWS CLI para identificar sua VPC e sub-redes:

```bash
# Liste as VPCs
aws ec2 describe-vpcs --query 'Vpcs[*].[VpcId,CidrBlock,Tags[?Key==`Name`].Value|[0]]' --output table

# Liste as sub-redes de uma VPC específica
aws ec2 describe-subnets --filters "Name=vpc-id,Values=vpc-xxxxx" \
  --query 'Subnets[*].[SubnetId,CidrBlock,AvailabilityZone,Tags[?Key==`Name`].Value|[0]]' \
  --output table

# Veja as rotas de uma sub-rede para identificar seu tipo
aws ec2 describe-route-tables --filters "Name=association.subnet-id,Values=subnet-xxxxx" \
  --query 'RouteTables[*].Routes' --output table
```

### Identifique cada tipo de sub-rede

* **Sub-redes públicas**: Possui rota `0.0.0.0/0 → igw-xxxxx` (Gateway de Internet)
* **Sub-redes privadas com saída**: Possui rota `0.0.0.0/0 → nat-xxxxx` (NAT Gateway)
* **Sub-redes privadas isoladas**: SEM rota para `0.0.0.0/0`

### Crie os Parâmetros SSM

Depois de identificar sua VPC e sub-redes, crie os Parâmetros SSM:

```bash
# Configure as variáveis com seus valores reais
ENV=dev
VPC_ID=vpc-xxxxx                    # ID da sua VPC
VPC_CIDR=172.31.0.0/16             # Seu CIDR da VPC
PUB_SUBNETS=subnet-111,subnet-222   # Sub-redes públicas (separadas por vírgula, sem espaços)
PRIV_EGRESS=subnet-333,subnet-444   # Sub-redes privadas com NAT
PRIV_ISOLATED=subnet-555,subnet-666 # Sub-redes privadas isoladas

# Crie todos os Parâmetros SSM necessários
aws ssm put-parameter --name "/shared/$ENV/vpc-id" --value "$VPC_ID" --type String --overwrite && \\
aws ssm put-parameter --name "/shared/$ENV/vpc-cidr" --value "$VPC_CIDR" --type String --overwrite && \\
aws ssm put-parameter --name "/shared/$ENV/public-subnet-ids" --value "$PUB_SUBNETS" --type StringList --overwrite && \\
aws ssm put-parameter --name "/shared/$ENV/private-egress-subnet-ids" --value "$PRIV_EGRESS" --type StringList --overwrite && \\
aws ssm put-parameter --name "/shared/$ENV/private-isolated-subnet-ids" --value "$PRIV_ISOLATED" --type StringList --overwrite && \\
echo "✅ Parâmetros SSM criados com sucesso!"
```

{% hint style="danger" %}
**Importante**:

* Use IDs de sub-redes separados por vírgula **SEM ESPAÇOS** (por exemplo, `subnet-111,subnet-222`)
* Garanta que as sub-redes estejam em AZs diferentes para alta disponibilidade
* Os tipos de sub-rede (public, private-egress, private-isolated) devem corresponder às rotas configuradas
  {% endhint %}

### Verifique se os parâmetros foram criados

```bash
# Liste todos os parâmetros
aws ssm get-parameters-by-path --path "/shared/dev" --recursive

# Veja valores individuais
aws ssm get-parameter --name "/shared/dev/vpc-id"
aws ssm get-parameter --name "/shared/dev/public-subnet-ids"
```

### Exclua os parâmetros (se precisar refazer)

```bash
ENV=dev
aws ssm delete-parameters --names \\
  "/shared/$ENV/vpc-id" \\
  "/shared/$ENV/vpc-cidr" \\
  "/shared/$ENV/public-subnet-ids" \\
  "/shared/$ENV/private-egress-subnet-ids" \\
  "/shared/$ENV/private-isolated-subnet-ids"
```

{% hint style="success" %}
**Qual opção escolher?**

* ✅ **Opção A (terraform-shared)**: Recomendado para novos projetos ou quando você deseja gerenciar a VPC com Terraform
* 🔧 **Opção B (Manual)**: Use se você já tiver uma VPC e ainda não quiser migrar para o Terraform
  {% endhint %}

## Etapa 3: Configure as variáveis da aplicação

Navegue até o diretório da aplicação:

```bash
cd src/terraform/allid
```

Copie o arquivo de variáveis de exemplo e configure os valores específicos do seu ambiente:

```bash
cp environments/dev/terraform.tfvars.example environments/dev/terraform.tfvars
```

Edite `environments/dev/terraform.tfvars` e configure os seguintes valores:

```hcl
# Configuração geral
aws_region  = "us-east-1"
environment = "dev"
prefix      = "allid"  # Altere isto para o nome do seu projeto (padrão: teste-tf)

# Imagens de contêiner
peer_ecr_repository_uri      = "211125355658.dkr.ecr.us-east-1.amazonaws.com/peer-v2"
peer_version                 = "v2.5.0"
facematch_ecr_repository_uri = "211125355658.dkr.ecr.us-east-1.amazonaws.com/facematch"
facematch_version            = "7d88b2c4803add026000f97ea7913f1297f6e786"

# Configuração do Router (varia conforme o ambiente)
# dev: https://mtls.us.dev.caf.io/v1/biometrics/facial-validation
# stg: https://mtls.us.stg.caf.io/v1/biometrics/facial-validation  
# prd: https://mtls.us.prd.caf.io/v1/biometrics/facial-validation
router_rest_url = "https://mtls.us.prd.caf.io/v1/biometrics/facial-validation"

# Observação: os certificados mTLS do Router NÃO são configurados aqui
# Eles serão adicionados ao AWS Secrets Manager após a implantação (veja a Etapa 5)

# Configuração do serviço
desired_count = 1

# Configuração do banco de dados
database_name                   = "db"
database_username               = "dbadmin"
database_min_capacity           = 0
database_max_capacity           = 2
database_backup_retention_period = 7
database_deletion_protection    = false

# Configuração do balanceador de carga
alb_allowed_cidr_blocks = [
  "3.218.90.124/32",     # IPs do roteador Certta
  "44.219.96.170/32",
  "18.235.54.162/32",
  "18.228.123.114/32",
  "54.232.24.70/32",
  "54.94.8.234/32"
]

# Configuração de logging
log_retention_days = 7
enable_ecs_exec    = true
```

**Valores de configuração a atualizar**:

| Campo                          | Descrição                                          | Como obter                                                    |
| ------------------------------ | -------------------------------------------------- | ------------------------------------------------------------- |
| `peer_ecr_repository_uri`      | Registro do contêiner do serviço Peer              | Fornecido pela Certta                                         |
| `peer_version`                 | Tag da imagem do Peer a implantar                  | Fornecido pela Certta (por exemplo, `latest`, hash do commit) |
| `facematch_ecr_repository_uri` | Registro do contêiner do Facematch                 | Fornecido pela Certta                                         |
| `facematch_version`            | Tag da imagem do Facematch a implantar             | Fornecido pela Certta (por exemplo, `latest`, hash do commit) |
| `desired_count`                | Número de tarefas por serviço peer                 | Defina como 0 para dev (economia de custos), 1+ para stg/prd  |
| `router_rest_url`              | Endpoint do Certta Router para sua região/ambiente | Fornecido pela Certta                                         |

{% hint style="info" %}
**Sobre `desired_count`**: Esta variável controla o número de tarefas para **todos os três serviços Peer** simultaneamente (padrão, client-a, client-b). Isso garante consistência entre todos os peers.

**Valores recomendados**:

* **Desenvolvimento**: `0` (nenhuma tarefa em execução - economiza custos quando não está em uso)
* **Staging**: `1` (uma tarefa por peer para testes)
* **Produção**: `2+` (múltiplas tarefas por peer para alta disponibilidade)

**Observação**: O serviço Facematch está fixado em 2 tarefas. Para alterar, edite o `facematch` módulo em `environments/<env>/main.tf`.
{% endhint %}

{% hint style="info" %}
**Certificados mTLS do Router**: Os certificados NÃO são configurados em `terraform.tfvars`. O Terraform cria segredos vazios no AWS Secrets Manager, e você os preencherá com certificados reais após a implantação na Etapa 5.

**Abordagem alternativa**: Você pode incluir certificados em `terraform.tfvars` se preferir, mas esteja ciente:

* Os valores serão armazenados nos arquivos de estado do Terraform (mesmo se marcados como sensíveis)
* Os arquivos de estado devem ser criptografados e com controle de acesso
* Essa abordagem é opcional e não é recomendada por motivos de segurança
  {% endhint %}

{% hint style="info" %}
**Múltiplos ambientes**: Crie arquivos `terraform.tfvars` separados para cada ambiente (dev, stg, prd) com valores específicos de cada ambiente.
{% endhint %}

## Etapa 4: Implantar a aplicação All ID

Implante os serviços da aplicação All ID:

```bash
# Certifique-se de que você está no diretório correto
cd src/terraform/allid

# Inicialize o Terraform (apenas na primeira vez)
make init ENV=dev

# Revise o que será criado
make plan ENV=dev

# Implante todos os recursos da aplicação
make apply ENV=dev
```

Tipo `yes` quando solicitado a confirmar a implantação.

**O que é implantado**:

1. **Cluster ECS + descoberta de serviços** (`ecs-cluster` módulo)
   * Cluster ECS Fargate
   * namespace privado do Cloud Map (`allid.local`)
   * Container Insights habilitado
2. **Banco de dados** (`banco de dados` módulo)
   * Cluster Aurora MySQL Serverless v2
   * Grupo de segurança do banco de dados
   * Secrets Manager para credenciais (geradas automaticamente)
   * CloudWatch Logs para logs de erro, gerais e de consultas lentas
   * Performance Insights habilitado
3. **Balanceador de carga** (`load-balancer` módulo)
   * Application Load Balancer (voltado para a internet)
   * listener HTTP (porta 80)
   * Grupo de segurança com whitelisting de IP
   * Ação padrão: 403 Acesso negado
4. **Serviço Facematch** (`facematch-service` módulo)
   * Definição de tarefa ECS (CPU: 1024, Memória: 2048 MB)
   * Serviço Fargate com 2 instâncias
   * Registro de serviço no Cloud Map (`facematch.allid.local`)
   * Grupo de segurança para comunicação interna
   * Funções IAM para execução e tarefa
5. **Serviços Peer** (`peer-service` módulo - instanciado 3 vezes)
   * Cria 3 instâncias peer (default, client-a, client-b)
   * Cada peer tem:
     * Definição de tarefa ECS (CPU: 256, Memória: 512 MB)
     * Serviço Fargate com contagem de instâncias configurável
     * Grupo de destino do ALB com roteamento baseado em caminho
     * Registro de serviço no Cloud Map
     * Conexão com o banco de dados no RDS
     * Certificado mTLS do Router armazenado no Secrets Manager
     * Funções IAM para execução e tarefa
     * Grupo de logs do CloudWatch

**Tempo de implantação**: \~15-20 minutos

{% hint style="info" %}
O Terraform lida automaticamente com as dependências dos recursos e os implanta na ordem correta. Você pode acompanhar o progresso na saída do terminal.
{% endhint %}

{% hint style="warning" %}
**Importante**: Após a implantação, conclua a Etapa 5 (configurar certificados) e a Etapa 6 (inicializar bancos de dados) para deixar os Serviços Peer operacionais.
{% endhint %}

## Etapa 5: Configurar certificados mTLS do Router

Após implantar a infraestrutura, você precisa preencher os certificados mTLS do Router no AWS Secrets Manager. O Terraform cria segredos vazios que devem ser preenchidos com o conteúdo real do certificado.

{% hint style="info" %}
**Por que os certificados não estão no Terraform**:

* Mantém credenciais sensíveis fora dos arquivos de estado do Terraform
* Permite rotação de certificados sem alterações no Terraform
* Segue as melhores práticas de segurança para gerenciamento de segredos

**Alternativa**: Você pode incluir certificados em `terraform.tfvars` se suas políticas de segurança permitirem, mas isso os armazenará no arquivo de estado do Terraform.
{% endhint %}

### Configure os certificados para cada peer

**Opção 1: Console da AWS** (recomendado)

1. Navegue até o Console do Secrets Manager → Segredos
2. Encontre e clique em cada segredo:
   * `{prefix}-peer-default-router-certificate`
   * `{prefix}-peer-client-a-router-certificate`
   * `{prefix}-peer-client-b-router-certificate`
3. Clique em "Recuperar valor do segredo" → "Editar"
4. Atualize o JSON com seus certificados reais:

```json
{
  "private-key": "-----BEGIN PRIVATE KEY-----\nMIIE...conteúdo...\n-----END PRIVATE KEY-----",
  "certificate": "-----BEGIN CERTIFICATE-----\nMIID...conteúdo...\n-----END CERTIFICATE-----"
}
```

5. Salvar alterações

**Opção 2: AWS CLI**

```bash
# Atualize o certificado do peer padrão (substitua pelo conteúdo real)
aws secretsmanager update-secret \\
  --secret-id {prefix}-peer-default-router-certificate \\
  --secret-string '{
    "private-key": "-----BEGIN PRIVATE KEY-----\nYOUR_KEY_HERE\n-----END PRIVATE KEY-----",
    "certificate": "-----BEGIN CERTIFICATE-----\nYOUR_CERT_HERE\n-----END CERTIFICATE-----"
  }'

# Atualize o certificado do peer client-a
aws secretsmanager update-secret \\
  --secret-id {prefix}-peer-client-a-router-certificate \\
  --secret-string '{
    "private-key": "-----BEGIN PRIVATE KEY-----\nYOUR_KEY_HERE\n-----END PRIVATE KEY-----",
    "certificate": "-----BEGIN CERTIFICATE-----\nYOUR_CERT_HERE\n-----END CERTIFICATE-----"
  }'

# Atualize o certificado do peer client-b
aws secretsmanager update-secret \\
  --secret-id {prefix}-peer-client-b-router-certificate \\
  --secret-string '{
    "private-key": "-----BEGIN PRIVATE KEY-----\nYOUR_KEY_HERE\n-----END PRIVATE KEY-----",
    "certificate": "-----BEGIN CERTIFICATE-----\nYOUR_CERT_HERE\n-----END CERTIFICATE-----"
  }'
```

{% hint style="warning" %}
**Importante**: Substitua `{prefix}` pelo seu valor real de prefixo (o padrão é `teste-tf` ou o que você configurou em `terraform.tfvars`).
{% endhint %}

{% hint style="success" %}
Após atualizar os segredos, os Serviços Peer detectarão e usarão automaticamente os certificados. Nenhuma reinicialização é necessária.
{% endhint %}

## Etapa 6: Inicializar o banco de dados

O Serviço Peer requer que um esquema de banco de dados seja inicializado. A Certta fornecerá um arquivo dump SQL que deve ser restaurado no banco de dados Aurora MySQL.

{% hint style="danger" %}
**Crítico**: Os Serviços Peer podem falhar ao iniciar se o esquema do banco de dados não estiver inicializado. Conclua esta etapa para permitir que os serviços se tornem operacionais.
{% endhint %}

{% hint style="info" %}
**Configuração multi-tenant**: Cada instância peer usa seu próprio banco de dados. Os nomes dos bancos de dados seguem o padrão `peer-{nome}`:

* `peer-default` (para o peer padrão)
* `peer-client-a` (para o peer client-a)
* `peer-client-b` (para o peer client-b)
  {% endhint %}

### Métodos de acesso ao banco de dados

O banco de dados Aurora MySQL é implantado em sub-redes isoladas sem acesso direto à internet. Você precisa estabelecer uma conexão segura para acessá-lo.

**Opção 1: Bastion Host (recomendado para produção)**

Implante um bastion host (instância EC2) em uma sub-rede pública para atuar como servidor de salto:

1. Inicie uma instância EC2 em uma sub-rede pública da sua VPC
2. Configure os grupos de segurança para permitir:
   * Acesso SSH do seu IP ao bastion host
   * Acesso MySQL do bastion host ao grupo de segurança do RDS
3. Conecte-se ao banco de dados por meio de um túnel SSH:

```bash
# Túnel SSH para o bastion host
ssh -i your-key.pem -L 3306:DATABASE_ENDPOINT:3306 ec2-user@BASTION_IP

# Em outro terminal, conecte-se ao banco de dados via localhost
mysql -h 127.0.0.1 -u DB_USERNAME -p
```

**Opção 2: Conexão VPN**

Se você tiver uma conexão VPN configurada para a sua VPC:

1. Conecte-se à sua VPN
2. Acesse o banco de dados diretamente usando seu endpoint privado

**Opção 3: AWS Systems Manager Session Manager**

Use o Session Manager para acesso seguro sem expor portas SSH:

1. Certifique-se de que seu bastion host tenha o agente SSM instalado
2. Conceda as permissões IAM necessárias
3. Crie uma sessão de encaminhamento de porta:

```bash
aws ssm start-session \\
  --target INSTANCE_ID \\
  --document-name AWS-StartPortForwardingSessionToRemoteHost \\
  --parameters '{"portNumber":["3306"],"localPortNumber":["3306"],"host":["DATABASE_ENDPOINT"]}'
```

### Obtenha o endpoint e as credenciais do banco de dados

**Opção 1: Saídas do Terraform**

```bash
# A partir do diretório allid
cd src/terraform/allid

# Obtenha o endpoint do banco de dados e o ARN do segredo
make output ENV=dev

# Ou navegue até o diretório do ambiente para saídas específicas
cd environments/dev
SECRET_ARN=$(terraform output -raw database_secret_arn)
aws secretsmanager get-secret-value --secret-id $SECRET_ARN --query 'SecretString' --output text | jq
```

**Opção 2: Console da AWS**

1. Navegue até o Console do RDS → Bancos de dados
2. Encontre o cluster Aurora (procure pelo nome com `allid-database`)
3. Copie o **endpoint do Writer** (por exemplo, `allid-database-cluster.cluster-xxx.us-east-1.rds.amazonaws.com`)
4. Navegue até o Console do Secrets Manager → Segredos
5. Encontre o segredo do banco de dados (procure pelo nome com `allid-database`)
6. Clique em "Recuperar valor do segredo" para ver o nome de usuário e a senha

**Opção 3: AWS CLI**

```bash
# Liste os clusters do RDS para encontrar seu banco de dados
aws rds describe-db-clusters --query 'DBClusters[*].[DBClusterIdentifier, Endpoint, Port]' --output table

# Liste os segredos para encontrar as credenciais do banco de dados
aws secretsmanager list-secrets --query 'SecretList[?contains(Name, `allid-database`)].[Name, ARN]' --output table

# Obtenha o valor específico do segredo (substitua SECRET_ARN pelo ARN real)
aws secretsmanager get-secret-value --secret-id SECRET_ARN --query 'SecretString' --output text | jq
```

### Criar e inicializar bancos de dados

Você pode usar qualquer uma das ferramentas a seguir para criar bancos de dados e restaurar o dump:

#### Opção A: Cliente de linha de comando MySQL

Melhor para automação e pipelines de CI/CD:

```bash
# Conecte-se ao Aurora MySQL (substitua pelo endpoint, nome de usuário e senha acima)
mysql -h {DB_ENDPOINT} -u {DB_USERNAME} -p

# Criar bancos de dados
CREATE DATABASE IF NOT EXISTS `peer-default`;
CREATE DATABASE IF NOT EXISTS `peer-client-a`;
CREATE DATABASE IF NOT EXISTS `peer-client-b`;
EXIT;

# Restaure o dump em cada banco de dados (a Certta fornecerá o arquivo dump SQL)
mysql -h {DB_ENDPOINT} -u {DB_USERNAME} -p peer-default < allid-dump.sql
mysql -h {DB_ENDPOINT} -u {DB_USERNAME} -p peer-client-a < allid-dump.sql
mysql -h {DB_ENDPOINT} -u {DB_USERNAME} -p peer-client-b < allid-dump.sql
```

#### Opção B: DBeaver (ferramenta GUI)

Recomendado para gerenciamento visual de banco de dados:

1. **Crie uma nova conexão**:
   * Banco de dados: MySQL
   * Host: `{DB_ENDPOINT}` (de cima)
   * Porta: 3306
   * Nome de usuário: `{DB_USERNAME}` (do Secrets Manager)
   * Senha: `{DB_PASSWORD}` (do Secrets Manager)
2. **Criar bancos de dados**:

   * Clique com o botão direito na conexão → Editor SQL → Novo script SQL
   * Executar:

   ```sql
   CREATE DATABASE IF NOT EXISTS `peer-default`;
   CREATE DATABASE IF NOT EXISTS `peer-client-a`;
   CREATE DATABASE IF NOT EXISTS `peer-client-b`;
   ```
3. **Restaurar dump**:
   * Clique com o botão direito em cada banco de dados → Ferramentas → Executar script
   * Selecione o `allid-dump.sql` arquivo fornecido pela Certta
   * Clique em "Iniciar" para executar

#### Opção C: MySQL Workbench (ferramenta GUI)

Ferramenta GUI alternativa para gerenciamento MySQL:

1. **Crie uma nova conexão**:
   * Nome da conexão: `All ID Database`
   * Hostname: `{DB_ENDPOINT}`
   * Porta: 3306
   * Nome de usuário: `{DB_USERNAME}`
   * Senha: Armazenar no Keychain/Vault
2. **Criar bancos de dados**:

   * Abrir conexão → guia Query
   * Executar:

   ```sql
   CREATE DATABASE IF NOT EXISTS `peer-default`;
   CREATE DATABASE IF NOT EXISTS `peer-client-a`;
   CREATE DATABASE IF NOT EXISTS `peer-client-b`;
   ```
3. **Importar dump**:
   * Servidor → Importação de dados
   * Selecione "Importar de arquivo autônomo"
   * Escolha `allid-dump.sql` o arquivo
   * Selecione o banco de dados de destino (repita para cada um: peer-default, peer-client-a, peer-client-b)
   * Clique em "Iniciar importação"

{% hint style="info" %}
**Solução de problemas de conexão**: Se você não conseguir se conectar ao banco de dados, certifique-se de que:

* Você estabeleceu o acesso adequado (bastion host, VPN ou Session Manager)
* O grupo de segurança do RDS permite conexões da sua origem
* O endpoint e as credenciais do banco de dados estão corretos
  {% endhint %}

{% hint style="danger" %}
**Crítico**: Cada Serviço Peer falhará ao iniciar se seu banco de dados correspondente não estiver inicializado. Entre em contato com seu gerente técnico de conta da Certta para obter o arquivo dump SQL.
{% endhint %}

{% hint style="success" %}
**Os serviços se recuperarão automaticamente**: Depois que você inicializar os bancos de dados, os Serviços Peer serão reiniciados automaticamente e ficarão saudáveis em poucos minutos. O ECS detectará que as tarefas estão falhando e as reiniciará automaticamente.
{% endhint %}

## Etapa 7: Obter endpoints

Após a conclusão da implantação, obtenha o endpoint da aplicação:

```bash
# Ver todas as saídas
make output ENV=dev

# Obtenha saídas específicas (navegue até o diretório do ambiente primeiro)
cd environments/dev
terraform output alb_dns_name
terraform output database_endpoint
terraform output database_secret_arn
terraform output ecs_cluster_name
```

**Saídas importantes**:

| Saída                       | Descrição                                                 | Exemplo                                                          |
| --------------------------- | --------------------------------------------------------- | ---------------------------------------------------------------- |
| `alb_dns_name`              | Nome DNS do balanceador de carga                          | `allid-load-balancer-123456789.us-east-1.elb.amazonaws.com`      |
| `database_endpoint`         | Endpoint do cluster Aurora MySQL                          | `allid-database-cluster.cluster-xxx.us-east-1.rds.amazonaws.com` |
| `database_secret_arn`       | ARN do Secrets Manager para credenciais do banco de dados | `arn:aws:secretsmanager:...`                                     |
| `ecs_cluster_name`          | Nome do cluster ECS                                       | `allid-cluster`                                                  |
| `peer_default_service_name` | Nome do serviço peer padrão                               | `allid-peer-default`                                             |
| `facematch_service_name`    | Nome do serviço Facematch                                 | `allid-facematch`                                                |

{% hint style="info" %}
A implantação cria 3 instâncias peer com roteamento baseado em caminho para suporte multilocatário. Cada peer tem seu próprio endpoint isolado com prefixo de caminho.
{% endhint %}

**Endpoints da API** (3 instâncias peer por padrão):

```
# Peer padrão
http://{alb-dns}/default/v1/biometric-validation-responder

# Peer Client A
http://{alb-dns}/client-a/v1/biometric-validation-responder

# Peer Client B
http://{alb-dns}/client-b/v1/biometric-validation-responder
```

**Endpoints de verificação de integridade**:

```
http://{alb-dns}/default/status
http://{alb-dns}/client-a/status
http://{alb-dns}/client-b/status
```

{% hint style="warning" %}
Para adicionar/remover peers, edite o arquivo de ambiente `main.tf` e adicione/remova módulos peer. Lembre-se de criar o banco de dados correspondente e fornecer certificados do Router para novos peers ANTES de implantar.
{% endhint %}

## Etapa 8: Validar a implantação

Teste se todos os serviços estão saudáveis:

**Teste os endpoints dos peers** (usando o DNS do ALB da Etapa 7):

```bash
# Obtenha o DNS do ALB das saídas (do diretório src/terraform/allid/environments/dev)
cd environments/dev
ALB_DNS=$(terraform output -raw alb_dns_name)

curl -f http://${ALB_DNS}/default/status
curl -f http://${ALB_DNS}/client-a/status
curl -f http://${ALB_DNS}/client-b/status
```

Todos os endpoints devem retornar HTTP 200 com informações de status.

**Verifique o status dos serviços ECS**:

**Console da AWS**:

1. Navegue até o Console do ECS → Clusters → `allid-cluster`
2. Clique na aba "Serviços"
3. Verifique se todos os serviços mostram o status "Em execução" e se a contagem desejada corresponde à contagem em execução

**AWS CLI**:

```bash
# Obter nome do cluster do Terraform
CLUSTER_NAME=$(terraform output -raw ecs_cluster_name)

# Listar todos os serviços no cluster
aws ecs list-services --cluster $CLUSTER_NAME --output table

# Verificar o status detalhado
aws ecs describe-services \\
  --cluster $CLUSTER_NAME \\
  --services allid-peer-default allid-peer-client-a allid-peer-client-b allid-facematch \\
  --query 'services[*].[serviceName, runningCount, desiredCount, deployments[0].status]' \\
  --output table
```

Todos os serviços devem mostrar `runningCount` correspondendo a `desiredCount` e o status da implantação `PRIMARY`.

**Verificar logs do CloudWatch** (se os serviços falharem ao iniciar):

**Console da AWS**:

1. Navegue até o Console do CloudWatch → Grupos de logs
2. Encontre os grupos de logs: `/ecs/allid/peer-default`, `/ecs/allid/facematch`, etc.
3. Verifique os streams de logs recentes em busca de erros

**AWS CLI**:

```bash
# Listar grupos de logs
aws logs describe-log-groups --log-group-name-prefix /ecs/allid --output table

# Acompanhar um log específico (substitua o nome do grupo de logs)
aws logs tail /ecs/allid/peer-default --follow
```

## Comandos do Makefile

Ambos `src/terraform/allid/` e `src/terraform/shared/` incluem um Makefile com comandos de automação para facilitar o gerenciamento da infraestrutura.

{% hint style="info" %}
**Primeiros passos**: Execute `make help` em qualquer um dos diretórios do projeto para ver todos os comandos disponíveis e suas descrições.
{% endhint %}

### Comandos disponíveis

```bash
# Mostrar ajuda e comandos disponíveis
make help

# Inicialize o Terraform
make init ENV=dev

# Validar a configuração do Terraform
make validate ENV=dev

# Planejar alterações
make plan ENV=dev

# Aplicar alterações
make apply ENV=dev

# Destruir a infraestrutura (requer confirmação)
make destroy ENV=dev

# Mostrar saídas
make output ENV=dev

# Format ar arquivos do Terraform
make fmt

# Verificar a formatação dos arquivos do Terraform
make fmt-check

# Limpar o estado e o cache do Terraform
make clean ENV=dev

# Limpar todos os ambientes
make clean-all

# Atualizar os provedores do Terraform
make upgrade ENV=dev

# Listar recursos no estado do Terraform
make state-list ENV=dev

# Mostrar um recurso específico do estado
make state-show ENV=dev RESOURCE=module.database.aws_rds_cluster.main

# Marcar um recurso como corrompido para forçar a recriação
make taint ENV=dev RESOURCE=module.peer_default.aws_ecs_service.main

# Importar infraestrutura existente
make import ENV=dev RESOURCE=module.database.aws_rds_cluster.main ID=cluster-id
```

### Seleção de ambiente

Todos os comandos suportam o `ENV` parâmetro para especificar o ambiente de destino:

```bash
# Desenvolvimento
make plan ENV=dev

# Homologação
make plan ENV=stg

# Produção
make plan ENV=prd
```

{% hint style="info" %}
**Ambiente padrão**: Se você não especificar `ENV`, o Makefile usa por padrão `dev`.
{% endhint %}

### Comandos da infraestrutura compartilhada

O Makefile da infraestrutura compartilhada inclui um comando adicional para visualizar parâmetros do SSM:

```bash
# Mostrar parâmetros do SSM criados pela infraestrutura compartilhada
cd src/terraform/shared
make ssm-params ENV=dev
```

### Exemplo de fluxo de trabalho

Aqui está um fluxo de trabalho típico usando comandos do Makefile:

```bash
# 1. Implantar a infraestrutura compartilhada (VPC)
cd src/terraform/shared
make init ENV=dev
make plan ENV=dev
make apply ENV=dev

# 2. Implantar a aplicação All ID
cd ../allid
make init ENV=dev
make plan ENV=dev
make apply ENV=dev

# 3. Ver saídas
make output ENV=dev

# 4. Mais tarde: atualizar e reimplantar
# Editar environments/dev/terraform.tfvars (por exemplo, alterar versões de imagem)
make plan ENV=dev
make apply ENV=dev

# 5. Escalar serviços
# Editar environments/dev/terraform.tfvars ou main.tf
make plan ENV=dev
make apply ENV=dev

# 6. Limpar quando terminar
make destroy ENV=dev
cd ../shared
make destroy ENV=dev
```

## Referência rápida

### Comandos mais comuns

```bash
# Ver ajuda
cd src/terraform/allid  # ou src/terraform/shared
make help

# Fluxo de trabalho básico
make init ENV=dev
make plan ENV=dev
make apply ENV=dev
make output ENV=dev

# Atualizar a infraestrutura
# Editar environments/dev/terraform.tfvars
make plan ENV=dev
make apply ENV=dev

# Ver saída específica
cd environments/dev
terraform output alb_dns_name

# Validar configuração
make validate ENV=dev

# Format ar arquivos do Terraform
make fmt

# Listar recursos no estado
make state-list ENV=dev

# Ver detalhes do recurso
make state-show ENV=dev RESOURCE=module.database.aws_rds_cluster.this

# Limpeza
make destroy ENV=dev
```

### Gerenciamento de ambiente

```bash
# Todos os comandos suportam o parâmetro ENV
make plan ENV=dev     # Desenvolvimento
make apply ENV=stg    # Homologação  
make output ENV=prd   # Produção

# O padrão é dev se não for especificado
make plan            # Igual a: make plan ENV=dev
```

### Tarefas comuns

**Implantar em um novo ambiente**:

```bash
cd src/terraform/shared
make init ENV=stg
make apply ENV=stg

cd ../allid
cp environments/dev/terraform.tfvars environments/stg/terraform.tfvars
# Edite environments/stg/terraform.tfvars com valores específicos do ambiente
make init ENV=stg
make apply ENV=stg
```

**Atualizar imagens de contêiner**:

```bash
cd src/terraform/allid
# Editar environments/dev/terraform.tfvars
# Atualize: peer_version = "new-version"
make plan ENV=dev
make apply ENV=dev
```

**Escalar serviços**:

```bash
cd src/terraform/allid
# Editar environments/dev/terraform.tfvars
# Atualize: desired_count = 2
make plan ENV=dev
make apply ENV=dev
```

**Ver logs**:

```bash
# Logs do Peer
aws logs tail /ecs/allid/peer-default --follow

# Logs do Facematch
aws logs tail /ecs/allid/facematch --follow

# Filtrar por padrão
aws logs tail /ecs/allid/peer-default --follow --filter-pattern "ERROR"
```

## Visão geral da arquitetura

### Camadas de rede

A implantação cria uma arquitetura de rede em três camadas:

```
┌─────────────────────────────────────────┐
│ Sub-redes públicas (2 AZs)              │
│ • Application Load Balancer             │
│ • Internet Gateway                      │
└─────────────────┬───────────────────────┘
                  │
┌─────────────────▼───────────────────────┐
│ Sub-redes privadas (2 AZs)              │
│ • Serviço Peer (ECS Fargate)            │
│ • Serviço Facematch (ECS Fargate)       │
│ • NAT Gateway (saída para a internet)   │
└─────────────────┬───────────────────────┘
                  │
┌─────────────────▼───────────────────────┐
│ Sub-redes isoladas (2 AZs)              │
│ • Banco de dados Aurora MySQL           │
│ • Sem acesso à internet                 │
└─────────────────────────────────────────┘
```

### Comunicação entre serviços

```
Internet → ALB (HTTP:80) → Peer (8080) → Facematch (8080)
                              ↓
                         Banco de dados (3306)
```

### Roteamento baseado em caminho (multi-tenant)

O ALB usa roteamento baseado em caminho para dar suporte a várias instâncias de peer:

```
/default/*   → peer-default   (Grupo de destino 1)
/client-a/*  → peer-client-a  (Grupo de destino 2)
/client-b/*  → peer-client-b  (Grupo de destino 3)
```

Cada instância de peer:

* Tem seu próprio serviço ECS
* Tem seu próprio banco de dados isolado (peer-default, peer-client-a, peer-client-b)
* Opera independentemente dos outros peers
* Compartilha o mesmo conjunto de serviços Facematch

## Gerenciamento de configuração

Os módulos do Terraform configuram automaticamente variáveis de ambiente e segredos para todos os serviços.

**As variáveis de ambiente** são definidas no `peer-service` módulo e incluem:

* Conexão com o banco de dados (host, porta, nome do banco)
* Endpoint do serviço Facematch
* URL do serviço Router
* Flags de recurso (RabbitMQ, Redis, comunicação com o Router)

**Segredos** são injetados por meio dos segredos da tarefa ECS e incluem:

* Credenciais do banco de dados (geradas automaticamente pelo Terraform)
* Certificados mTLS do Router (fornecidos via terraform.tfvars)

{% hint style="info" %}
Veja [Configuração](/caf-api/caf-api-pt-br/all-id/configuration.md) para a lista completa de variáveis de ambiente, valores necessários e detalhes de configuração.
{% endhint %}

### Gerenciamento de segredos

O Terraform cria automaticamente segredos no AWS Secrets Manager:

**Convenção de nomenclatura de segredos**:

* Credenciais do banco de dados: `{prefix}-database-secret` (por exemplo, `allid-database-secret`)
  * Gerado automaticamente pelo Terraform durante a implantação
* Certificados do Router: `{prefix}-peer-{name}-router-certificate` (por exemplo, `allid-peer-default-router-certificate`)
  * Criado vazio pelo Terraform, preenchido manualmente após a implantação (veja [Etapa 5](#step-5-configure-router-mtls-certificates))

{% hint style="info" %}
**Abordagem de segurança dos certificados do Router**:

Por padrão, os segredos do certificado do Router são criados vazios e preenchidos manualmente após a implantação. Essa abordagem:

* ✅ Mantém credenciais sensíveis fora dos arquivos de estado do Terraform
* ✅ Permite a rotação de certificados sem alterações no Terraform
* ✅ Segue as melhores práticas de segurança para gerenciamento de segredos

**Alternativa**: Você pode incluir certificados em `terraform.tfvars` se necessário, mas esteja ciente de que eles serão armazenados nos arquivos de estado do Terraform (mesmo se marcados como sensíveis). Se você escolher esta abordagem:

* Armazene os arquivos de estado em buckets S3 criptografados com acesso restrito
* Use bloqueio de estado com DynamoDB
* Nunca faça commit dos arquivos de estado no controle de versão
* Limite o acesso aos arquivos de estado apenas ao pessoal autorizado
  {% endhint %}

## Segurança

O Terraform configura automaticamente grupos de segurança e whitelist de IP seguindo os princípios de privilégio mínimo.

**Grupos de segurança**:

* O ALB aceita tráfego apenas de IPs permitidos
* Os serviços Peer aceitam tráfego apenas do ALB e da VPC interna
* O Facematch aceita tráfego apenas dos serviços Peer
* O banco de dados aceita tráfego apenas dos serviços Peer

**Whitelist de IP**:

* O ALB é configurado para aceitar tráfego apenas dos endereços IP do Certta Router
* Configure IPs adicionais em `terraform.tfvars` por meio da `alb_allowed_cidr_blocks` variável

{% hint style="info" %}
Veja [Melhores Práticas de Segurança](/caf-api/caf-api-pt-br/all-id/security-best-practices.md) para:

* Lista completa dos endereços IP do Certta Router
* Recomendações de segmentação de rede
* Melhores práticas de gerenciamento de segredos
* Opções adicionais de reforço de segurança
  {% endhint %}

## Atualizando a implantação

### Atualizar imagens de contêiner

1. Atualize as versões das imagens em `terraform.tfvars`:

```hcl
peer_version      = "new-commit-hash"
facematch_version = "new-commit-hash"
```

2. Aplique as alterações:

```bash
cd src/terraform/allid

# Revisar alterações
make plan ENV=dev

# Aplicar alterações
make apply ENV=dev
```

O Terraform atualizará as definições de tarefa do ECS e acionará uma implantação contínua.

### Atualizar variáveis de ambiente

1. Edite o `peer-service` módulo em `src/terraform/allid/modules/peer-service/main.tf`
2. Modifique as variáveis de ambiente na definição da tarefa
3. Aplique as alterações:

```bash
cd src/terraform/allid
make plan ENV=dev
make apply ENV=dev
```

Isso atualizará todas as instâncias de peer (default, client-a, client-b) com a nova configuração.

### Rotacionar certificados mTLS do Router

Se você precisar rotacionar os certificados mTLS do Router (expiração do certificado, incidente de segurança etc.), siga o mesmo processo da configuração inicial em [Etapa 5](#step-5-configure-router-mtls-certificates).

{% hint style="info" %}
**Quando rotacionar certificados**:

* Expiração/renovação do certificado
* Incidente de segurança que exige a substituição do certificado
* Mudança entre ambientes Certta (dev/stg/prd)
* Requisitos de conformidade para rotação periódica

A aplicação pegará automaticamente os novos certificados do Secrets Manager, sem precisar reiniciar o serviço.
{% endhint %}

### Escalar serviços

**Escalar serviços Peer**: Edite `environments/dev/terraform.tfvars` e altere a `desired_count` variável:

```hcl
desired_count = 2  # Altere de 1 para 2
```

Depois, aplique:

```bash
cd src/terraform/allid
make plan ENV=dev
make apply ENV=dev
```

**Escalar serviço Facematch**: Edite o `facematch` módulo em `environments/dev/main.tf`:

```hcl
module "facematch" {
  # ... outras configurações ...
  desired_count = 4  # Altere de 2 para 4
}
```

Depois, aplique:

```bash
cd src/terraform/allid
make plan ENV=dev
make apply ENV=dev
```

### Adicionar/remover instâncias de peer

Para adicionar uma nova instância de peer:

1. **Edite o ambiente `main.tf`** arquivo (por exemplo, `src/terraform/allid/environments/dev/main.tf`):

```hcl
# Adicionar novo módulo de peer
module "peer_client_c" {
  source = "../../modules/peer-service"

  prefix                   = var.prefix
  peer_name                = "client-c"
  vpc_id                   = local.vpc_id
  vpc_cidr_block           = local.vpc_cidr_block
  subnet_ids               = local.private_egress_subnet_ids
  cluster_id               = module.ecs_cluster.cluster_id
  namespace_id             = module.ecs_cluster.namespace_id
  namespace_name           = module.ecs_cluster.namespace_name
  listener_arn             = module.load_balancer.http_listener_arn
  alb_security_group_id    = module.load_balancer.security_group_id
  database_host            = module.database.cluster_endpoint
  database_port            = module.database.cluster_port
  database_name            = module.database.database_name
  database_secret_arn      = module.database.secret_arn
  ecr_repository_uri       = var.peer_ecr_repository_uri
  image_version            = var.peer_version
  router_rest_url          = var.router_rest_url
  router_certificate       = var.router_certificate
  router_private_key       = var.router_private_key
  cpu                      = 256
  memory                   = 512
  desired_count            = var.desired_count
  priority_base            = 190  # Use o próximo bloco de prioridade disponível
  enable_private_endpoints = false
  enable_ecs_exec          = var.enable_ecs_exec
  anonymization_enabled    = true
  cache_enabled            = true
  log_retention_days       = var.log_retention_days

  tags = {
    environment = var.environment
  }

  depends_on = [module.facematch]
}
```

2. **Adicione a saída para o novo peer** em `outputs.tf`:

```hcl
output "peer_client_c_service_name" {
  description = "Nome do serviço ECS do Peer Client C"
  value       = module.peer_client_c.service_name
}
```

3. **Aplique as alterações**:

```bash
cd src/terraform/allid
make plan ENV=dev
make apply ENV=dev
```

4. **Crie e inicialize o banco de dados** para o novo peer (veja a Etapa 6):

```bash
# Conectar ao banco de dados
mysql -h {DB_ENDPOINT} -u {DB_USERNAME} -p

# Criar banco de dados
CREATE DATABASE IF NOT EXISTS `peer-client-c`;
EXIT;

# Restaurar o dump
mysql -h {DB_ENDPOINT} -u {DB_USERNAME} -p peer-client-c < allid-dump.sql
```

{% hint style="info" %}
O novo Peer Service terá automaticamente seu segredo de certificado do Router criado pelo Terraform usando o mesmo certificado de `terraform.tfvars`. O serviço ficará saudável depois que você concluir a inicialização do banco de dados.
{% endhint %}

{% hint style="warning" %}
**Faixas de prioridade**: Cada peer deve usar um `priority_base` valor exclusivo para as regras do listener do ALB. Use faixas de 30 (por exemplo, 100-129, 130-159, 160-189, 190-219) para evitar conflitos.
{% endhint %}

## Solução de problemas

### Erro: Parâmetro SSM não encontrado

**Causa**: A infraestrutura de rede (src/terraform/shared) não foi implantada, ou os Parâmetros SSM não foram criados.

**Solução**:

1. **Verifique se os parâmetros existem**:

```bash
aws ssm get-parameter --name "/shared/dev/vpc-id" --query "Parameter.Value" --output text
```

2. **Se os parâmetros não existirem**, implante a infraestrutura compartilhada:

```bash
cd src/terraform/shared
make init ENV=dev
make apply ENV=dev
```

3. **Se você tiver uma VPC existente**, crie os Parâmetros SSM manualmente:

```bash
# Substitua pelos seus valores reais
aws ssm put-parameter --name "/shared/dev/vpc-id" --value "vpc-xxxxx" --type "String"
aws ssm put-parameter --name "/shared/dev/vpc-cidr" --value "10.0.0.0/16" --type "String"
aws ssm put-parameter --name "/shared/dev/public-subnet-ids" --value "subnet-aaa,subnet-bbb" --type "String"
aws ssm put-parameter --name "/shared/dev/private-egress-subnet-ids" --value "subnet-ccc,subnet-ddd" --type "String"
aws ssm put-parameter --name "/shared/dev/private-isolated-subnet-ids" --value "subnet-eee,subnet-fff" --type "String"
```

### O serviço Peer não inicia

**Verificar logs do CloudWatch**:

```bash
# Exibir logs do peer específico
aws logs tail /ecs/allid/peer-default --follow
```

**Causas comuns**:

1. **Banco de dados não inicializado**: Veja o Passo 6 (inicialização do banco de dados e restauração do dump)
2. **Falha na conexão com o banco de dados**: Verifique os security groups e o endpoint do RDS
3. **Serviço Facematch indisponível**: Verifique o status do serviço Facematch

**Verifique o motivo da parada da task**:

**Console da AWS**:

1. Console do ECS → Clusters → allid-cluster
2. Clique no serviço (por exemplo, allid-peer-default)
3. Vá para a aba "Tasks" → clique nas tasks paradas
4. Verifique o campo "Stopped reason"

**AWS CLI**:

```bash
CLUSTER_NAME=$(terraform output -raw ecs_cluster_name)

aws ecs describe-tasks \
  --cluster $CLUSTER_NAME \\
  --tasks $(aws ecs list-tasks --cluster $CLUSTER_NAME --service-name allid-peer-default --query 'taskArns[0]' --output text) \
  --query 'tasks[0].stoppedReason'
```

### Falhas na verificação de integridade

**Verifique o status do serviço ECS**:

```bash
CLUSTER_NAME=$(terraform output -raw ecs_cluster_name)

# Verifique o status do serviço
aws ecs describe-services \\
  --cluster $CLUSTER_NAME \\
  --services allid-peer-default allid-peer-client-a allid-peer-client-b allid-facematch \\
  --query 'services[*].[serviceName, runningCount, desiredCount, healthCheckGracePeriodSeconds]' \
  --output table
```

**Verifique a integridade dos alvos do ALB**:

**AWS CLI**:

```bash
# Liste os target groups
aws elbv2 describe-target-groups \
  --query 'TargetGroups[?contains(TargetGroupName, `allid`)][TargetGroupName, TargetGroupArn]' \
  --output table

# Verifique a integridade de um target group específico (substitua TARGET_GROUP_ARN)
aws elbv2 describe-target-health --target-group-arn TARGET_GROUP_ARN
```

**Problemas comuns**:

* Security groups bloqueando o tráfego entre o ALB e os Peer Services
* Serviço não registrado no Cloud Map (a resolução de DNS falha)
* Erros de conexão com o banco de dados (verifique o secret de credenciais)
* Serviço Facematch não respondendo
* Período de carência da verificação de integridade insuficiente

### Nenhuma task em execução / Serviços mostrando 0/0

**Causa**: `desired_count` está definido como 0 em `terraform.tfvars`.

**Solução**:

Isso geralmente é intencional para ambientes de desenvolvimento para economizar custos. Para iniciar as tasks:

1. Edite `environments/dev/terraform.tfvars`:

```hcl
desired_count = 1  # Altere de 0 para 1
```

2. Aplique as alterações:

```bash
cd src/terraform/allid
make plan ENV=dev
make apply ENV=dev
```

3. Verifique se as tasks estão iniciando:

```bash
cd environments/dev
CLUSTER_NAME=$(terraform output -raw ecs_cluster_name)
aws ecs list-tasks --cluster $CLUSTER_NAME
```

{% hint style="info" %}
**Dica de economia de custos**: Defina `desired_count = 0` quando não estiver usando ativamente os ambientes de desenvolvimento para parar todas as tasks do ECS e reduzir os custos de infraestrutura.
{% endhint %}

### Não consegue acessar o ALB

**Verifique se seu IP está na allowlist**:

```bash
ALB_DNS=$(terraform output -raw alb_dns_name)
curl -v http://${ALB_DNS}/default/status
```

Se você receber timeout de conexão ou 403 Forbidden, seu IP não está na allowlist.

**Adicione seu IP à allowlist**:

1. Edite `environments/dev/terraform.tfvars`:

```hcl
alb_allowed_cidr_blocks = [
  "3.218.90.124/32",     # IPs do roteador Certta
  "44.219.96.170/32",
  # ... outros IPs ...
  "YOUR_IP_HERE/32",     # Adicione seu IP
]
```

2. Aplique as alterações:

```bash
cd src/terraform/allid
make plan ENV=dev
make apply ENV=dev
```

{% hint style="info" %}
Veja [Melhores Práticas de Segurança](/caf-api/caf-api-pt-br/all-id/security-best-practices.md) para a lista completa de endereços IP do Certta Router que devem estar na allowlist.
{% endhint %}

## Limpeza

Para remover todos os recursos e parar de incorrer em custos:

```bash
# Destruir a aplicação All ID
cd src/terraform/allid
make destroy ENV=dev

# Destruir a infraestrutura compartilhada (somente se você a implantou)
cd ../shared
make destroy ENV=dev
```

{% hint style="info" %}
**Destruição direcionada**: Se você precisar destruir recursos específicos em uma ordem específica, você pode navegar até o diretório do ambiente e usar a destruição direcionada:

```bash
cd src/terraform/allid/environments/dev
terraform destroy -target=module.peer_default
terraform destroy -target=module.peer_client_a
terraform destroy -target=module.peer_client_b
terraform destroy -target=module.facematch
terraform destroy -target=module.load_balancer
terraform destroy -target=module.database
terraform destroy -target=module.ecs_cluster
```

{% endhint %}

{% hint style="danger" %}
**Aviso**: Isso exclui permanentemente todos os recursos, incluindo:

* Banco de dados Aurora MySQL e todos os dados
* logs do CloudWatch
* secrets do Secrets Manager (credenciais do banco de dados, certificados do Router)
* serviços e tasks do ECS

Garanta que você tenha backups antes de destruir. Snapshots do banco de dados NÃO são criados automaticamente durante a destruição.
{% endhint %}

**Criar snapshot do banco de dados antes da limpeza** (opcional):

```bash
aws rds create-db-cluster-snapshot \
  --db-cluster-identifier allid-database-cluster \
  --db-cluster-snapshot-identifier allid-final-snapshot-$(date +%Y%m%d)
```

## Padronização de Ambientes

Todos os ambientes (dev, stg, prd) seguem a mesma estrutura base e os mesmos padrões de configuração. Essa padronização simplifica o gerenciamento e reduz erros ao promover mudanças entre ambientes.

### Componentes Padronizados

1. **Estrutura dos Módulos**: Todos os ambientes usam os mesmos módulos com os mesmos parâmetros
2. **Nomenclatura de Tags**: Em letras minúsculas com hífens (por exemplo, `environment`, `managed-by`, `business-unity-id`)
3. **Valores Padrão**: Padrões consistentes entre ambientes, personalizáveis via `terraform.tfvars`
4. **Nomeação de Recursos**: `{prefix}-{resource-type}` padrão

### Personalização Específica por Ambiente

Personalize cada ambiente ajustando os valores em `environments/<env>/terraform.tfvars`:

**Desenvolvimento (dev)**:

```hcl
prefix                 = "allid-dev"
desired_count          = 0  # Economize custos quando não estiver em uso
enable_ecs_exec        = true  # Habilite a depuração
database_min_capacity  = 0  # Escala para zero quando ocioso
database_max_capacity  = 2
log_retention_days     = 7
database_deletion_protection = false
```

**Homologação (stg)**:

```hcl
prefix                 = "allid-stg"
desired_count          = 1  # Uma task por peer
enable_ecs_exec        = false
database_min_capacity  = 0
database_max_capacity  = 2
log_retention_days     = 7
database_deletion_protection = true
```

**Produção (prd)**:

```hcl
prefix                             = "allid-prd"
desired_count                      = 2  # Alta disponibilidade
enable_ecs_exec                    = false
database_min_capacity              = 0.5  # Sempre ativo
database_max_capacity              = 4
database_backup_retention_period   = 30
database_deletion_protection       = true
alb_enable_deletion_protection     = true
log_retention_days                 = 30
```

### Tags Padrão

Todos os recursos são automaticamente marcados via AWS provider `default_tags`:

```hcl
default_tags {
  tags = {
    environment       = var.environment      # dev, stg, prd
    managed-by        = "Terraform"
    business-unity-id = "allid"
    workload-id       = "allid"
    cost-center       = "engineering"
  }
}
```

Tags adicionais específicas de recursos podem ser adicionadas por meio de parâmetros do módulo.

### Promoção de Mudanças Entre Ambientes

Melhor prática para promover mudanças de dev → stg → prd:

1. **Testar em Desenvolvimento**:

   ```bash
   cd src/terraform/allid
   # Editar environments/dev/terraform.tfvars
   make plan ENV=dev
   make apply ENV=dev
   # Teste completamente
   ```
2. **Promover para Homologação**:

   ```bash
   # Copie as mudanças testadas para homologação
   # Edite environments/stg/terraform.tfvars com as mesmas mudanças
   make plan ENV=stg
   make apply ENV=stg
   # Verifique
   ```
3. **Implantar em Produção**:

   ```bash
   # Aplique em produção com a devida revisão
   # Edite environments/prd/terraform.tfvars
   make plan ENV=prd > plan-output.txt
   # Revise cuidadosamente plan-output.txt
   make apply ENV=prd
   ```

{% hint style="warning" %}
**Checklist de Implantação em Produção**:

* [ ] Mudanças testadas em dev e stg
* [ ] Plano do Terraform revisado e aprovado
* [ ] Backup do banco de dados concluído (se aplicável)
* [ ] Plano de rollback documentado
* [ ] Equipe notificada sobre a janela de implantação
* [ ] Monitoramento e alertas prontos
  {% endhint %}

## Estrutura Detalhada de Arquivos

### Aplicação All ID (`src/terraform/allid/`)

```
src/terraform/allid/
├── README.md                           # Documentação do projeto
├── Makefile                            # Automação de comandos
├── modules/                            # Módulos reutilizáveis
│   ├── ecs-cluster/
│   │   ├── main.tf                     # Cluster ECS + descoberta de serviços
│   │   ├── variables.tf
│   │   └── outputs.tf
│   ├── database/
│   │   ├── main.tf                     # Aurora MySQL Serverless V2
│   │   ├── variables.tf
│   │   └── outputs.tf
│   ├── load-balancer/
│   │   ├── main.tf                     # ALB + Listener + Security Group
│   │   ├── variables.tf
│   │   └── outputs.tf
│   ├── peer-service/
│   │   ├── main.tf                     # Definição da task + Serviço + Secrets
│   │   ├── variables.tf
│   │   └── outputs.tf
│   └── facematch-service/
│       ├── main.tf                     # Definição da task + Serviço
│       ├── variables.tf
│       └── outputs.tf
└── environments/
    ├── dev/
    │   ├── main.tf                     # Configuração do ambiente
    │   ├── variables.tf                # Definições de variáveis
    │   ├── outputs.tf                  # Saídas do ambiente
    │   ├── terraform.tfvars.example    # Valores de exemplo
    │   └── terraform.tfvars            # Valores reais (não versionados)
    ├── stg/
    └── prd/
```

### Infraestrutura Compartilhada (`src/terraform/shared/`)

```
src/terraform/shared/
├── README.md                           # Documentação do projeto
├── Makefile                            # Automação de comandos
├── modules/
│   └── network/
│       ├── main.tf                     # VPC, Subnets, IGW, NAT
│       ├── variables.tf
│       └── outputs.tf
└── environments/
    ├── dev/
    │   ├── main.tf                     # Configuração do ambiente
    │   ├── ssm.tf                      # Parâmetros SSM para referência cruzada
    │   ├── variables.tf                # Definições de variáveis
    │   ├── outputs.tf                  # Saídas do ambiente
    │   ├── terraform.tfvars.example    # Modelo de configuração
    │   └── terraform.tfvars            # Valores reais (não versionados)
    ├── stg/
    └── prd/
```

### Arquivos Principais Explicados

**`main.tf`**:

* Configuração do Terraform e do provider AWS
* Chamadas de módulos com parâmetros
* Fontes de dados para Parâmetros SSM (projeto allid)
* Estrutura idêntica entre ambientes

**`variables.tf`**:

* Todas as definições de variáveis com tipos e padrões
* Padrões padronizados entre ambientes
* Documentação inline para cada variável

**`outputs.tf`**:

* Saídas dos recursos criados
* Usado para recuperar valores após a implantação
* Referenciado por módulos dependentes ou sistemas externos

**`terraform.tfvars.example`**:

* Modelo com todos os valores configuráveis
* Comentários explicativos para cada variável
* Valores de exemplo específicos do ambiente

**`terraform.tfvars`** (não versionado):

* Valores reais do ambiente
* Contém segredos (certificados, chaves privadas)
* Deve ser criado a partir do `.example` modelo
* **Nunca faça commit deste arquivo no git**

**`ssm.tf`** (somente compartilhada):

* Cria Parâmetros SSM para VPC e IDs de sub-rede
* Permite que outros projetos consultem recursos
* Formato: `/shared/{environment}/{parameter-name}`

## Próximos passos

* Revise [Requisitos Técnicos](/caf-api/caf-api-pt-br/all-id/technical-requirements.md) para especificações de recursos
* Revise [Configuração](/caf-api/caf-api-pt-br/all-id/configuration.md) para detalhes das variáveis de ambiente
* Revise [Melhores Práticas de Segurança](/caf-api/caf-api-pt-br/all-id/security-best-practices.md) para fortalecimento


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.caf.io/caf-api/caf-api-pt-br/all-id/production-guidance/ecs-terraform.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
