257 lines
7.2 KiB
Markdown
257 lines
7.2 KiB
Markdown
# Guia Pulumi
|
|
|
|
## O que é Pulumi?
|
|
|
|
Pulumi é uma ferramenta de **Infrastructure as Code (IaC)**: em vez de clicar no console da AWS, você descreve os recursos em código Python (ou outras linguagens) e o Pulumi cria, atualiza e destrói esses recursos de forma controlada e reproduzível.
|
|
|
|
### Conceitos básicos
|
|
|
|
| Conceito | O que é |
|
|
|----------|---------|
|
|
| **Projeto** | O diretório com `Pulumi.yaml` — define o nome e a linguagem do projeto |
|
|
| **Stack** | Um ambiente independente do mesmo projeto (ex: `dev`, `prod`, `Inovyo`). Cada stack tem seu próprio estado e configuração |
|
|
| **Estado** | Arquivo que o Pulumi mantém mapeando cada recurso do código a um recurso real na AWS. É a "memória" do Pulumi |
|
|
| **`pulumi preview`** | Mostra o que **vai** mudar, sem aplicar nada — equivalente a um "dry run" |
|
|
| **`pulumi up`** | Aplica as mudanças: cria, atualiza ou remove recursos para corresponder ao código |
|
|
| **Output** | Valores exportados pelo código após o deploy (ex: a URL do ALB) |
|
|
|
|
### Como o Pulumi sabe o que mudar?
|
|
|
|
1. Você edita o código ou o arquivo de configuração
|
|
2. `pulumi preview` compara o código com o estado salvo e mostra o diff
|
|
3. `pulumi up` aplica o diff na AWS e atualiza o estado
|
|
|
|
---
|
|
|
|
## Pré-requisitos
|
|
|
|
- [Pulumi CLI](https://www.pulumi.com/docs/install/) instalado
|
|
- AWS CLI configurado com credenciais válidas para a conta
|
|
- Python 3.12+ e `venv`
|
|
|
|
---
|
|
|
|
## Estrutura do projeto
|
|
|
|
```
|
|
infra/ecs_alb/
|
|
├── Pulumi.yaml # Metadados do projeto (nome, runtime)
|
|
├── Pulumi.Inovyo.yaml # Configuração da stack "Inovyo" (região, VPC, ECS, env vars...)
|
|
├── __main__.py # Ponto de entrada — define ALB, cluster ECS e chama ecs.deploy_app()
|
|
├── conf.py # Lê as configurações do Pulumi e as expõe como variáveis Python
|
|
├── ecs.py # Cria task definition, service, target groups, listeners e auto-scaling
|
|
├── ecr.py # Referencia a imagem no ECR pelo digest ou tag
|
|
├── iam.py # Cria execution role e task role com políticas (Bedrock, DynamoDB, Secrets Manager...)
|
|
└── kms.py # Chave KMS (usada opcionalmente para criptografia de segredos)
|
|
```
|
|
|
|
---
|
|
|
|
## Setup inicial
|
|
|
|
```bash
|
|
cd infra/ecs_alb
|
|
|
|
# Criar e ativar virtualenv
|
|
python -m venv .venv
|
|
source .venv/bin/activate
|
|
|
|
# Instalar dependências
|
|
pip install -r requirements.txt
|
|
|
|
# Selecionar a stack
|
|
pulumi stack select <stack-name>
|
|
```
|
|
|
|
---
|
|
|
|
## Comandos principais
|
|
|
|
| Comando | O que faz |
|
|
|---------|-----------|
|
|
| `pulumi preview` | Mostra o que será criado/alterado/destruído **sem aplicar** |
|
|
| `pulumi preview --diff` | Igual ao anterior, com diff detalhado de cada recurso |
|
|
| `pulumi up` | Aplica as mudanças na AWS |
|
|
| `pulumi up --yes` | Aplica sem pedir confirmação interativa |
|
|
| `pulumi destroy` | Remove **todos** os recursos da stack da AWS |
|
|
| `pulumi stack ls` | Lista todas as stacks do projeto |
|
|
| `pulumi stack output` | Exibe os outputs exportados (ex: URL do ALB) |
|
|
| `pulumi refresh` | Sincroniza o estado Pulumi com o estado real da AWS |
|
|
|
|
Sempre prefira `pulumi preview` antes de `pulumi up` para revisar o impacto das mudanças.
|
|
|
|
---
|
|
|
|
## Arquivo de configuração: `Pulumi.Inovyo.yaml`
|
|
|
|
Toda a configuração da stack fica nesse arquivo. As seções principais:
|
|
|
|
### Rede
|
|
|
|
```yaml
|
|
app-ecs:network:
|
|
vpc_id: <vpc-id>
|
|
alb_internal: false
|
|
alb_subnet_ids: # Subnets públicas do ALB (mínimo 2, mesma região)
|
|
- <subnet-publica-1>
|
|
- <subnet-publica-2>
|
|
alb_allow_ingress_cidr: # IPs que podem acessar o ALB
|
|
- <ip-permitido>/32
|
|
ecs_subnet_ids: # Subnets privadas dos containers
|
|
- <subnet-privada-1>
|
|
- <subnet-privada-2>
|
|
```
|
|
|
|
### ECS / Container
|
|
|
|
```yaml
|
|
app-ecs:ecs:
|
|
- task_name: assisnte-analitico-db-dev
|
|
ecr_repo_name: assistente-analitico-db-dev
|
|
# Use ecr_image_digest OU ecr_image_tag (nunca os dois)
|
|
ecr_image_digest: sha256:<digest>
|
|
cpu: 256
|
|
memory: 512
|
|
desired_count: 1
|
|
use_load_balancer: true
|
|
auto_scaling:
|
|
min_capacity: 1
|
|
max_capacity: 3
|
|
target_value: 60.0 # % de CPU alvo para escalar
|
|
lb_configs:
|
|
- name: api
|
|
listener_port: 8000
|
|
target_port: 8000
|
|
container_port: 8000
|
|
- name: streamlit
|
|
listener_port: 8501
|
|
target_port: 8501
|
|
container_port: 8501
|
|
env_variables:
|
|
TABLE: poc_dnx_monthly_summary
|
|
REGION: us-east-1
|
|
```
|
|
|
|
---
|
|
|
|
## Fluxo de deploy de nova imagem
|
|
|
|
Após buildar e publicar uma nova imagem Docker (veja [deployment.md](deployment.md)):
|
|
|
|
**1. Obter o digest da nova imagem:**
|
|
|
|
```bash
|
|
aws ecr describe-images \
|
|
--repository-name assistente-analitico-db-dev \
|
|
--region us-east-1 \
|
|
--query 'sort_by(imageDetails, &imagePushedAt)[-1].imageDigest' \
|
|
--output text
|
|
```
|
|
|
|
**2. Atualizar o `Pulumi.Inovyo.yaml`:**
|
|
|
|
```yaml
|
|
ecr_image_digest: sha256:<novo-digest>
|
|
```
|
|
|
|
**3. Revisar e aplicar:**
|
|
|
|
```bash
|
|
cd infra/ecs_alb
|
|
pulumi preview --diff --stack <stack-name>
|
|
pulumi up --stack <stack-name>
|
|
```
|
|
|
|
---
|
|
|
|
## Adicionar ou alterar variáveis de ambiente do container
|
|
|
|
Edite a seção `env_variables` em `Pulumi.Inovyo.yaml` e rode `pulumi up`. O Pulumi atualizará a task definition e forçará o re-deploy do serviço ECS automaticamente.
|
|
|
|
```yaml
|
|
env_variables:
|
|
NOVA_VARIAVEL: valor
|
|
```
|
|
|
|
---
|
|
|
|
## Verificar o output após o deploy
|
|
|
|
```bash
|
|
pulumi stack output --stack <stack-name>
|
|
```
|
|
|
|
Retorna a URL do ALB, por exemplo:
|
|
```
|
|
url: http://alb-assistente-analitico-xxxxxxxx.us-east-1.elb.amazonaws.com
|
|
```
|
|
|
|
---
|
|
|
|
## Alterar capacidade de auto-scaling
|
|
|
|
Edite `auto_scaling` em `Pulumi.Inovyo.yaml`:
|
|
|
|
```yaml
|
|
auto_scaling:
|
|
min_capacity: 1 # mínimo de tasks rodando
|
|
max_capacity: 5 # máximo de tasks
|
|
target_value: 70.0 # escala quando CPU média ultrapassar 70%
|
|
```
|
|
|
|
Depois rode `pulumi up`.
|
|
|
|
---
|
|
|
|
## Permitir acesso ao ALB por Security Group
|
|
|
|
Por padrão, o acesso ao ALB é restrito por CIDR (`alb_allow_ingress_cidr`). Para permitir um security group no lugar de um IP, são necessárias duas alterações:
|
|
|
|
**1. Edite `__main__.py`** — troque `cidr_blocks` por `security_groups` na regra de ingress do ALB:
|
|
|
|
```python
|
|
ingress=[aws.ec2.SecurityGroupIngressArgs(
|
|
protocol="-1",
|
|
from_port=0,
|
|
to_port=0,
|
|
security_groups=config.network["alb_allow_ingress_sgs"],
|
|
)],
|
|
```
|
|
|
|
**2. Edite `Pulumi.Inovyo.yaml`** — substitua `alb_allow_ingress_cidr` por:
|
|
|
|
```yaml
|
|
app-ecs:network:
|
|
alb_allow_ingress_sgs:
|
|
- <security-group-id>
|
|
```
|
|
|
|
> Para manter ambos (IP e SG ao mesmo tempo), adicione os dois campos à mesma `SecurityGroupIngressArgs`, ou crie entradas separadas em `ingress`.
|
|
|
|
---
|
|
|
|
## Solução de problemas
|
|
|
|
**`pulumi up` falha com erro de estado inconsistente:**
|
|
```bash
|
|
pulumi refresh --stack <stack-name> # sincroniza estado com AWS
|
|
pulumi up --stack <stack-name>
|
|
```
|
|
|
|
**Recurso preso em estado de update:**
|
|
```bash
|
|
pulumi stack export --stack <stack-name> > state.json
|
|
# Editar state.json para remover o recurso problemático
|
|
pulumi stack import --stack <stack-name> < state.json
|
|
```
|
|
|
|
**Ver logs do container após o deploy:**
|
|
```bash
|
|
aws logs tail <nome-do-log-group> --follow --region us-east-1
|
|
```
|
|
|
|
**Verificar tasks rodando no ECS:**
|
|
```bash
|
|
aws ecs list-tasks --cluster <nome-do-cluster> --region us-east-1
|
|
```
|