Pulumi Cheat Sheet
Covers Pulumi's programming-language-based IaC model, project structure, stacks, resource definitions, and core CLI commands.
Pulumi CLI Basics
Initialize, preview, and deploy a Pulumi project.
pulumi new aws-typescript # scaffold a new projectpulumi stack init dev # create a new stack (environment)pulumi preview # show planned changespulumi up # deploy changespulumi stack output # view exported outputspulumi destroy # tear down all resourcespulumi config set aws:region us-east-1
Define an S3 Bucket (TypeScript)
Provisioning an AWS resource with Pulumi's TypeScript SDK.
import * as pulumi from "@pulumi/pulumi";import * as aws from "@pulumi/aws";const bucket = new aws.s3.Bucket("my-bucket", { acl: "private", versioning: { enabled: true },});export const bucketName = bucket.id;
Key Concepts
Pulumi-specific terminology.
- Stack- An isolated instance of a Pulumi program, e.g. dev, staging, prod
- State Backend- Where stack state is stored: Pulumi Cloud (default), S3, Azure Blob, or self-managed
- Component Resource- A reusable abstraction that groups multiple resources into one logical unit
- Config- Per-stack key/value settings accessed via pulumi.Config() in code
- Secrets- Config values encrypted at rest, set with --secret flag
- Output<T>- A wrapped async value representing a resource property not known until deploy time
Config and Secrets
Setting and reading stack configuration values.
pulumi config set dbUser adminpulumi config set --secret dbPassword S3cr3t!pulumi config get dbUser
Define Resources (Python)
The same S3 + compute pattern expressed in Pulumi's Python SDK, showing typed resource args.
import pulumiimport pulumi_aws as awsbucket = aws.s3.Bucket("my-bucket", acl="private", versioning=aws.s3.BucketVersioningArgs(enabled=True))role = aws.iam.Role("lambda-role", assume_role_policy="""{ "Version": "2012-10-17", "Statement": [{"Action": "sts:AssumeRole", "Effect": "Allow", "Principal": {"Service": "lambda.amazonaws.com"}}] }""")fn = aws.lambda_.Function("my-fn", runtime="python3.12", handler="index.handler", role=role.arn, code=pulumi.FileArchive("./lambda"))pulumi.export("bucket_name", bucket.id)
Custom ComponentResource
Bundle several primitive resources into a reusable abstraction with its own outputs, similar to a Terraform module.
import * as pulumi from "@pulumi/pulumi";import * as aws from "@pulumi/aws";export class StaticWebsite extends pulumi.ComponentResource { public readonly bucketName: pulumi.Output<string>; constructor(name: string, args: { indexDocument: string }, opts?: pulumi.ComponentResourceOptions) { super("custom:web:StaticWebsite", name, {}, opts); const bucket = new aws.s3.Bucket(`${name}-bucket`, { website: { indexDocument: args.indexDocument }, }, { parent: this }); this.bucketName = bucket.id; this.registerOutputs({ bucketName: this.bucketName }); }}
Cross-Stack References
Read outputs from one deployed stack (e.g. networking) into another (e.g. app) without duplicating resources.
import * as pulumi from "@pulumi/pulumi";import * as aws from "@pulumi/aws";const networkStack = new pulumi.StackReference("my-org/network/prod");const vpcId = networkStack.getOutput("vpcId");const subnetId = networkStack.requireOutput("privateSubnetId");const instance = new aws.ec2.Instance("app", { ami: "ami-0abcdef1234567890", instanceType: "t3.micro", subnetId: subnetId,});
Import an Existing Resource
Bring a manually created resource under Pulumi management without recreating it, generating boilerplate code to paste in.
pulumi import aws:s3/bucket:Bucket my-bucket existing-bucket-name# Pulumi prints a matching resource declaration, e.g.:# const myBucket = new aws.s3.Bucket("my-bucket", {# bucket: "existing-bucket-name",# acl: "private",# }, { import: "existing-bucket-name" });## Paste it into your program, remove `import:` once `pulumi up` shows no diff.
Advanced Pulumi Concepts
Mechanisms for programmatic, org-scale, and non-standard IaC use cases.
- Dynamic Provider- Custom CRUD lifecycle logic written in the host language when no native resource provider exists
- Automation API- Embeds Pulumi deployments inside another application or pipeline without shelling out to the CLI
- Policy Pack (CrossGuard)- Org-wide guardrails enforced at preview/up time, written as code rather than a separate DSL
- Aliases- Lets a resource be renamed/moved in code without Pulumi treating it as delete-then-create
- Transformations- Programmatically mutate resource properties (e.g. force a tag) across an entire stack
- Providers & Aliases- Multiple explicit provider instances let one program target several regions/accounts at once
Use Pulumi's Output.apply()/pulumi.all() to combine multiple resource outputs instead of trying to read raw values synchronously — Outputs are only resolved at deploy time, not at program-write time.