Pulumi: infrastructure as code in TypeScript, Python, Go and C#
Pulumi - Infrastructure as Code in any programming language 🚀
At a glance
- What is it?
- Pulumi replaces YAML templates with general-purpose programming languages and keeps a state file of what it created. It suits teams that already write TypeScript or Python and want loops, classes and package managers in their infrastructure code.
- Who is it for?
- Adopt Pulumi if your team writes TypeScript, Python, Go or C# daily and wants the AWS, Azure, GCP or Kubernetes resources expressed with loops, functions and package managers instead of YAML. Do not adopt it if you need a single static binary with no language runtime, or if you cannot store or protect a state file.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Pulumi replaces, and for whom
Most infrastructure-as-code tools ask you to describe resources in a configuration language. Pulumi asks you to describe them in a programming language. The README states that you "Skip the YAML, and use standard language features like loops, functions, classes, and package management that you already know and love." That is the whole proposition, and it defines the audience: developers who already write TypeScript, JavaScript, Python, Go, C# or F# and who find template languages limiting when a resource graph needs conditionals or generated names.
The repository layout confirms the scope. This repo holds the pulumi CLI, the language SDKs (sdk/nodejs, sdk/python, sdk/go, and the PCL intermediate language) and the core engine, while individual provider libraries live in their own repositories. The README points to more than 300 providers in the Pulumi Registry and to pulumi/examples for containers, serverless and general infrastructure samples. The declared targets are AWS, Azure, Google Cloud Platform and Kubernetes.
The practical difference shows up in the first example in the README: three EC2 instances are created inside a for loop over [0, 1, 2], each named web-${i}, sharing one security group. In a template language that pattern usually means copy-paste or a meta-argument. Here it is a loop. The trade-off is that nothing stops a developer from writing a fifteen-line helper function that computes resource arguments, which is harder to review than a flat document.
How the engine, SDKs and providers fit together
A Pulumi program is ordinary code that imports provider packages and constructs resource objects. The README's TypeScript example imports @pulumi/aws and calls new aws.ec2.Instance(...). The program is not interpreted by a hand-written evaluator: it runs on the language runtime, and the SDK registers each resource with the Pulumi engine over a gRPC connection. The engine, written in Go, then talks to the provider plugins that actually call the cloud APIs.
The Makefile in this repository makes the language split concrete. SDKS is set to nodejs python go pcl, and each entry becomes a sub-project under sdk/. The CLI itself is built from github.com/pulumi/pulumi/pkg/v3/cmd/pulumi. There is a separate language host binary per SDK, for example sdk/go/pulumi-language-go and sdk/python/cmd/pulumi-language-python, and the Makefile lists a language conformance test package, pulumi-test-language, that checks language implementations against a shared specification.
State is the other half. Pulumi records what it created so that the next run can diff desired against actual, and the README's getting-started flow implies a backend that stores it. The README documents Pulumi ESC for secrets and configuration, but it does not document rollback, so do not assume an undo command exists; verify what your backend offers before you rely on it. The engine also has an Automation API, which the README describes as a way to "embed IaC anywhere", meaning the same engine can be driven from inside an application rather than from the CLI.
Installing the Pulumi CLI and deploying a first stack
The README gives a single install command for the latest release and links to fuller installation instructions for other platforms, including Windows and macOS. Run the install script, then confirm the binary is on your PATH.
curl -fsSL https://get.pulumi.com/ | shAfter installation, create a directory and generate a project from a template. The README uses the serverless-aws-typescript template, which produces an AWS Lambda project in TypeScript. Running pulumi new with no argument instead prompts you with the available templates for all languages and clouds.
mkdir pulumi-demo && cd pulumi-demo
pulumi new serverless-aws-typescriptThe generated project is where you write resource definitions. The README's own example shows the shape of a program: import the provider package, declare resources, and let the engine handle creation. A minimal serverless timer from the README creates a DynamoDB table and a scheduled Lambda that fetches a page and writes it to that table.
import * as aws from "@pulumi/aws";
const snapshots = new aws.dynamodb.Table("snapshots", {
attributes: [{ name: "id", type: "S" }],
hashKey: "id",
billingMode: "PAY_PER_REQUEST",
});The deploy step is pulumi up, which previews the changes and then applies them after confirmation. The README's getting-started section is truncated at the deploy step, so the exact prompt text is not quoted here. What you should see after a successful run is a summary of created resources and a stack whose state your backend now holds. The README notes that the CLI can also be driven through the Automation API when you want to run deployments from application code.
Where Pulumi is the wrong tool
The first limitation is the runtime. A Pulumi program executes in Node.js, Python, Go or .NET, so a deployment machine needs that runtime plus the provider plugins. A team that standardises on one static binary and no language toolchain has a smaller surface with a template-based tool. The README does not claim otherwise; it leans into the dependency by treating your existing package manager as a feature.
The second is state. Pulumi needs somewhere to record the resources it manages. The README documents Pulumi ESC for secrets and configuration, but it does not describe how to operate without a state backend, and it does not document rollback. If your organisation cannot store state safely, or cannot accept that a corrupted state file blocks the next apply, this is a poor fit. There is a search question about using Pulumi without Pulumi Cloud; the README does not answer it, so treat the choice of backend as something to confirm in the documentation rather than assume.
The third is drift between the program and reality. Because resources are created by imperative-looking code, a reviewer reading a diff sees the program change, not the cloud change. That is a real cost when the person reviewing is not the person who wrote the helper functions. Finally, the repository is large and polyglot: the Makefile lints seven separate Go module directories, and the project ships SDKs for four languages. Contributing a fix to the engine means building and testing against that matrix, not a single module.
Pulumi compared with Terraform's approach
The comparison people search for is real, and the difference is architectural rather than cosmetic. Terraform and its descendants evaluate HCL, a purpose-built configuration language, with expressions, functions and modules. Pulumi evaluates a general-purpose program through a language host. In HCL, a loop is a for expression inside a resource block. In Pulumi, it is the language's own loop, as the README's three-instance example shows.
That has consequences in both directions. General-purpose languages bring real package management, real test frameworks and real type checkers, which is why the README can point at standard tooling. They also bring the ability to hide resource definitions behind abstractions that a configuration-language reviewer would see plainly. HCL's constraint is its advantage here: a flat document is easier to audit than a function that returns a resource map.
Both tools keep state and both diff desired against actual. Pulumi's state is managed through a backend, and the README's getting-started flow assumes one. The engine is open source under Apache-2.0, and the CLI is distributed as a binary through an install script, with SDKs published to npm, PyPI and NuGet as the README's badges show. If your team already has HCL modules in production, the migration cost is not the language syntax alone; it is re-expressing every module and re-importing every resource into a new state file.
Licence, release cadence and upgrade cost
The repository is licensed Apache-2.0, and the README states the project is "open source under the Apache 2.0 license". That covers the CLI, the engine and the SDKs in this repository. It does not automatically cover the Pulumi Cloud service or ESC, which the README describes as a product. If your compliance review depends on running everything yourself, separate the open source components from the hosted ones before you decide. Nothing here is legal advice; read the licence file and the service terms.
The release cadence is visible in the version history: v3.261.0 on 2026-09-02, v3.262.0 on 2026-09-10, and v3.263.0 on 2026-09-16. The repository's last push was on 2026-09-19, so this is a project with frequent releases and current activity. That cadence is a cost as well as a signal. A CLI that ships a minor version every week or two means your pinned version ages quickly, and provider plugins are versioned separately, so an upgrade plan has to cover the CLI, the language SDK and each provider package you import.
The build system reflects that complexity. The top-level Makefile defines PROJECT_NAME as Pulumi SDK, sets SDKS to nodejs python go pcl, and declares LINT_GOLANG_PKGS across sdk, pkg, tests and the language host directories. VERSION is derived from scripts/pulumi-version.sh unless PULUMI_VERSION is set. Building from source therefore means installing Go, the language toolchains you intend to test, and running the conformance suite, which is a heavier commitment than consuming the released binary.
Editorial conclusion
Adopt Pulumi if your team writes TypeScript, Python, Go or C# daily and wants the AWS, Azure, GCP or Kubernetes resources expressed with loops, functions and package managers instead of YAML. Do not adopt it if you need a single static binary with no language runtime, or if you cannot store or protect a state file. Before committing, verify on one non-production stack that pulumi up reports the resources you expect, inspect the generated state, and confirm whether your chosen backend is the Pulumi Cloud service or a self-managed store.
Frequently asked questions
What is Pulumi used for?
It provisions and manages cloud resources on AWS, Azure, Google Cloud Platform and Kubernetes using code written in TypeScript, JavaScript, Python, Go, C# or F#. The README describes it as an infrastructure-as-code approach that skips YAML and uses standard language features such as loops, functions and classes.
How do I install the Pulumi CLI?
The README gives one command for the latest release: curl -fsSL https://get.pulumi.com/ | sh. It also links to fuller installation instructions for additional installation options, including Windows and macOS.
How does Pulumi work?
You write a program in a supported language that imports provider packages and constructs resource objects. The language host runs that program and registers resources with the Go engine, which calls provider plugins to create them in the cloud, and state is kept so the next run can diff desired against actual.
Is Pulumi better than Terraform?
They differ in approach rather than in a single ranking. Terraform evaluates HCL, a purpose-built configuration language, while Pulumi evaluates a general-purpose program through a language host, so loops and abstractions come from the language itself. The README does not make a comparison claim.
Can I use Pulumi without Pulumi Cloud?
The README does not document running without a backend; it documents Pulumi ESC for secrets and configuration and a getting-started flow that assumes state is stored somewhere. Confirm the supported backends in the installation and state documentation before committing to a setup.
What is Pulumi ESC?
The README lists it under Secrets Management and describes it as a way to manage secrets sprawl and configuration complexity across cloud infrastructure and applications. It is presented as a product rather than as part of the CLI, engine and SDKs in this repository.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/pulumi-pulumi)