Introdução ao Pulumi: infraestrutura como código em sua linguagem favorita
1. O que é o Pulumi e por que ele se destaca no ecossistema IaC
Pulumi é uma plataforma de infraestrutura como código (IaC) que permite gerenciar recursos de nuvem usando linguagens de programação reais como TypeScript, Python, Go, C# e Java. Diferente de ferramentas como Terraform, que utilizam uma DSL (HCL) proprietária, o Pulumi permite que você escreva infraestrutura com a mesma sintaxe, bibliotecas e ferramentas que já usa no desenvolvimento de software.
As diferenças cruciais em relação ao Terraform incluem:
- Paradigma de programação: No Terraform, você declara recursos em HCL; no Pulumi, você usa loops, condicionais, funções e classes nativas da linguagem.
- Gerenciamento de estado: O Pulumi oferece backend gerenciado (Pulumi Cloud) ou auto-gerenciado (S3, Azure Blob, GCS), com suporte nativo a versionamento e colaboração.
- Provedores: O Pulumi possui provedores oficiais para AWS, Azure, GCP, Kubernetes e mais de 100 provedores comunitários.
Em comparação com o AWS CDK, o Pulumi se destaca por ser multi-cloud (não apenas AWS) e por oferecer uma experiência consistente entre provedores.
As vantagens práticas incluem:
- Reuso de bibliotecas e pacotes (npm, pip, Go modules)
- Uso de IDEs com autocomplete, refatoração e debugging nativo
- Testes unitários com frameworks como Jest, pytest e Ginkgo
- Depuração com breakpoints e logs diretamente no código
2. Configurando o ambiente e primeiro projeto
Para começar, instale o CLI do Pulumi:
# Linux/macOS
curl -fsSL https://get.pulumi.com | sh
# Windows (PowerShell)
iwr https://get.pulumi.com/install.ps1 -useb | iex
Configure o backend de estado. Vamos usar o Pulumi Cloud (gratuito para uso individual):
pulumi login
Acesse https://app.pulumi.com para criar uma conta e obter um token de acesso.
Crie seu primeiro projeto:
mkdir meu-projeto-pulumi
cd meu-projeto-pulumi
pulumi new aws-typescript
Isso gera a estrutura:
- Pulumi.yaml: arquivo de configuração do projeto
- Pulumi.dev.yaml: configurações específicas do stack dev
- index.ts: código principal da infraestrutura
Configure as credenciais da AWS:
pulumi config set aws:region us-east-1
3. Escrevendo sua primeira infraestrutura: recursos e stacks
Vamos criar uma VPC com subnets, security groups e uma instância EC2 em TypeScript:
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
// Criação de uma VPC
const vpc = new aws.ec2.Vpc("minha-vpc", {
cidrBlock: "10.0.0.0/16",
enableDnsSupport: true,
enableDnsHostnames: true,
tags: { Name: "minha-vpc" },
});
// Subnet pública
const subnet = new aws.ec2.Subnet("minha-subnet", {
vpcId: vpc.id,
cidrBlock: "10.0.1.0/24",
mapPublicIpOnLaunch: true,
availabilityZone: "us-east-1a",
tags: { Name: "minha-subnet" },
});
// Security Group
const sg = new aws.ec2.SecurityGroup("meu-sg", {
vpcId: vpc.id,
ingress: [{ protocol: "tcp", fromPort: 22, toPort: 22, cidrBlocks: ["0.0.0.0/0"] }],
egress: [{ protocol: "-1", fromPort: 0, toPort: 0, cidrBlocks: ["0.0.0.0/0"] }],
tags: { Name: "meu-sg" },
});
// Instância EC2
const instance = new aws.ec2.Instance("minha-instancia", {
ami: "ami-0c55b159cbfafe1f0", // Amazon Linux 2
instanceType: "t2.micro",
subnetId: subnet.id,
vpcSecurityGroupIds: [sg.id],
tags: { Name: "minha-instancia" },
});
export const instancePublicIp = instance.publicIp;
Stacks permitem criar ambientes isolados:
pulumi stack init dev
pulumi stack init staging
pulumi stack init prod
Para alternar entre stacks:
pulumi stack select dev
pulumi up
4. Trabalhando com provedores e componentes reutilizáveis
O Pulumi suporta provedores oficiais para AWS, Azure, GCP, Kubernetes, Cloudflare, Datadog e muitos outros. Vamos criar um componente reutilizável para deploy serverless com API Gateway + Lambda:
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
// Componente reutilizável
export class ServerlessAPI extends pulumi.ComponentResource {
public readonly apiUrl: pulumi.Output<string>;
constructor(name: string, args: ServerlessAPIArgs, opts?: pulumi.ComponentResourceOptions) {
super("my:modules:ServerlessAPI", name, args, opts);
const role = new aws.iam.Role(`${name}-role`, {
assumeRolePolicy: JSON.stringify({
Version: "2012-10-17",
Statement: [{
Action: "sts:AssumeRole",
Principal: { Service: "lambda.amazonaws.com" },
Effect: "Allow",
}],
}),
}, { parent: this });
const lambda = new aws.lambda.Function(`${name}-fn`, {
runtime: "nodejs18.x",
handler: "index.handler",
role: role.arn,
code: new pulumi.asset.AssetArchive({
".": new pulumi.asset.FileArchive("./lambda"),
}),
}, { parent: this });
const api = new aws.apigatewayv2.Api(`${name}-api`, {
protocolType: "HTTP",
routeKey: "$default",
target: lambda.arn,
}, { parent: this });
this.apiUrl = api.apiEndpoint;
}
}
// Uso do componente
const minhaAPI = new ServerlessAPI("minha-api", {});
export const url = minhaAPI.apiUrl;
5. Gerenciamento de estado, secrets e políticas de segurança
O fluxo de trabalho básico do Pulumi:
# Visualizar mudanças
pulumi preview
# Aplicar mudanças
pulumi up
# Destruir recursos
pulumi destroy
Para gerenciar segredos:
pulumi config set --secret db_password "minha-senha-super-secreta"
No código, acesse o segredo:
const config = new pulumi.Config();
const dbPassword = config.requireSecret("db_password");
Para aplicar políticas de governança com CrossGuard, crie um arquivo PulumiPolicy.yaml:
pulumi policy new aws-typescript
Exemplo de política que impede buckets S3 públicos:
import { PolicyPack } from "@pulumi/policy";
import { AwsResourceValidationPolicy } from "@pulumi/aws-policy";
const policies = new PolicyPack("meu-pacote", {
policies: [
{
name: "s3-no-public-read",
description: "Proíbe buckets S3 com acesso público de leitura",
enforcementLevel: "mandatory",
validateResource: (args, reportViolation) => {
if (args.type === "aws:s3/bucket:Bucket") {
const acl = args.props.acl;
if (acl === "public-read" || acl === "public-read-write") {
reportViolation("Buckets S3 não podem ter ACL pública.");
}
}
},
},
],
});
6. Integração contínua e pipelines com Pulumi
Exemplo de pipeline com GitHub Actions:
name: Deploy Infrastructure
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- run: npm install
- uses: pulumi/actions@v4
with:
command: up
stack: dev
env:
PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
Comandos essenciais para automação:
# Deploy sem confirmação
pulumi up --yes
# Preview com diff detalhado
pulumi preview --diff
# Rollback para versão anterior
pulumi stack select dev
pulumi stack revert <stack-tag>
Estratégias de implantação podem ser implementadas usando tags de stack e múltiplos stacks para blue/green:
pulumi stack select blue
pulumi up
# Validar
pulumi stack select green
pulumi up
# Trocar DNS
7. Boas práticas, debugging e próximos passos
Estrutura de projeto modular:
projeto/
├── infra/
│ ├── networking/
│ │ └── index.ts
│ ├── compute/
│ │ └── index.ts
│ └── database/
│ └── index.ts
├── config/
│ └── index.ts
├── Pulumi.yaml
└── package.json
Debugging:
# Visualizar logs de recursos
pulumi logs --resource minha-instancia
# Visualizar grafo de dependências
pulumi stack graph | dot -Tpng > grafo.png
# Logs detalhados
pulumi up --logtostderr --verbose=9
Próximos passos:
- Explore o Pulumi Registry para encontrar componentes prontos
- Estude a Automation API para criar ferramentas personalizadas
- Migre projetos Terraform existentes usando pulumi convert
- Aprofunde-se em testes com pulumi-aws e @pulumi/policy
Referências
- Documentação Oficial do Pulumi — Guia completo de instalação, conceitos e exemplos práticos para todas as linguagens suportadas.
- Pulumi Registry — Catálogo de provedores oficiais e comunitários com documentação detalhada de cada recurso.
- Tutorial: Getting Started with Pulumi and AWS — Passo a passo para criar seu primeiro projeto AWS com TypeScript.
- CrossGuard: Policy as Code — Documentação sobre políticas de governança para segurança e compliance.
- Pulumi Automation API — Guia para integrar o Pulumi em aplicações e pipelines personalizados.
- Migrating from Terraform to Pulumi — Estratégias e ferramentas para converter projetos Terraform existentes.
- Pulumi GitHub Actions — Action oficial para integrar o Pulumi em workflows de CI/CD.