Understanding State
Why State & Backends Matter
The Problem: Pulumi needs to know what infrastructure already exists to determine what to create, update, or delete. Without state, every deployment would try to recreate everything.
The Solution: Pulumi maintains a state file that records the mapping between your program's resources and the actual cloud resources, enabling incremental updates.
Real Impact: Proper state management enables team collaboration, prevents conflicts, and ensures infrastructure changes are safe and predictable.
Real-World Analogy
Think of state like an inventory management system:
- State File = The inventory database recording everything in the warehouse
- Backend = Where the inventory database is stored (local, cloud, shared drive)
- Locking = The "checked out" sign preventing two people from editing at once
- Import = Adding existing items to the inventory that weren't tracked before
- Refresh = Walking the warehouse to verify inventory matches reality
What State Tracks
Resource Mapping
Maps logical resource names in your code to physical resource IDs in the cloud (e.g., "my-bucket" to "my-bucket-a1b2c3d").
Input Values
Records the input values used to create each resource, enabling Pulumi to detect what changed between deployments.
Output Values
Stores the output values from each resource, including computed values like ARNs, IPs, and endpoints.
Dependencies
Tracks the dependency graph between resources so operations happen in the correct order.
Pulumi Cloud Backend
# Login to Pulumi Cloud (default)
pulumi login
# Login to a specific Pulumi Cloud organization
pulumi login https://app.pulumi.com
# Check current backend
pulumi whoami -v
# View stack in Pulumi Cloud console
pulumi console
Self-Managed Backends
# Use local filesystem backend
pulumi login --local
# Use AWS S3 backend
pulumi login s3://my-pulumi-state-bucket
# Use Azure Blob Storage backend
pulumi login azblob://my-state-container
# Use Google Cloud Storage backend
pulumi login gs://my-pulumi-state-bucket
# Use S3-compatible storage (MinIO, etc.)
pulumi login "s3://state?endpoint=minio.example.com&disableSSL=true&s3ForcePathStyle=true"
State Management
# Refresh state to match actual cloud resources
pulumi refresh
# View resources in state
pulumi stack --show-urns
# Delete a resource from state (without deleting cloud resource)
pulumi state delete 'urn:pulumi:dev::myproject::aws:s3/bucket:Bucket::my-bucket'
# Rename a resource in state
pulumi state rename 'old-urn' 'new-name'
# Unprotect a protected resource
pulumi state unprotect 'urn:pulumi:dev::myproject::aws:rds/instance:Instance::prod-db'
Import & Export
# Import an existing AWS resource into Pulumi state
pulumi import aws:s3/bucket:Bucket my-bucket my-existing-bucket-name
# Export state to a file
pulumi stack export --file state.json
# Import state from a file
pulumi stack import --file state.json
# Import with code generation
pulumi import aws:ec2/vpc:Vpc main-vpc vpc-0123456789abcdef0 --out index.ts
Common Pitfall
Problem: Two team members running pulumi up simultaneously against the same stack can cause state corruption.
Solution: Pulumi Cloud and self-managed backends with locking (S3 + DynamoDB) prevent concurrent modifications. Always use a backend with locking enabled for team environments.
Quick Reference
State & Backend Commands
| Command | Description | Example |
|---|---|---|
pulumi login | Set the backend | pulumi login s3://my-bucket |
pulumi refresh | Sync state with cloud | pulumi refresh --yes |
pulumi import | Import existing resource | pulumi import aws:s3/bucket:Bucket name id |
pulumi stack export | Export state to file | pulumi stack export --file s.json |
pulumi stack import | Import state from file | pulumi stack import --file s.json |
pulumi state delete | Remove from state only | pulumi state delete 'urn:...' |
pulumi whoami -v | Show current backend | pulumi whoami -v |