Files
AI-inovyo-assistende-db/docs/pulumi-guide.md
2026-05-14 15:29:03 -03:00

7.2 KiB

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

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

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

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

1. Obter o digest da nova imagem:

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:

ecr_image_digest: sha256:<novo-digest>

3. Revisar e aplicar:

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.

env_variables:
  NOVA_VARIAVEL: valor

Verificar o output após o deploy

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:

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:

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:

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:

pulumi refresh --stack <stack-name>   # sincroniza estado com AWS
pulumi up --stack <stack-name>

Recurso preso em estado de update:

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:

aws logs tail <nome-do-log-group> --follow --region us-east-1

Verificar tasks rodando no ECS:

aws ecs list-tasks --cluster <nome-do-cluster> --region us-east-1