In the last years, teams have accelerated their dependency on the public cloud. Whether you are scaling an already existing product or building a new product that is native to the cloud, chances are you’ve felt that there has got to be a better way to build cloud infrastructure. There is. Enter Pulumi.
What we’ll cover in this article:
Pulumi is an infrastructure-as-code (IaC) platform for full-stack developers and cloud engineers who want to use a general-purpose programming language, such as TypeScript, Python, Go, and C#, for their cloud resources.
Unlike domain-specific languages used by tools like Terraform, Pulumi integrates directly into application codebases, supporting testing, abstraction, and reuse. It works across major cloud providers such as AWS, Azure, and Google Cloud, offering flexibility for multi-cloud environments.
Pulumi is an ecosystem of components that all work together. At a high level, the components include provider SDKs, CLI, and service backend.
SDKs are installable packages your program consumes using the respective language’s package registry. You probably work with them already. Pulumi supports the following programming and markup languages for writing infrastructure as code:
- TypeScript
- JavaScript
- Python
- Go
- .NET languages (C#, F#, and VB)
- Java
- YAML
This means you can use general-purpose code to create cloud resources such as variables, loops, functions, classes (well, at least in OOP), strong-type support, code reuse, and everything else you can do in those programming languages.
It also gives you the option to maintain a homogeneous codebase if that’s important to your team. For example, a team working on a C# .NET app may be interested in implementing their cloud infrastructure also in C# .NET. Or a team working on a React-based app strong in JS and the Node.js ecosystem may want to use JS for their cloud infrastructure too. Let’s examine each of those components in detail:
Provider SDKs
There are over 75 providers, and new ones are being added regularly. You can also contribute new ones.
All SDKs are available in all supported languages. Extension libraries are typically not supported in every supported language because they are typically authored manually and in a language based on community demand.
For example, the official Pulumi EKS is a popular Pulumi component library supported in JS/TS and Python. But wait! The EKS library is also a great example of how you can author and use multi-language components in the Pulumi ecosystem. More on multi-language components later…
CLI
The Pulumi CLI is one of the ways users can run previews and updates on their infrastructure programs. The CLI supports several powerful commands to mutate the state of your cloud resources.
There is another powerful way to automate the execution of your Pulumi apps.
Service backend
The Pulumi Service backend is the default state storage service for all Pulumi projects. This means that every time you update your cloud resources using Pulumi, the service stores a snapshot of the state of your resources known as the checkpoint. The checkpoint allows you to confidently make changes to your infrastructure.
Example: How to use Pulumi
As mentioned before, several components work together in the Pulumi ecosystem to mutate cloud resources. Let’s examine this with an example:
Say we want to create a Bucket using DigitalOcean Spaces. We’ll use JS as an example for demonstration purposes:
const foobar = new digitalocean.SpacesBucket("foobar", {
region: "nyc3",
});
// Export the bucket name as an output. This is a familiar concept for JS developers.
// A similar construct exists in all of the supported languages so you can export
// outputs regardless of the language you choose.
module.exports = {
bucketName: foobar.name
};
Note that I’ve skipped the part about bootstrapping a new project. Just as with any other new app, Pulumi requires some minimal project setup. This can be done easily with pulumi new
, which lets you pick a template to start from.
To create the Bucket in a DigitalOcean account, we’ll need an account and an access key for Spaces, so that Pulumi can authenticate on our behalf to mutate resources. We’ll assume that a token is created and configured correctly.
Now that we have authentication with DigitalOcean, we can run pulumi preview
from the terminal (or an IDEs integrated terminal.)
The Pulumi CLI “processed” the index.js
file and generated a graph of the resources that needed to be created (or deleted, updated…or do nothing if nothing has changed). The graph is simple in this case. We just want to create a single bucket.
Behind the scenes, the CLI uses this graph to calculate the set of CRUD operations using the DigitalOcean API.
Running pulumi up -y
will auto-approve Pulumi to go ahead and create the bucket.
Using a general-purpose programming language means all language features are implicitly Pulumi’s features. Aside from that, there is a rich feature set to help with an ever-evolving cloud infrastructure landscape.
1. ComponentResources
ComponentResources are resources that encapsulate multiple child resources. In simple terms, think of them as a class that you can create that lets you represent several related resources as a single unit.
For example, you might want to create a component that handles setting up an S3 bucket with replication in a secondary region for disaster recovery scenarios.
You could create a component that accepts the bucket name as input but creates two buckets behind the scenes — one in the primary region and the other in the failover region. Actually, there is already a component for that.
2. StackReferences
As your infrastructure evolves, you may want to create multiple stacks, with certain stacks needing to consume the outputs exported by other “upstream” stacks. This is easy to do with StackReferences.
Here is a quick example:
const docker = require(“@pulumi/docker”);
const other = new pulumi.StackReference("acmecorp/infra/database");
const dbEndpoint = other.getOutput("dbEndpoint");
// Build a container image for an API service that uses the DB endpoint.
const api = new docker.Image(“api”, {
build: {
context: “”,
env: {
“DB_ENDPOINT”: dbEndpoint
}
}
});
3. Dynamic providers
Although limited to specific languages, dynamic providers can serve as a sort of escape hatch for when you need to mimic the CRUD lifecycle of a resource, but there is no official provider for that resource. A great example of dynamic providers would be to answer the question, “how do I configure a newly provisioned VM?”.
4. Automation API
When we discussed the CLI, we mentioned it is one way to run Pulumi apps on users’ machines and in CI/CD pipelines. The Automation API allows users to programmatically invoke CLI operations, unlocking a whole other set of possibilities. Pulumi’s customers have fully exploited this feature to enable advanced deployment scenarios for their organizations.
Alternatives vary based on which aspects of Pulumi you would like to compare.
Other general-purpose programming language tools
AWS CDK is superficially similar to Pulumi. However, it is limited to… well, AWS. It is also fundamentally different in how it works behind the scenes. As a user provisioning resource on AWS, you may not need to worry about the implementation details of the technology for your use case.
AWS CDK vs. Pulumi
CDK | Pulumi |
Supports popular languages | Supports popular languages |
Transpiles to CloudFormation template | Doesn’t transpile to any proprietary format |
Cannot natively provision non-AWS resources | Can use any of the 70+ providers as well author your own for edge-cases using Dynamic Providers or contribute your own |
Can create custom encapsulations using CdkContructs that create other AWS resources or Constructs | Can create custom encapsulations using ComponentResources that can |
Has a registry showcasing community-supported as well as AWS-supported Constructs in the Construct Hub | Has a registry showcasing community-supported as well as Pulumi-supported components and packages in the Pulumi Registry |
Other infrastructure-as-code tools
IaC isn’t restricted to general-purpose programming language-based tools. In fact, one of the most common IaC tools that Pulumi is often compared with is Terraform. HashiCorp’s Terraform existed in the IaC space well before Pulumi was created.
If you look deeper, Pulumi extends (the official word is “bridge”; however) many of Terraform’s providers as well as native providers that are direct implementations from Open API specs. They are conceptually similar in that both tools want you to think about everything in the cloud as a “resource.” The resource model drives the core of your infrastructure state. Every resource has a CRUD lifecycle.
Though similar in concept, they are very different. The fundamental difference is that the developer can choose the language that suits them and their team. Of course, there are other differences.
Terraform vs. Pulumi
Terraform | Pulumi |
Uses proprietary but open-source language HCL which stands for HashiCorp Configuration Language | Supports popular open-source, general-purpose programming languages |
HCL is a type of domain-specific language | None of the supported languages are DSLs |
By definition, DSLs are limited in their language feature set | Out-of-box support for language-level features that are not custom-made by Pulumi |
Has a registry showcasing community-supported as well as Terraform-supported Constructs | Has a registry showcasing community-supported as well as Pulumi-supported components and packages |
No escape-hatch like functionality to create self-managed resources in cases where a provider doesn’t support a feature | Dynamic Provider feature to model the CRUD lifecycle of custom one-off resources |
Check out a detailed comparison of Pulumi vs. Terraform.
OpenTofu vs. Pulumi
OpenTofu is an open-source IaC tool for provisioning and managing cloud and on-prem infrastructure. It originated as a community-driven fork of Terraform following HashiCorp’s licensing changes.
OpenTofu allows users to define infrastructure declaratively using configuration files, ensuring consistent, repeatable deployments. It supports major cloud providers and integrates with CI/CD pipelines for automated infrastructure management.
Because it remains open-source under a permissive license, OpenTofu appeals to organizations seeking transparency, vendor neutrality, and community-driven development.
OpenTofu focuses on simplicity, predictability, and a Terraform-compatible workflow, making it ideal for teams already familiar with Terraform. Pulumi offers more flexibility and integration with software development practices, which may be appealing to developers who prefer using familiar languages and tooling.
Other alternatives
Some of the biggest cloud providers have their own proprietary tools for implementing cloud infrastructure.
- AWS CloudFormation — A JSON/YAML-based authoring experience for provisioning AWS resources. AWS CDK, which lets you author infrastructure for AWS resources, transpires to a CloudFormation template and then deploys the infrastructure using CloudFormation.
- Azure Bicep — Microsoft Azure’s version of a DSL IaC tool, it is meant to replace ARM templates.
- GCP Deployment Manager — A deployment service whose primary configuration language is YAML. In some cases, documentation is scarce, and feature support is very limited.
Let’s examine a few concerns developers have expressed about adopting a fundamentally new way to implement cloud infrastructure with a tool like Pulumi.
Deciding on a language
Picking a language in a new tool can feel like a pretty drastic one-way decision. Fortunately, Pulumi interoperates with the supported languages. Delving into how multi-language components work deserves its own post.
Some may say that being stuck with a general-purpose programming language is still better than having to learn a cloud provider’s DSL (templates or otherwise.) Learning a new language or technology has a cost. That cost is especially high when members of your team may not spend a lot of time with infrastructure on a daily basis.
DSL is easier/quicker
One of the strengths of any DSL is its succinctness. It’s one of the reasons why DSLs are great for all types of configuration management. I think this is a matter of perspective. Developer skills are highly varied, and everyone has their own sweet spot of languages with which they are comfortable. I mean, why would we need anything other than JS? Just kidding.
On a more serious note, many developers are indeed more comfortable using DSL-based technologies such as Terraform for their cloud automation needs. Many others want something familiar and can be supported by any developer with language familiarity.
State storage
One of the nice features of Pulumi is that the Pulumi Service stores the state for your infrastructure, by default. Right from the moment you run pulumi stack init <stackName>
. But if things change and you would like to manage the state on your own, Pulumi does support self-managed backends too.
That means you could export your state and store it on your own inside one of the supported self-managed backends such as AWS S3, Azure Storage or GCS.
New technology/Never heard of it
Pulumi emerged in 2018, and several well-known organizations use it. During my time at Pulumi, I encountered several teams that built complex cloud infrastructure installations spanning several cloud providers. Your use case doesn’t have to be complex to use Pulumi. Many start simple but grow organically and don’t realize the growth was facilitated by Pulumi.
See also: Pulumi Pricing – Editions Overview.
Once you’ve got your Pulumi stack configured, you might be wondering, well, now what? It is pretty typical to wire up a CI/CD pipeline to run the same Pulumi commands you ran on your machine. Pulumi integrates really well with many CI/CD services.
This is where Spacelift excels. Spacelift is the most flexible management platform for IaC. It provides excellent capabilities to automate running your Pulumi stacks, so you don’t have to configure your own CI pipelines — especially if you have several stacks and want to connect them together, and it does not stop there.
With Spacelift, you get:
- Policies to control what kind of resources engineers can create, what parameters they can have, how many approvals you need for a run, what kind of task you execute, what happens when a pull request is open, and where to send your notifications
- Stack dependencies to build multi-infrastructure automation workflows with dependencies, having the ability to build a workflow that, for example, generates your EC2 instances using Terraform and combines it with Ansible to configure them
- Self-service infrastructure via Blueprints, or Spacelift’s Kubernetes operator, enabling your developers to do what matters – developing application code while not sacrificing control
- Creature comforts such as contexts (reusable containers for your environment variables, files, and hooks), and the ability to run arbitrary code
- Drift usually occurs when people manually modify resources outside of Pulumi. Spacelift can detect it automatically and optionally remediate it.
If you are searching for the right product to manage your OpenTofu, Terraform, Pulumi, Ansible, CloudFormation, Kubernetes, and Terragrunt, Spacelift is the answer.

AI-powered environmental monitoring platform Orbica wanted to focus on bringing its geospatial domain expertise to market — not learning new tools. Spacelift was the most cost-effective and flexible option, supporting multiple frameworks, including OpenTofu and Pulumi — not just Terraform. This flexibility mitigated the risk of vendor lock-in and sprawl as Orbica’s tech stack expanded. The integrated Terraform registry also made it easier to manage a catalog of infrastructure modules to construct better abstractions and further improve the DX.
Even if you know the language well, cloud infrastructure is complex. (Want to create a private subnet with a NAT gateway? Wait, what’s a NAT, and why do I need a private subnet? Exactly.)
Pulumi helps reduce some of that complexity by removing the cognitive load associated with familiarizing yourself with a DSL or a template system.
In some cases, packages like the Crosswalk for AWS or the Pulumi Cloud framework actually help address the complexity associated with cloud infrastructure, but they do not eliminate it. You’ll discover that as your cloud infrastructure needs evolve, Pulumi’s capabilities scale well with that.
What are the main advantages of using Pulumi?
Pulumi is well-suited for teams seeking a programmable approach to cloud infrastructure with broad provider support. The general main advantages include:
- Multicloud support: It works across AWS, Azure, GCP, Kubernetes, and others through a unified model.
- Use of real programming languages: It allows conditionals, loops, abstraction, and reuse using familiar language features.
- CI/CD and version control integration: It supports modern DevOps workflows with native integrations.
- Flexible state management: It offers both a managed service and self-hosted options for storing infrastructure state.
Pulumi is an open-source infrastructure as code (IaC) tool for provisioning, managing, and deploying cloud infrastructure using general-purpose programming languages. Instead of writing YAML or JSON (like in Terraform or CloudFormation), you can use actual code logic (e.g., loops, conditionals) to define infrastructure, making it more reusable and maintainable.
Hopefully, this post has given you many reasons to try Pulumi. To get you started, check out the Pulumi and Spacelift documentation.
If you want to test drive Spacelift for free, create a free trial account or book a demo with one of our engineers.
Cost-effective Pulumi Cloud alternative
Spacelift is a highly cost-effective Pulumi Cloud alternative that works with Pulumi, Terraform, and many other IaC frameworks. It supports self-hosted on-prem workers, workflow customization, drift detection, and much more.