PU

Pulumi

Infrastructure as code using general-purpose languages

Developer Tools & Git ★ 25.7k stars Medium setup Apache-2.0

Pulumi is an open-source infrastructure-as-code platform that lets engineers define cloud resources in TypeScript, Python, Go, and other languages. The CLI and engine are self-hostable for private workflows.

Key features

  • Real programming languages
  • Multi-cloud support
  • Self-managed state backend
  • Reusable components

Pros & cons

Strengths

  • Real programming languages
  • Multi-cloud support
  • Typed code catches errors

Trade-offs

  • Defaults to hosted state
  • Smaller ecosystem than Terraform

Pulumi replaces

Last reviewed Aug 26, 2026 · 888 words

Run pulumi login --local before you run anything else. The Pulumi CLI is Apache-2.0 and entirely yours, but the first pulumi up on a fresh install will send your stack state to Pulumi Cloud, and state is the crown jewels of infrastructure as code: every resource ID, every output, and unless you configure otherwise, every secret. Self-hosting Pulumi means self-hosting that file. Everything else about the tool is a matter of taste.

What is actually self-hostable, and what is not

Pulumi is three things. The CLI and deployment engine (Go, 25,604 stars, first released 2018) run on your laptop or a CI runner and want about 512 MB of RAM plus whatever the language runtime adds. The providers are per-cloud plugins fetched on demand. The third piece, Pulumi Cloud, is the hosted service for state, secrets and team features, and its self-hosted edition is an enterprise product, not something you docker-compose on a Sunday. So "self-hosted Pulumi" in practice means open-source CLI, your own state backend, your own secrets provider. You give up the web console, the audit history and the drift dashboard. You keep everything that touches your infrastructure.

Three backends keep state on your hardware

The file backend is the simplest. pulumi login --local writes state under ~/.pulumi, and pulumi login file:///srv/pulumi-state puts it wherever you like. One person, one machine: fine. Two people, or one person plus a CI job, and you want object storage. Pulumi speaks S3, Azure Blob and GCS natively, and S3 includes anything S3-compatible, so a MinIO bucket on your own box works:

export AWS_ACCESS_KEY_ID=pulumi
export AWS_SECRET_ACCESS_KEY=change-me
pulumi login 's3://pulumi-state?endpoint=minio.lan:9000&disableSSL=true&s3ForcePathStyle=true'

Whichever you pick, a stack on a self-managed backend needs a secrets provider, and the default is a passphrase. Set PULUMI_CONFIG_PASSPHRASE (or PULUMI_CONFIG_PASSPHRASE_FILE) and every pulumi config set --secret value is encrypted with it before it lands in the state file. Lose the passphrase and the stack is unreadable, so store it separately from the bucket. Turn on bucket versioning too: a corrupted state file is a 2-minute fix if yesterday's copy exists and a rebuild-from-scratch if it does not.

Where it earns its keep in a homelab

Pulumi has no opinion about running services; it provisions the things services run on. The jobs I have seen it do well at home: a Proxmox host where VMs and LXCs are declared in TypeScript instead of clicked into existence, Cloudflare DNS and tunnel records that drift the moment 2 people manage them by hand, a cheap off-site VM for backups, and the Docker provider for the 5 containers you want typed and reviewed rather than pasted. The Proxmox provider, like most niche ones, is a bridge over the Terraform provider, and that bridge is the quiet answer to the ecosystem gap: if a Terraform provider exists, a Pulumi one can usually be generated from it. Put the program in Gitea so pulumi preview output lands in a pull request, and run pulumi up from a CI runner so nobody deploys from a laptop with uncommitted changes.

Real languages cut both ways

The pitch is that TypeScript or Python catches errors HCL cannot, and it is true: a typo in a resource property fails before anything is created, a loop is a loop, and shared components are ordinary packages. The cost is that a Pulumi program is a program. Someone will npm install a helper, someone will put logic in a constructor that runs on every preview, and in a year the infrastructure repo has a lockfile, a test suite and a dependency audit. For a solo homelab that is fine and honestly pleasant. For a team that includes people who do not write code, OpenTofu's flatter HCL is easier to review.

The honest OpenTofu comparison

Terraform moved to the BSL licence in 2023 and OpenTofu forked under MPL; Pulumi stayed Apache-2.0 throughout. On ecosystem, the Terraform registry is still far larger, and although the bridge closes most of the gap, community-bridged providers lag upstream releases by weeks. On state, all three default to a hosted product and all three point at your own bucket in one command. On day-to-day feel, Pulumi previews are the best of the three, because the engine shows what a real program will do rather than what a template expands to. I would not migrate a working Terraform estate for its own sake. I would start new projects in Pulumi whenever the maintainers already write TypeScript, Python or Go.

What I'd do

pulumi login to a versioned MinIO bucket, passphrase in a password manager and nowhere near the repo, one stack per environment, pulumi preview in CI on every pull request and pulumi up only from CI on main. Write the program in the language the maintainers already think in, keep it boring, and give the state bucket the same 3-2-1 backup discipline as everything else. Run that way, Pulumi is the most pleasant infrastructure-as-code tool I have used, and the only one where the free tier is the whole product.

Compare Pulumi

1 head-to-head comparisons.

Similar developer tools & git apps