1. Answers
  2. Multi-Stack Management with Pulumi

How Do I Manage Multiple Stacks With Pulumi?

Introduction

In this guide, we’ll explore how to manage stacks with Pulumi. Stacks in Pulumi represent isolated deployments of your infrastructure often mapping to different environments (e.g. development, staging, and production). Managing multiple stacks allows you to maintain separation between environments while sharing code and configuration patterns. We’ll use TypeScript to demonstrate the concepts and techniques.

Explanation

Understanding Pulumi Stacks

Stacks are isolated, independently configurable instances of your Pulumi program. Each stack has its own state and configuration values. Stacks are commonly used to denote different phases of development (such as development, staging, and production) or feature branches (such as feature-x-dev).

Creating and Managing Multiple Stacks

  1. Create a new Pulumi project if you haven’t already:

    mkdir pulumi-multi-stack && cd pulumi-multi-stack
    pulumi new aws-typescript
    
  2. Create additional stacks for different environments:

    pulumi stack init dev    # Creates a stack named "dev"
    pulumi stack init staging
    pulumi stack init prod
    
  3. List the stacks associated with your project:

    pulumi stack ls
    
  4. Switch between stacks using the pulumi stack select command:

    pulumi stack select dev
    

Configuring Stacks

  1. Set stack-specific configuration values:

    pulumi config set aws:region us-west-2 --stack dev
    pulumi config set aws:region us-east-1 --stack prod
    
  2. Use configuration values in your code:

    const config = new pulumi.Config();
    const instanceType = config.get("instanceType") || "t2.micro";
    
  3. Get the current stack name programmatically:

    const stack = pulumi.getStack();
    // Use the stack name for conditional logic or naming resources
    const prefix = stack === "prod" ? "prod" : "dev";
    

Stack References

Stack references allow you to access the outputs of one stack from another stack, enabling inter-stack dependencies.

  1. Export values from one stack to use in another:

    // In the network stack (e.g., network-infra/index.ts)
    export const vpcId = vpc.id;
    export const subnetIds = vpc.privateSubnetIds;
    
  2. Import values from another stack:

    // In the app stack (e.g., app-infra/index.ts)
    import * as pulumi from "@pulumi/pulumi";
    
    // Reference another stack (if needed)
    const env = pulumi.getStack();
    const networkStack = new pulumi.StackReference(`organization/network-infra/${env}`);
    
    // Get output from the referenced stack
    const vpcId = networkStack.getOutput("vpcId");
    const subnetIds = networkStack.getOutput("subnetIds");
    
    // Use these values in your resources
    const securityGroup = new aws.ec2.SecurityGroup("app-sg", {
        vpcId: vpcId,
        // Other configurations
    });
    

Stack references support two ways of reading outputs:

  • getOutput: Returns an Output that provides gated access to the output value
  • getOutputDetails: Returns an OutputDetails object that provides direct access to the output value

Stack Tags

Stacks can have associated metadata in the form of tags. You can assign custom tags to a stack to customize grouping in Pulumi Cloud:

pulumi stack tag set environment production
pulumi stack tag set team platform

View a stack’s tags with:

pulumi stack tag ls

Stack Operations

  1. Update a stack:

    pulumi up
    
  2. View stack resources:

    pulumi stack
    
  3. Export and import stack deployments (for manual adjustments):

    pulumi stack export --file stack.json
    pulumi stack import --file stack.json
    
  4. Destroy a stack’s resources:

    pulumi destroy
    
  5. Delete a stack (after resources are destroyed):

    pulumi stack rm
    

Summary

Managing multiple stacks in Pulumi enables you to maintain separate environments while sharing code. By using stack references, you can create dependencies between stacks, allowing for modular and maintainable infrastructure as code. This approach is particularly valuable for complex applications that require consistent but separately managed infrastructure across different environments.

Deploy this code

Want to deploy this code? Sign up for a free Pulumi account to deploy in a few clicks.

Sign up

New to Pulumi?

Want to deploy this code? Sign up with Pulumi to deploy in a few clicks.

Sign up