CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-pulumi--pulumi

Pulumi's Node.js SDK for infrastructure-as-code platform that allows you to create, deploy, and manage infrastructure using familiar programming languages and tools.

85

1.02x
Overview
Eval results
Files

stack-references.mddocs/

Stack References

Stack references enable access to outputs from other Pulumi stacks, facilitating cross-stack dependencies and data sharing in multi-stack architectures.

Core Stack Reference Class

class StackReference extends CustomResource {
  constructor(name: string, args: StackReferenceArgs, opts?: CustomResourceOptions);
  
  // Output access methods
  getOutput(name: Input<string>): Output<any>;
  requireOutput(name: Input<string>): Output<any>;
  getOutputDetails(name: Input<string>): Output<StackReferenceOutputDetails>;
  
  // Synchronous access (non-secret values only)
  getOutputValue(name: string): any;
  requireOutputValue(name: string): any;
  
  // Properties
  readonly name: Output<string>;
  readonly outputs: Output<{[name: string]: any}>;
  readonly secretOutputNames: Output<string[]>;
}

interface StackReferenceArgs {
  name: Input<string>;
}

interface StackReferenceOutputDetails {
  value?: any;
  secretValue?: any;
}

Usage Examples

Basic Stack Reference

import * as pulumi from "@pulumi/pulumi";

// Reference another stack
const networkStack = new pulumi.StackReference("network-stack", {
  name: "myorg/network-infrastructure/production",
});

// Access outputs from the referenced stack
const vpcId = networkStack.getOutput("vpcId");
const subnetIds = networkStack.getOutput("privateSubnetIds");

// Use referenced outputs in current stack
const database = new aws.rds.Instance("app-db", {
  subnetGroupName: new aws.rds.SubnetGroup("db-subnet-group", {
    subnetIds: subnetIds,
  }).name,
  vpcSecurityGroupIds: [networkStack.getOutput("databaseSecurityGroupId")],
  // ... other properties
});

Cross-Organization References

import * as pulumi from "@pulumi/pulumi";

// Reference stack from different organization
const sharedInfra = new pulumi.StackReference("shared-infrastructure", {
  name: "shared-org/common-infrastructure/production",
});

// Get shared resources
const sharedVpc = sharedInfra.getOutput("vpcId");
const sharedDnsZone = sharedInfra.getOutput("dnsZoneId");

// Use in current stack
const service = new aws.ecs.Service("app-service", {
  cluster: sharedInfra.getOutput("ecsClusterId"),
  taskDefinition: taskDefinition.arn,
  subnets: sharedInfra.getOutput("privateSubnetIds"),
});

Handling Secret Outputs

import * as pulumi from "@pulumi/pulumi";

const dbStack = new pulumi.StackReference("database-stack", {
  name: "myorg/database/production",
});

// Get secret output (returns Output<any>)
const dbPassword = dbStack.getOutput("masterPassword");

// Get output details to check if secret
const passwordDetails = dbStack.getOutputDetails("masterPassword");

passwordDetails.apply(details => {
  if (details.secretValue !== undefined) {
    console.log("Password is stored as secret");
  } else {
    console.log("Password is plain text");
  }
});

// Use secret in resource
const application = new aws.ecs.TaskDefinition("app-task", {
  containerDefinitions: pulumi.jsonStringify([{
    name: "app",
    image: "myapp:latest",
    environment: [
      {
        name: "DB_HOST",
        value: dbStack.getOutput("endpoint"),
      },
      {
        name: "DB_PASSWORD",
        value: dbPassword, // Maintains secret status
      },
    ],
  }]),
});

Conditional Stack References

import * as pulumi from "@pulumi/pulumi";

const config = new pulumi.Config();
const environment = config.require("environment");

// Reference different stacks based on environment
const infraStackName = environment === "production" 
  ? "myorg/infrastructure/production"
  : "myorg/infrastructure/staging";

const infraStack = new pulumi.StackReference("infra", {
  name: infraStackName,
});

// Get environment-appropriate resources
const vpc = infraStack.getOutput("vpcId");
const certificateArn = infraStack.getOutput("sslCertificateArn");

Multi-Stack Dependencies

import * as pulumi from "@pulumi/pulumi";

// Reference multiple related stacks
const networkStack = new pulumi.StackReference("network", {
  name: "myorg/network/production",
});

const securityStack = new pulumi.StackReference("security", {
  name: "myorg/security/production", 
});

const monitoringStack = new pulumi.StackReference("monitoring", {
  name: "myorg/monitoring/production",
});

// Combine outputs from multiple stacks
const webService = new aws.ecs.Service("web-service", {
  cluster: networkStack.getOutput("ecsClusterId"),
  taskDefinition: taskDefinition.arn,
  loadBalancers: [{
    targetGroupArn: networkStack.getOutput("webTargetGroupArn"),
    containerName: "web",
    containerPort: 80,
  }],
  serviceConnectConfiguration: {
    enabled: true,
    namespace: securityStack.getOutput("serviceConnectNamespace"),
  },
});

// Export combined information
export const serviceEndpoint = pulumi.interpolate`https://${networkStack.getOutput("loadBalancerDnsName")}`;
export const monitoringDashboard = monitoringStack.getOutput("dashboardUrl");

Error Handling

import * as pulumi from "@pulumi/pulumi";

const remoteStack = new pulumi.StackReference("remote", {
  name: "external-org/shared-services/production",
});

// Safe access with fallbacks
const databaseUrl = remoteStack.getOutput("databaseUrl").apply(url => {
  if (!url) {
    throw new Error("Database URL not available from remote stack");
  }
  return url;
});

// Optional outputs with defaults
const cacheEndpoint = remoteStack.getOutput("cacheEndpoint").apply(endpoint => 
  endpoint || "localhost:6379"
);

// Validate required outputs exist
const requiredOutputs = ["vpcId", "subnetIds", "securityGroupId"];

requiredOutputs.forEach(outputName => {
  remoteStack.getOutput(outputName).apply(value => {
    if (value === undefined || value === null) {
      throw new Error(`Required output '${outputName}' is missing from remote stack`);
    }
  });
});

Stack Reference Patterns

import * as pulumi from "@pulumi/pulumi";

// Utility function for consistent stack naming
function createStackReference(component: string, environment: string): pulumi.StackReference {
  const org = pulumi.getOrganization();
  const stackName = `${org}/${component}/${environment}`;
  
  return new pulumi.StackReference(`${component}-${environment}`, {
    name: stackName,
  });
}

// Use with consistent naming pattern
const currentEnv = new pulumi.Config().require("environment");

const network = createStackReference("network", currentEnv);
const security = createStackReference("security", currentEnv);
const data = createStackReference("data-platform", currentEnv);

// Helper for getting typed outputs
function getTypedOutput<T>(stackRef: pulumi.StackReference, outputName: string): pulumi.Output<T> {
  return stackRef.getOutput(outputName) as pulumi.Output<T>;
}

// Usage with type safety
interface NetworkOutputs {
  vpcId: string;
  privateSubnetIds: string[];
  publicSubnetIds: string[];
}

const networkOutputs = pulumi.all({
  vpcId: getTypedOutput<string>(network, "vpcId"),
  privateSubnetIds: getTypedOutput<string[]>(network, "privateSubnetIds"),
  publicSubnetIds: getTypedOutput<string[]>(network, "publicSubnetIds"),
});

Best Practices

  • Use consistent stack naming conventions across your organization
  • Handle missing outputs gracefully with appropriate defaults or errors
  • Be mindful of secret outputs and maintain their secret status
  • Use stack references to enforce separation of concerns between infrastructure layers
  • Document the expected outputs from each stack for consumers
  • Consider using typed interfaces for complex output structures
  • Test stack references in non-production environments first
  • Use organization-scoped stack names for shared infrastructure
  • Plan for stack lifecycle management and migration strategies

Install with Tessl CLI

npx tessl i tessl/npm-pulumi--pulumi

docs

asset-management.md

automation.md

configuration.md

dynamic-resources.md

index.md

logging-diagnostics.md

output-system.md

provider-development.md

resource-management.md

runtime-operations.md

stack-references.md

utilities.md

tile.json