Table of Contents
- Overview
- Core Components
- Stack Operations
- Stack Configuration
- Stack Outputs
- Stack References
- Troubleshooting
- Common Stack Commands Summary
- Conclusion
Pulumi Stacks Overview
What Is a Pulumi Stack?
A Pulumi Stack is a fundamental unit of deployment in Pulumi’s infrastructure-as-code platform. Think of a stack as an isolated instance of a Pulumi program—complete with its own configuration, state, secrets, and resource history. Each stack operates independently, so you can have separate stacks for different environments (like development, staging, or production), for separate customers, or for testing out changes without affecting others.
Why Should You Care About Pulumi Stacks?
- Environment Isolation: Stacks let you manage distinct environments using the same codebase, which makes it easier to separate dev/test/prod workflows and prevent configuration overlap or errors.
- Repeatability: Each stack tracks its own resource state, enabling you to reproduce infrastructure consistently across environments or regions.
- Configuration Management: Stacks support configuration and secrets storage, so sensitive data and environment-specific values stay organized and secure.
- Collaboration: Teams can work on different stacks in parallel—testing features, fixing bugs, or rolling out staged releases—without risk of collision or accidental changes to production.
- Automation: Stacks are ideal for CI/CD pipelines, allowing automated provisioning and teardown across projects or branches.
How Do Pulumi Stacks Work?
- Stack Initialization: You create a stack as an environment (for example:
pulumi stack init dev
). Each stack gets its own configuration and state files. - Configuration: Configuration values—plain and secret—are scoped to the stack, enabling custom behavior per environment without code changes.
- State Tracking: Pulumi stores the deployed resource state (either locally, remotely, or in the Pulumi Service). This enables it to determine what needs to change during updates and ensures resource consistency.
- Commands: You control stacks with Pulumi CLI commands (
init
,select
,up
,destroy
). These let you create, update, and remove infrastructure per environment with a few commands. - Outputs and Stack References: Stacks can export key values (like IP addresses, URLs), which can be shared with other stacks or automation tools using stack references—a mechanism for composing infrastructure in a modular fashion.
In summary, Pulumi Stacks provide a powerful, repeatable, and secure approach to managing cloud infrastructure in code—across environments, teams, and projects. They form the backbone for reliable, organized, and scalable cloud deployments.
Core Components
These are the essential building blocks that define and operate a Pulumi Stack effectively:
- Pulumi Program: The infrastructure as code (IaC) logic written using Pulumi-supported languages such as TypeScript, Python, Go, or .NET. Each stack runs a Pulumi program independently, which determines the resources it creates.
- Stack Configuration: Key-value pairs specific to a stack, such as region, resource limits, or credentials. These help customize the behavior of the stack without modifying the code. Sensitive data can be encrypted using the secrets manager.
- Stack State: The saved snapshot of currently deployed resources and their properties. This enables Pulumi to identify and apply only the necessary changes during updates, ensuring efficient and reliable deployments.
- Secrets Provider: Manages encryption of sensitive configuration values such as API keys or passwords. Pulumi supports multiple providers including cloud-native KMS solutions and the Pulumi Service.
- Stack Outputs: Named values exported from the Pulumi program at runtime—such as IP addresses, DNS names, or IDs. These outputs can be referenced by other stacks or consumed by CI/CD pipelines.
- Backend Provider: Determines where stack state is stored—local folder, cloud storage bucket, or the Pulumi Service. This setup dictates collaboration capabilities and backup strategies.
Stack Operations
Stack operations are essential Pulumi CLI commands used to manage the life cycle of a stack — from creation to teardown. These operations help control your deployment environments safely and efficiently.
-
pulumi stack init <name>:
Initializes a new stack with its own state and configuration. This is typically done for new environments like
dev
,stage
, orprod
. - pulumi stack select <name>: Switches between existing stacks in your current project. Useful when working on multiple environments or configurations.
- pulumi up: Applies infrastructure changes defined in your Pulumi program. It provisions, updates, or deletes cloud resources in a safe and trackable way.
-
pulumi preview:
Shows what changes will be made by
pulumi up
without actually performing them. Helps validate the intent before deploying. - pulumi stack output [name]: Retrieves specific output values from the currently selected stack. These can be used in scripts or chained deployments.
- pulumi destroy: Deletes all resources that were provisioned by the stack, but retains the stack itself and its configuration.
- pulumi stack rm <name>: Permanently removes a stack and optionally deletes its state. Use with caution — this action is irreversible.
- pulumi refresh: Re-syncs the Pulumi state file by inspecting the actual infrastructure. This is used to correct drift caused by external changes.
-
pulumi stack export / import:
Allows backup or migration of stack state.
export
creates a JSON snapshot, andimport
can restore it later.
Stack Configuration
Stack Configuration allows each Pulumi stack to behave differently by passing in key-value pairs that parameterize its behavior. These values allow separation between code and environment-specific settings.
-
Plain Text Values:
Regular configuration options used to set parameters like cloud region, instance sizes, or feature toggles. Example:
pulumi config set aws:region us-west-2
-
Secret Values:
Sensitive configuration inputs such as API keys, passwords, or tokens. These values are encrypted and decrypted automatically using a selected secrets provider.
pulumi config set dbPassword MyS3cret123 --secret
-
Configuration Files:
Pulumi stores configuration in YAML files named after the stack (e.g.
Pulumi.dev.yaml
), making it easy to review and version control. -
CLI Commands:
Common configuration management commands include:
pulumi config set <key> <value>
– Add or update a config valuepulumi config get <key>
– Read a config valuepulumi config rm <key>
– Remove a config key--secret
– Designate a value as encrypted
-
Use Case Example:
You can define a different database password or Azure region per stack (e.g. dev, staging, prod) without duplicating your Pulumi code:
pulumi config set database:password --secret
Stack Outputs
Stack outputs are runtime-exported values from a Pulumi stack. They expose important information that can be consumed by other stacks, scripts, or systems after deployment completes.
- What Are Outputs? Outputs are named values that a Pulumi program returns after the infrastructure has been provisioned. Examples include endpoint URLs, IP addresses, security group IDs, and ARNs.
-
Common Use Cases:
- Share a VPC ID from a networking stack to an app stack
- Expose S3 bucket URLs to CI/CD pipelines
- Reference database connection strings in deployment scripts
-
How to Define Outputs:
Add export statements inside your Pulumi code. Example in TypeScript:
Or in Python:export const bucketUrl = myBucket.websiteEndpoint;
pulumi.export("db_endpoint", my_db.endpoint)
-
Fetching Outputs via CLI:
Use the CLI command to retrieve an output value:
pulumi stack output bucketUrl
-
Referencing Outputs from Another Stack:
Use a
StackReference
to retrieve outputs between stacks. Example in Python:from pulumi import StackReference network_stack = StackReference("org/project/network-stack") vpc_id = network_stack.get_output("vpcId")
Stack References
Stack References in Pulumi allow one stack to programmatically access the outputs of another stack. This mechanism is useful to create dependencies between stacks, enabling modular and reusable infrastructure across separate projects or environments.
- What is a Stack Reference? A Stack Reference is a Pulumi construct that lets a stack read exported output values from another stack by specifying the fully qualified stack name (including organization, project, and stack).
- Usage Scenario: When you have multiple related stacks—such as one managing networking and another deploying applications—you can have the application stack reference outputs like VPC IDs or subnet IDs from the networking stack.
-
Creating a Stack Reference:
To create a reference to another stack, instantiate a
StackReference
by passing the full stack name:// TypeScript or JavaScript const network = new pulumi.StackReference("org/project/network-stack");
# Python from pulumi import StackReference network = StackReference("org/project/network-stack")
-
Accessing Outputs:
Use the
getOutput
method to retrieve specific output values:// TypeScript const vpcId = network.getOutput("vpcId");
# Python vpc_id = network.get_output("vpcId")
-
Benefits:
- Enables clean separation of infrastructure into modular stacks
- Supports environment-specific configurations via isolated stack names
- Allows cascading updates between dependent layers (e.g. networking → apps)
-
Best Practices:
- Reference only the outputs you need to reduce tight coupling
- Use stack configuration to dynamically pass in the name of referenced stacks
- Keep stacks small, reusable, and environment-aware
-
Example Usage in Python:
from pulumi import StackReference network_stack = StackReference("org/project/network-stack") vpc_id = network_stack.get_output("vpcId") # Use vpc_id in your Pulumi program for dependent resources
Troubleshooting
Working with multiple stacks and environments sometimes leads to errors or unexpected behavior. Below are common issues and how to troubleshoot them effectively.
-
Stack Already Exists:
This occurs when trying to create a stack that has already been initialized. Use:
to switch to the existing stack instead of creating a new one.pulumi stack select <stack-name>
- Secrets Not Decryptable: If Pulumi can't decrypt secrets (e.g., after moving to a new machine), ensure you're using the correct secrets provider configuration or passphrase. You may need to restore access to the original encryption key or provider.
-
Corrupted or Missing State:
When the state file becomes invalid or deleted, try restoring it from a backup using:
If using the Pulumi Service backend, history may offer a rollback option.pulumi stack import --file state.json
-
Stack Drift:
When someone modifies infrastructure outside of Pulumi, the Pulumi state becomes out of sync. To reconcile the internal state with reality, run:
pulumi refresh
- Locked State File: A failed or interrupted update can leave the stack's state locked. Wait a few minutes or remove the lock through your backend provider if applicable.
-
Unexpected Preview Changes:
If
pulumi preview
shows changes you weren’t expecting, double-check config values, state versions, and inline logic that may differ between environments. -
Invalid Configuration Keys:
Misspelled or missing config values can lead to runtime errors. View all current settings using:
Or inspect the config YAML file for accuracy.pulumi config
Common Stack Commands Summary
This section provides a quick-reference summary of the most commonly used Pulumi stack commands for managing infrastructure deployments.
- pulumi stack init <name>: Initializes a new stack with its own configuration and state file.
- pulumi stack select <name>: Switches the current working context to the specified stack.
- pulumi stack ls: Lists all stacks for the current project, along with their associated backend and default status.
- pulumi up: Creates or updates cloud infrastructure as defined in your Pulumi program.
-
pulumi preview:
Displays a preview of the changes that
pulumi up
would apply—useful for review before execution. - pulumi destroy: Tears down all resources managed by the selected stack but retains stack metadata.
- pulumi stack output [name]: Retrieves the value of a specific output defined in your Pulumi program.
-
pulumi config:
Displays or updates stack configuration values. Add
--secret
to store encrypted secrets. - pulumi refresh: Syncs the Pulumi state with the actual cloud resources by performing a read-only check.
- pulumi stack rm <name>: Permanently deletes the specified stack and optionally its state file. Irreversible.
Conclusion
Throughout this blog post, we explored Pulumi Stacks—an essential concept for building scalable, maintainable cloud infrastructure using Pulumi’s infrastructure-as-code model. You’ve seen how stacks provide isolation, configuration control, and repeatability for deploying infrastructure across environments like development, staging, and production.
Here’s a quick recap of what we covered:
- Core Components: We broke down what makes a stack work under the hood—including state, config, secrets, outputs, and backend providers.
- Stack Operations: You learned how to initialize, update, destroy, and manage stacks using powerful Pulumi CLI commands.
- Stack Configuration: We showed how stack-specific key/value settings and encrypted secrets allow dynamic and secure deployments.
- Stack Outputs: You saw how to export key values from your infrastructure for other stacks or tools to consume.
- Stack References: We covered how modular stacks can share data with each other, allowing clean architectural layering.
- Troubleshooting: We outlined errors you may encounter in day-to-day use—and how to resolve them confidently.
- Command Summary: You now have a cheat sheet of essential, commonly-used Pulumi CLI commands as a quick guide.
Pulumi Stacks unlock the power of clean environment separation, automation, and scalable infrastructure as code—all with the flexibility of your favorite programming language.
Thanks for following along! Whether you're just getting started with Pulumi or looking to refine your stack architecture across teams, we hope this guide gave you a strong foundation to build on. 🚀
If you enjoyed this post, consider sharing it with your team or bookmarking it for future reference during deployments.
Happy coding, and may your stacks stay healthy and your previews always be clean! 👨💻✨