Choosing a Pulumi State Backend: Service vs. Self-Managed Storage
Learn how to choose between Pulumi's managed service, self-managed cloud storage, and local state backends, including a guide on configuring S3 with DynamoDB locking.
04 May 2026, 19:06 UTC

The State Management Dilemma
Pulumi tracks the current state of your infrastructure in a state file. If this file is lost or corrupted, Pulumi loses the mapping between your code and the actual cloud resources, leading to "orphaned" resources that must be manually deleted or imported. The primary decision is where this state lives: in a managed service, a cloud storage bucket, or on your local disk.
The critical takeaway is that local state is only for experimentation. For any team environment or CI/CD pipeline, you must use a backend that supports concurrent access and state locking to prevent two developers from modifying the same resource simultaneously, which would corrupt the state file.
Backend Comparison Matrix
| Backend | Setup Effort | Collaboration | Locking | Encryption | Best For |
|---|---|---|---|---|---|
| Local File | None | Single User | None | None | Learning/Prototyping |
| Pulumi Service | Low (Sign-in) | High (RBAC/UI) | Automatic | Managed | Shared Dev/Test/Enterprise |
| Self-Managed (S3/GCS/Blob) | Medium (Bucket/IAM) | Medium (Bucket Policy) | Manual Setup | Bucket-level | Strict Compliance/Air-gapped |
Evaluating the Trade-offs
Pulumi Service (Managed)
The Pulumi Service is the default experience. It handles the "plumbing" of state management, providing a web console to visualize changes, history, and Role-Based Access Control (RBAC). The trade-off is a dependency on an external SaaS provider and potential costs as your organization grows.
Self-Managed Cloud Storage
Using a backend like AWS S3, Azure Blob Storage, or Google Cloud Storage (GCS) gives you total control over the data residency. However, you inherit the operational burden of managing the storage lifecycle and, crucially, the locking mechanism. Without a lock provider, concurrent pulumi up commands can overwrite each other's changes.
Local Storage
Local storage saves state to your filesystem. It is fast and requires zero configuration, but it cannot be shared across a team or used in a standard CI/CD pipeline without manually moving files, which is error-prone and insecure.
Implementing a Self-Managed S3 Backend
When moving to a self-managed backend on AWS, you must configure both the storage location and a DynamoDB table to handle state locking. Run these commands from your local terminal with the necessary AWS credentials configured.
Step 1: Login to the Backend
Use the pulumi login command to point your local environment to the S3 bucket. To enable locking, you must specify the DynamoDB lock table.
# Run this on your local machine or CI runner
# Replace placeholders with your actual bucket and table names
pulumi login s3://my-corp-pulumi-state/ --lock-provider=dynamodb --lock-table=PulumiStateLockTable
Step 2: Verification
To verify that your environment is correctly pointed to the self-managed backend, run:
pulumi whoami
Expected Result: The output should display the S3 URL (s3://my-corp-pulumi-state/) rather than a Pulumi Service account.
Step 3: Validating the Lock
To ensure your state is protected from corruption, perform this diagnostic check:
- Open two separate terminal windows.
- In the first window, run
pulumi up. While the update is pending (or during the "preview" phase), switch to the second window. - In the second window, run
pulumi up. - Expected Result: The second command should fail with a locking error, indicating that the DynamoDB table is successfully preventing concurrent updates.
Limitations and Risks
- Encryption: When using self-managed backends, you are responsible for the encryption of the state file. Ensure your S3 bucket has Default Encryption enabled (SSE-S3 or SSE-KMS).
- State Migration: Moving state from the Pulumi Service to a self-managed backend (or vice versa) requires using
pulumi stack exportandpulumi stack import, which can be tedious for many stacks. - Permissions: The IAM role running the Pulumi commands must have
s3:GetObject,s3:PutObject, anddynamodb:PutItem/DeleteItempermissions on the respective resources.
Rollback Procedure
If you need to revert to the Pulumi Service or a different backend, simply re-run the login command:
pulumi login
This will prompt you to sign in to the managed service and will ignore the previously set S3 configuration for subsequent commands.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.