● INFRAESTRUTURA 01.04 01 de jul. de 2026 4 min

Como estruturar um projeto de IaC com Pulumi para múltiplos ambientes

Ambientes comuns e como estruturar a criação deles em um único projeto reprodutível

Ilustração de um diagrama sobre IaC
FIG.1 · diagrama IaC

Acho que inegávelmente um dos principais pontos quando começamos os estudos sobre infraestrutura, cloud, devops e etc é IaC. Versionamento de código sempre foi considerado como um dos cernes do desenvolvimento, é indiscutível que a maioria esmagadora dos softwares existentes no mercado hoje tem um repositório git por trás, e tudo isso só pra poder dar um blame em uma gambiarra de 6 meses atrás e descobrir que foi a gente mesmo que fez.

Infraestrutura como código vem justamente pra trazer toda a graça do VSC pra nossa construção de ambientes e fortifica algumas práticas essenciais como reprodutibilidade. Nesse post quero decorrer sobre como estruturar sua infraestrutura como código para suportar múltiplos ambientes.

Por que múltiplos ambientes?

Software é algo previsivelmente imprevisível, tanto é que uma das disciplinas mais famosas que temos é o chaos engineering, feito justamente para tentar garantir o máximo possível de resiliência nessas situações imprevisíveis e aleatórias, caóticas. Um dos processos dentro da garantia de qualidade é o teste de features e entregáveis em multiplos ambientes antes da produção.

Dev: O ambiente que o desenvolvedor vai trabalhar é tido comumente como o ambiente de dev/develop/desenvolvimento. Pode ele ser local, cloud, virtualizado, uma VPS, um WSL, independente, é o ambiente onde o nosso desenvolvedor vai construir e ajustar do zero.

Homolog: Aqui é geralmente onde o time de QA vai testar a feature e a integração de ponta-a-ponta em um ambiente isolado e seguro. O cliente não têm acesso, é interno.

Staging: Bem semelhante ao ambiente de homologação mas com a ressalva de que a idéia aqui é ele ser um réplica exata do ambiente de produção. Muito útil para testes de estresse e capacity planning.

Produção: Ambiente final, clientes acessam.

A ideia do fluxo é sempre promover uma feature entre esses ambientes. É comum encontrar fluxos onde só exista um ambiente de homologação e não um de staging, ou só um de staging que serve como homologação também, ou os que não tem nenhum e testam direto em produção rezando pra não quebrar nada.

Estrutura IaC para suportar múltiplos ambientes

Vou usar aqui o Pulumi para exemplo, mas todos os conceitos aqui discutidos podem ser aplicados em outras ferramentas como Terraform.

Um dos conceitos mais difundidos aqui é que uma stack (workspace no caso do Terraform) equivale sempre a um ambiente. Considere o seguinte.

Nós criamos um endpoint novo na nossa API e precisamos validar o funcionamento dela de ponta-a-ponta em um ambiente de staging que vamos criar, e estressar esse endpoint ao máximo em um ambiente o mais próximo possível do de produção para ter noção da carga que aguentamos. No Pulumi, temos os Pulumi.yaml e Pulumi.<stack>.yaml. Considere o primeiro como os “defaults” e o segundo como o override dinâmico por stack.

const config = new pulumi.Config();

const environment = config.require("environment");
const instanceType = config.require("instanceType");
const instanceCount = config.requireNumber("instanceCount");
const allowedCidrBlocks = config.requireObject<string[]>("allowedCidrBlocks");

Isso nos possibilita ter uma única entrada de código e alterar o que for necessário via arquivos de configuração por stack, o que facilita muito mantermos a réplica de ambiente necessária para garantir que staging está o mais próximo possível de production.

#Pulumi.yaml
name: pulumi-ec2-alb
runtime: nodejs
description: Exemplo de EC2 + Security Group + ALB com Pulumi, estruturado para múltiplos ambientes (staging/prod)
config:
  environment:
    type: string
    description: Nome do ambiente; usado em prefixos e tags. Definido por cada stack.
  instanceType:
    type: string
    description: Tipo da instância EC2.
    default: t3.micro
  instanceCount:
    type: integer
    description: Quantas instâncias EC2 atrás do ALB.
    default: 1
  allowedCidrBlocks:
    type: array
    items:
      type: string
    description: CIDRs liberados para acessar o ALB na porta 80.
    default:
      - 0.0.0.0/0
#Pulumi.prod.yaml
config:
  aws:region: us-east-1
  pulumi-ec2-alb:environment: prod
  # prod sobrescreve os defaults: instância maior e mais réplicas.
  pulumi-ec2-alb:instanceType: t3.small
  pulumi-ec2-alb:instanceCount: 2
#Pulumi.staging.yaml
config:
  aws:region: us-east-1
  pulumi-ec2-alb:environment: staging
  # staging idêntico a prod, queremos o mais próximo possível.
  pulumi-ec2-alb:instanceType: t3.small
  pulumi-ec2-alb:instanceCount: 2

E se quiséssemos subir um ambiente de homologação, reduzido, somente para testes de features? Basta um pulumi stack init homolog e ajustar o arquivo de configuração conforme o estado desejado

#Pulumi.homolog.yaml
config:
  aws:region: us-east-1
  # homolog herda quase tudo dos defaults do Pulumi.yaml
  # (instanceType=t3.micro, instanceCount=1, allowedCidrBlocks=0.0.0.0/0).
  # Só precisamos identificar o ambiente:
  pulumi-ec2-alb:environment: homolog

Tudo isso para rodar nesse único entrypoint.


const servers: aws.ec2.Instance[] = [];
for (let i = 0; i < instanceCount; i++) {
    servers.push(new aws.ec2.Instance(`${prefix}-web-${i}`, {
        ami: ami.id,
        instanceType: instanceType,
        subnetId: subnets.ids.apply(ids => ids[i % ids.length]),
        vpcSecurityGroupIds: [ec2Sg.id],
        userData: userData,
        tags: { ...commonTags, Name: `${prefix}-web-${i}` },
    }));
}

Pra fechar

Esse setup inicial parece bem simples né? E realmente é, mas ainda sim tem algumas armadilhas e cuidados que devemos tomar pensando em escala e ambientes reais. A complexidade vai entrando conforme vamos escalando e queremos manter nossa IaC como fonte da verdade inclusive do runtime da nossa aplicação, o que é bem comum em aplicações com ECS por exemplo, onde começamos a separar as stacks não só por ambiente mas também entre o que é “volátil” e o que é “estável”, aqui definimos até qual a tag da imagem docker rodando atualmente na aplicação, e não podemos que updates de imagem travem ou afetem updates no restante da infraestrutura, vide o que é volátil e o que é estável.

Precisa de ajuda?

Sente que precisa de ajuda pra estruturar a sua própria infraestrutura ou algo do que eu falei aqui faz sentido pra você mas sente que é muito complicado fazer por conta? Aqui na UEEK a gente fornece esse tipo de consultoria pra facilitar sua estruturação de DevOps, desde infraestrutura até CI/CD, segurança e observabilidade. Clica aqui e confere gratuitamente!

voltar para /blog END · 01.04