Skip to main content

Pulumi — Modern Infrastructure as Code

Provision any cloud infrastructure using TypeScript, Python, Go, C#, or Java. Pulumi brings real programming languages, package managers, and IDE tooling to infrastructure.

✓ TypeScript / Python / Go / C# / Java ✓ 100+ cloud providers ✓ Automation API ✓ Policy as Code

What is Pulumi?

Pulumi is an open-source infrastructure-as-code platform founded in 2017 that fundamentally rethinks how developers define cloud resources. Rather than inventing a new configuration language, Pulumi lets you write infrastructure code using TypeScript, Python, Go, C#, or Java — the same languages you already use for your applications. This means real loops, functions, classes, conditionals, package managers (npm, pip, go mod), unit tests, and all the IDE tooling you depend on daily.

Pulumi supports over 100 cloud providers through a rich provider ecosystem including AWS, Azure, Google Cloud, Kubernetes, Cloudflare, MongoDB Atlas, GitHub, and many SaaS platforms. A single Pulumi program can provision resources across multiple providers, making it uniquely suited for organizations running workloads across clouds or managing cloud infrastructure alongside SaaS configuration.

Key Features

Getting Started: TypeScript Program

Install the Pulumi CLI and create a new project:

curl -fsSL https://get.pulumi.com | sh
pulumi new aws-typescript
npm install

Define an S3 bucket, Lambda function, and API Gateway:

// index.ts
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const config = new pulumi.Config();
const environment = config.require("environment");

// S3 bucket for file storage
const bucket = new aws.s3.Bucket("data-bucket", {
  acl: "private",
  versioning: { enabled: true },
  serverSideEncryptionConfiguration: {
    rule: {
      applyServerSideEncryptionByDefault: {
        sseAlgorithm: "AES256",
      },
    },
  },
  tags: { Environment: environment, ManagedBy: "Pulumi" },
});

// IAM role for Lambda
const lambdaRole = new aws.iam.Role("lambda-role", {
  assumeRolePolicy: aws.iam.assumeRolePolicyForPrincipal({
    Service: "lambda.amazonaws.com",
  }),
});

new aws.iam.RolePolicyAttachment("lambda-basic", {
  role: lambdaRole.name,
  policyArn: aws.iam.ManagedPolicy.AWSLambdaBasicExecutionRole,
});

// Lambda function
const processor = new aws.lambda.Function("processor", {
  runtime: aws.lambda.Runtime.NodeJS20dX,
  handler: "index.handler",
  role: lambdaRole.arn,
  code: new pulumi.asset.AssetArchive({
    "index.js": new pulumi.asset.StringAsset(
      `exports.handler = async (e) => ({ statusCode: 200, body: 'OK' });`
    ),
  }),
  environment: {
    variables: { BUCKET_NAME: bucket.bucket },
  },
});

// Stack outputs — accessible from other stacks via StackReference
export const bucketName = bucket.bucket;
export const bucketArn = bucket.arn;
export const lambdaArn = processor.arn;

Manage stacks and deploy:

pulumi stack init dev                    # create dev stack
pulumi config set environment dev       # set config value
pulumi config set --secret dbPass s3cr3t  # encrypted secret
pulumi preview                          # dry-run, see what changes
pulumi up                               # deploy
pulumi stack output bucketName          # read stack output
pulumi destroy                          # tear down resources

Automation API Example

// deploy-programmatically.ts
import { LocalWorkspace } from "@pulumi/pulumi/automation";

async function provisionTenant(tenantId: string) {
  const stack = await LocalWorkspace.createOrSelectStack({
    stackName: `tenant-${tenantId}`,
    workDir: "./infrastructure",
  });

  await stack.setConfig("tenantId", { value: tenantId });
  await stack.setConfig("dbPassword", { value: "secret", secret: true });

  const result = await stack.up({ onOutput: console.log });
  console.log(`Tenant ${tenantId} provisioned:`, result.outputs);
  return result.outputs;
}

// Call from your SaaS app when a customer signs up
provisionTenant("customer-abc-123");

Pulumi vs Alternatives

Feature Pulumi Terraform AWS CDK Crossplane
Language TS / Python / Go / C# / Java HCL TS / Python / Java / C# / Go YAML (Kubernetes CRDs)
Cloud scope Multi-cloud + SaaS (100+) Multi-cloud (1000+ providers) AWS only Multi-cloud via K8s
State backend Pulumi Cloud / S3 / GCS / local TF Cloud / S3 / local CloudFormation (managed) etcd (Kubernetes)
Automation API Yes (first-class) Limited (CLI wrapping) No K8s API
Policy as code CrossGuard (TS/Python) Sentinel / OPA CDK Aspects OPA / Kyverno
Community size Growing Very large Large (AWS ecosystem) Medium (K8s community)

Use Cases

Pros and Cons

Pros

  • ✓ Real programming languages with full IDE support
  • ✓ Multi-cloud and SaaS providers in one tool
  • ✓ Automation API enables infrastructure-as-a-feature
  • ✓ Unit-testable with standard testing frameworks
  • ✓ Encrypted secrets built into config system
  • ✓ StackReference for modular stack composition

Cons

  • ✗ Smaller community and provider ecosystem than Terraform
  • ✗ Pulumi Cloud required for full team features (paid)
  • ✗ Language flexibility can lead to inconsistent codebases
  • ✗ State file conflicts can be tricky to resolve
  • ✗ Longer cold start for complex programs vs HCL plans
  • ✗ Less mature than Terraform in enterprise tooling

Frequently Asked Questions

What makes Pulumi different from Terraform?▼

Pulumi uses general-purpose programming languages (TypeScript, Python, Go, C#, Java) instead of a domain-specific language like HCL. This gives you real loops, conditionals, functions, classes, package managers, and IDE support out of the box. Pulumi also uses an explicit resource model with async/await, making it easy to express dependencies. Terraform's HCL is simpler to learn and has a larger community and provider ecosystem, but Pulumi is often more productive for complex infrastructure because you write real code.

How does Pulumi manage state?▼

Pulumi stores state in a backend that tracks which cloud resources belong to your stack. By default it uses the Pulumi Cloud (managed service, free tier available) which provides collaboration, secrets encryption, history, and policy enforcement. You can also use self-managed backends: AWS S3, Azure Blob Storage, Google Cloud Storage, or a local filesystem. Each Pulumi stack (dev/staging/prod) gets its own state file. pulumi stack ls lists stacks, pulumi state export exports state for inspection or repair.

What is a Pulumi Stack and how do environments work?▼

A Pulumi Stack is an isolated instance of your program — think of it as an environment. You can have stacks named dev, staging, and prod, each with different config values and potentially different cloud accounts or regions. Config is set with pulumi config set key value and accessed in code with config.require('key'). Secrets are encrypted: pulumi config set --secret dbPassword mySecret. Stacks can export values (stack outputs) that other stacks can read via StackReference, enabling stack composition.

Does Pulumi support multiple cloud providers?▼

Yes. Pulumi has providers for over 100 cloud platforms and services including AWS, Azure, Google Cloud, Kubernetes, Cloudflare, Datadog, MongoDB Atlas, GitHub, and more. You can use multiple providers in the same program — for example, provision an AWS RDS database, configure a Datadog monitor, and create a GitHub Actions secret all in one Pulumi program. This makes Pulumi particularly powerful for multi-cloud or cloud-plus-SaaS infrastructure.

What is the Pulumi Automation API?▼

The Automation API is a programmatic interface to the Pulumi engine that lets you embed infrastructure management inside your own applications and scripts. Instead of running pulumi up from the CLI, you call pulumi.automation.LocalWorkspace.createOrSelectStack() from TypeScript or Python, set config values, and call stack.up(). This enables use cases like infrastructure-as-a-feature (SaaS apps that provision cloud resources per customer), custom deployment UIs, and CI/CD systems that need fine-grained programmatic control.

What is Pulumi CrossGuard (Policy as Code)?▼

CrossGuard is Pulumi's policy-as-code framework. You write policies in TypeScript or Python that run during pulumi preview and pulumi up to enforce organizational standards — for example, blocking S3 buckets without encryption, requiring resource tags, or preventing public security groups. Policies are packaged into Policy Packs and can be applied to individual stacks or enforced organization-wide via Pulumi Cloud. This replaces ad-hoc review checklists with automated, testable guardrails.

Share this tool: X / Twitter LinkedIn
✓ 60,000+ developers use DevPlaybook ★★★★★ 4.8 / 5 on Gumroad ✓ MIT licensed · Instant download ✓ No login required

Related Products

on Gumroad

You Might Also Need

More Free Tools

Enjoying this tool? Get more like it.

Weekly developer tool guides, productivity playbooks & AI tricks. Free. No spam.

DevPlaybook Pro 7 days free

Unlock AI-Powered Dev Tools

  • ⚡ AI Code Review, Doc Generator & SQL Builder
  • ⚡ All premium templates & early access
  • ⚡ Member discounts on Gumroad products
Start Free Trial →

$9/mo after trial · Cancel anytime

Want the full toolkit?

Get DevPlaybook Pro

Every template, guide, boilerplate, and automation script in one bundle. 13 premium products — grab them all at once and save big.

$79
$241 separately Save $162 (67% off)
Get DevPlaybook Pro — $79 →

MIT licensed · Instant download · No subscription

See what's included → Browse all deals →