What is Pulumi?
Why Pulumi Matters
The Problem: Traditional IaC tools use custom DSLs (domain-specific languages) that limit expressiveness and force you to learn entirely new syntax.
The Solution: Pulumi lets you define cloud infrastructure using real programming languages like TypeScript, Python, Go, and C#, giving you full access to loops, conditionals, functions, and packages.
Real Impact: Teams using Pulumi report up to 10x fewer lines of infrastructure code and can leverage existing software engineering practices like testing, code review, and IDE support.
Real-World Analogy
Think of Pulumi as an architect's blueprint software:
- Your Code = The blueprint you draw using familiar tools
- Pulumi Engine = The construction manager who reads your blueprint
- State = The as-built documentation tracking what exists
- Cloud Provider = The actual construction site where things get built
- Stack = Different versions of the same building (dev, staging, prod)
Core Benefits of Pulumi
Real Languages
Use TypeScript, Python, Go, C#, Java, or YAML. Leverage existing skills, IDEs, and package managers.
Multi-Cloud
Deploy to AWS, Azure, GCP, Kubernetes, and 100+ providers with a single consistent workflow.
Software Engineering
Apply testing, refactoring, code review, and CI/CD to your infrastructure just like application code.
State Management
Automatic state tracking with Pulumi Cloud or self-managed backends like S3, Azure Blob, or local files.
Installation & Setup
Installing the Pulumi CLI
# macOS (Homebrew)
brew install pulumi/tap/pulumi
# Linux (curl)
curl -fsSL https://get.pulumi.com | sh
# Windows (Chocolatey)
choco install pulumi
# Verify installation
pulumi version
$ pulumi version v3.100.0 $ which pulumi /opt/homebrew/bin/pulumi
Setting Up Your Environment
# Login to Pulumi Cloud (free tier available)
pulumi login
# Or use local state backend
pulumi login --local
# Configure AWS credentials (if using AWS)
export AWS_ACCESS_KEY_ID=<your-access-key>
export AWS_SECRET_ACCESS_KEY=<your-secret-key>
export AWS_REGION=us-east-1
# Install Node.js runtime (for TypeScript/JavaScript)
node --version # Ensure v18+ is installed
Your First Program
Let's Build Something!
We'll create an AWS S3 bucket using Pulumi with TypeScript. This demonstrates the core workflow of every Pulumi project.
Step 1: Create a New Project
# Create a new directory
mkdir my-first-pulumi && cd my-first-pulumi
# Create a new Pulumi project from a template
pulumi new aws-typescript
# This will prompt you for:
# project name: my-first-pulumi
# project description: My first Pulumi project
# stack name: dev
# aws:region: us-east-1
Step 2: Write Your Infrastructure Code
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
// Create an S3 bucket
const bucket = new aws.s3.Bucket("my-bucket", {
website: {
indexDocument: "index.html",
},
tags: {
Environment: "dev",
ManagedBy: "pulumi",
},
});
// Export the bucket name and URL
export const bucketName = bucket.id;
export const bucketUrl = bucket.websiteEndpoint;
Project Files Generated
name: my-first-pulumi
runtime: nodejs
description: My first Pulumi project
Pulumi.yaml file defines the project metadata, while your infrastructure code lives in standard source files.
Common Mistake
Wrong: Running pulumi up without first running pulumi preview
Why it fails: You might accidentally create or destroy resources without understanding the full impact. Preview shows exactly what will change.
Instead: Always run pulumi preview first, review the diff, then run pulumi up to apply changes.
Deploying Your Stack
Running Your First Deployment
# Preview changes before deploying
pulumi preview
# Deploy the stack
pulumi up
# View stack outputs
pulumi stack output
# View the deployed resources
pulumi stack
# Destroy all resources when done
pulumi destroy
Understanding the Output
Previewing update (dev):
Type Name Plan
+ pulumi:pulumi:Stack my-first-pulumi-dev create
+ └── aws:s3:Bucket my-bucket create
Resources:
+ 2 to create
Do you want to perform this update? yes
Updating (dev):
Type Name Status
+ pulumi:pulumi:Stack my-first-pulumi-dev created
+ └── aws:s3:Bucket my-bucket created
Outputs:
bucketName: "my-bucket-a1b2c3d"
bucketUrl : "my-bucket-a1b2c3d.s3-website-us-east-1.amazonaws.com"
Resources:
+ 2 created
Duration: 12s
Understanding the Symbols
- + (green) = Resource will be created
- ~ (yellow) = Resource will be updated in place
- +- (orange) = Resource will be replaced (delete + create)
- - (red) = Resource will be deleted
Common Pitfall
Problem: "error: no Pulumi.yaml project file found"
Solution: Ensure you are running Pulumi commands from the directory containing your Pulumi.yaml file. This file is the root of every Pulumi project.
Updating (dev):
Type Name Status
+ pulumi:pulumi:Stack my-first-pulumi created
+ aws:s3:Bucket my-bucket created
Outputs:
bucketName: "my-bucket-a1b2c3d"
Resources:
+ 2 created
Duration: 12s
pulumi up shows a preview before applying changes. Resources are tracked in state, so Pulumi knows what exists and what needs to change on subsequent runs.
Deep Dive: Pulumi State Management
Pulumi tracks all deployed resources in a state file. By default, state is stored in Pulumi Cloud (free for individual use). You can also use self-managed backends like S3, Azure Blob, or a local file. The state records each resource's inputs, outputs, and provider metadata. When you run pulumi up, the engine compares desired state (your code) with current state (the state file) to compute the minimal set of changes. Never manually edit state files -- use pulumi state commands for state operations.
Quick Reference
Essential Pulumi CLI Commands
| Command | Description | Example |
|---|---|---|
pulumi new |
Create a new project from a template | pulumi new aws-typescript |
pulumi up |
Deploy infrastructure changes | pulumi up --yes |
pulumi preview |
Preview changes without deploying | pulumi preview |
pulumi destroy |
Tear down all resources | pulumi destroy --yes |
pulumi stack |
Manage stacks | pulumi stack select dev |
pulumi stack output |
View stack outputs | pulumi stack output bucketName |
pulumi config |
Manage configuration | pulumi config set aws:region us-east-1 |
Supported Languages
Language Runtimes
- TypeScript/JavaScript: Most popular choice, excellent type safety with TypeScript
- Python: Great for data teams and those familiar with Python ecosystem
- Go: Strong typing, fast compilation, popular with platform teams
- C#/.NET: Enterprise-friendly, works well in Microsoft-heavy environments
- Java: Enterprise standard, integrates with Maven/Gradle
- YAML: Declarative option for simpler configurations