Pulumi
Pulumi is an infrastructure as code tool that lets you define cloud resources in general-purpose programming languages — TypeScript, JavaScript, Python, Go, C#, Java, or YAML — instead of a domain-specific language. You get loops, functions, classes, types, package managers, IDE autocomplete, and unit tests, while Pulumi's engine computes a plan, shows a preview, and creates, updates, or deletes resources to match your program.
Pulumi supports AWS, Azure, Google Cloud, Kubernetes, and hundreds of other providers, including many bridged from the Terraform provider ecosystem. It's a strong fit for teams that want infrastructure written by the same engineers, in the same language, with the same testing habits as application code.
TL;DR
- A program in a real language declares resources; the engine diffs desired vs actual state.
- Projects contain code; stacks are instances (dev, staging, prod) with their own config and state.
- Resource properties are Outputs — values known after deployment; combine them with
applyorinterpolate. - Package reusable patterns as component resources.
- Store secrets with encrypted config; state lives in Pulumi Cloud or a self-managed backend (S3, Azure Blob, GCS).
pulumi previewshows changes;pulumi upapplies them; add policy as code and tests in CI.
Quick Example
A TypeScript program that creates a private S3 bucket and a Lambda function with least-privilege access, configured per stack:
Core Concepts
Projects, Stacks, and State
A project is a directory with Pulumi.yaml and your program. A stack is an isolated deployment of that project, with its own Pulumi.<stack>.yaml config and state. State records what Pulumi manages; it can live in Pulumi Cloud (with history, locking, and RBAC) or a self-managed backend like S3 or Azure Blob Storage.
Resources, Inputs, and Outputs
Declaring new aws.s3.BucketV2(...) registers a desired resource. Many properties — IDs, ARNs, endpoints — aren't known until deployment, so they're Outputs. Pass Outputs directly to other resources (Pulumi tracks the dependency), or transform them with .apply(), pulumi.interpolate, or pulumi.all(). Don't try to read their values synchronously.
Component Resources
A ComponentResource groups child resources into a reusable abstraction with its own inputs and outputs — for example, a SecureBucket or ServiceWithDatabase class. Components can be shared as packages in your language's package manager or as multi-language components.
Config and Secrets
Stack configuration holds per-environment values. Values set with --secret are encrypted (with Pulumi Cloud, a passphrase, or a cloud KMS key) and stay encrypted in state. Pulumi ESC centralizes environments, secrets, and dynamic cloud credentials across stacks and tools.
Policy, Testing, and Automation
- CrossGuard policy as code — rules like "no public buckets" or "all resources tagged," enforced during preview.
- Unit tests with mocks run in your normal test framework; integration tests deploy ephemeral stacks.
- Automation API embeds the Pulumi engine in your own programs, useful for internal platforms and self-service provisioning.
Providers and Imports
Native providers (like azure-native and google-native) track cloud APIs closely; bridged providers reuse Terraform providers. pulumi import brings existing resources under management, and pulumi convert translates Terraform HCL into a Pulumi program.
Best Practices
Keep Programs Declarative
Use language features for composition and loops, but avoid side effects like calling cloud APIs directly or reading mutable external state during a deployment.
Split Stacks by Lifecycle
Separate networking, data, and application stacks, and connect them with stack references so a routine app deploy can't touch the VPC.
Protect Critical Resources
Set protect: true on databases and buckets, and use retainOnDelete where losing data would be catastrophic.
Review Previews in Pull Requests
Run pulumi preview in CI and post the diff on the pull request, like terraform plan.
Encrypt Secrets and Use Short-Lived Credentials
Mark sensitive config as secret and use OIDC or ESC for cloud credentials rather than static keys.
Pin Provider Versions
Lock package versions so provider updates don't change behavior unexpectedly between runs.
Common Mistakes
Treating Outputs Like Plain Values
Using an Output in string concatenation produces [object Object] or a warning. Use pulumi.interpolate or .apply().
Creating Resources Inside apply
Resources declared inside callbacks don't appear in previews and make plans unpredictable.
Renaming Resources Without Aliases
Changing a resource's logical name makes Pulumi delete and recreate it. Use aliases to preserve identity during refactors.
Mixing Manual Console Changes
Out-of-band changes cause drift. Run pulumi refresh to detect them and reconcile in code.
Too-Clever Abstractions
Deep inheritance hierarchies and dynamic resource generation make infrastructure hard to review. Keep components simple and explicit.
Comparison
FAQ
What is Pulumi used for?
Provisioning and managing cloud infrastructure — networks, databases, Kubernetes resources, serverless functions — using programs written in general-purpose languages.
How is Pulumi different from Terraform?
Pulumi uses general-purpose languages with their tooling and testing, while Terraform uses HCL. Both use a plan-then-apply model and a state file, and both support many providers.
Where does Pulumi store state?
By default in Pulumi Cloud, which handles locking and history. You can instead use a self-managed backend such as S3, Azure Blob Storage, Google Cloud Storage, or the local filesystem.
Is Pulumi free?
The Pulumi CLI and SDKs are open source. Pulumi Cloud has a free individual tier and paid team and enterprise tiers; self-managed backends are free to use.
Can I migrate from Terraform to Pulumi?
Yes. pulumi convert translates HCL to a Pulumi program, and pulumi import or state import tools bring existing resources under Pulumi management without recreating them.
Related Topics
- Infrastructure as Code — Principles and practices
- Terraform — The most widely used alternative
- CloudFormation — AWS-native IaC and the CDK
- Cloud Computing — The platforms Pulumi manages
- Secrets Management — Handling credentials safely