Operations¶
Scope
Production deployment patterns, operational procedures, performance tuning, and troubleshooting for Pulumi.
Deployment¶
Installation & Setup¶
# Install
brew install pulumi
# Login to backend
pulumi login # Pulumi Cloud
pulumi login --local # Local state
pulumi login s3://my-state # S3 backend
# New project
pulumi new typescript
Stack Management¶
# Create and select stacks
pulumi stack init staging
pulumi stack init production
pulumi stack select production
# Preview changes
pulumi preview
# Deploy
pulumi up --yes
# Destroy
pulumi destroy --yes
State Operations¶
# Export/import state
pulumi stack export > state.json
pulumi stack import < state.json
# Refresh state from cloud
pulumi refresh
# Import existing resource
pulumi import aws:s3:Bucket my-bucket my-bucket-name
Secrets Management¶
# Set encrypted secret
pulumi config set --secret dbPassword "s3cr3t"
# Change encryption provider
pulumi stack change-secrets-provider "awskms://alias/pulumi"
Common Issues¶
| Issue | Diagnosis | Fix |
|---|---|---|
| State conflict | Multiple deployers | Use Pulumi Cloud or state locking |
| Import drift | pulumi refresh |
Refresh then pulumi up |
| Plugin version mismatch | pulumi plugin ls |
pulumi plugin install resource aws v6.0.0 |
| Stack locked | Concurrent operation | pulumi cancel |
Commands & Recipes¶
Getting Started¶
# Install Pulumi
curl -fsSL https://get.pulumi.com | sh
# Create new project (TypeScript)
mkdir myinfra && cd myinfra
pulumi new aws-typescript
# Create new project (Python)
pulumi new aws-python
Core Workflow¶
# Preview changes
pulumi preview
# Deploy
pulumi up
# Destroy
pulumi destroy
# View stack outputs
pulumi stack output
# View stack resources
pulumi stack --show-urns
TypeScript Example (AWS)¶
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
// VPC
const vpc = new aws.ec2.Vpc("main-vpc", {
cidrBlock: "10.0.0.0/16",
enableDnsHostnames: true,
tags: { Name: "production" },
});
// S3 Bucket with encryption
const bucket = new aws.s3.Bucket("data-bucket", {
acl: "private",
serverSideEncryptionConfiguration: {
rule: {
applyServerSideEncryptionByDefault: {
sseAlgorithm: "AES256",
},
},
},
});
// Export outputs
export const vpcId = vpc.id;
export const bucketName = bucket.bucket;
Python Example (K8s)¶
import pulumi
import pulumi_kubernetes as k8s
app_labels = {"app": "nginx"}
deployment = k8s.apps.v1.Deployment("nginx",
spec=k8s.apps.v1.DeploymentSpecArgs(
replicas=3,
selector=k8s.meta.v1.LabelSelectorArgs(match_labels=app_labels),
template=k8s.core.v1.PodTemplateSpecArgs(
metadata=k8s.meta.v1.ObjectMetaArgs(labels=app_labels),
spec=k8s.core.v1.PodSpecArgs(
containers=[k8s.core.v1.ContainerArgs(
name="nginx",
image="nginx:1.27",
ports=[k8s.core.v1.ContainerPortArgs(container_port=80)],
)],
),
),
))
pulumi.export("deployment_name", deployment.metadata.name)
Unit Testing (TypeScript)¶
import * as pulumi from "@pulumi/pulumi";
import { expect } from "chai";
pulumi.runtime.setMocks({
newResource: (args) => ({ id: args.name + "_id", state: args.inputs }),
call: (args) => args.inputs,
});
describe("Infrastructure", () => {
it("should create a VPC with correct CIDR", async () => {
const infra = await import("../index");
const cidr = await new Promise((resolve) =>
infra.vpc.cidrBlock.apply(resolve)
);
expect(cidr).to.equal("10.0.0.0/16");
});
});
Stacks & Config¶
# Create environments as stacks
pulumi stack init dev
pulumi stack init staging
pulumi stack init production
# Set stack-specific config
pulumi config set aws:region us-east-1
pulumi config set --secret dbPassword "s3cret"