or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

asset-management.mdautomation.mdconfiguration.mddynamic-resources.mdindex.mdlogging-diagnostics.mdoutput-system.mdprovider-development.mdresource-management.mdruntime-operations.mdstack-references.mdutilities.md

stack-references.mddocs/

0

# Stack References

1

2

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

3

4

## Core Stack Reference Class

5

6

```typescript { .api }

7

class StackReference extends CustomResource {

8

constructor(name: string, args: StackReferenceArgs, opts?: CustomResourceOptions);

9

10

// Output access methods

11

getOutput(name: Input<string>): Output<any>;

12

requireOutput(name: Input<string>): Output<any>;

13

getOutputDetails(name: Input<string>): Output<StackReferenceOutputDetails>;

14

15

// Synchronous access (non-secret values only)

16

getOutputValue(name: string): any;

17

requireOutputValue(name: string): any;

18

19

// Properties

20

readonly name: Output<string>;

21

readonly outputs: Output<{[name: string]: any}>;

22

readonly secretOutputNames: Output<string[]>;

23

}

24

25

interface StackReferenceArgs {

26

name: Input<string>;

27

}

28

29

interface StackReferenceOutputDetails {

30

value?: any;

31

secretValue?: any;

32

}

33

```

34

35

## Usage Examples

36

37

### Basic Stack Reference

38

39

```typescript

40

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

41

42

// Reference another stack

43

const networkStack = new pulumi.StackReference("network-stack", {

44

name: "myorg/network-infrastructure/production",

45

});

46

47

// Access outputs from the referenced stack

48

const vpcId = networkStack.getOutput("vpcId");

49

const subnetIds = networkStack.getOutput("privateSubnetIds");

50

51

// Use referenced outputs in current stack

52

const database = new aws.rds.Instance("app-db", {

53

subnetGroupName: new aws.rds.SubnetGroup("db-subnet-group", {

54

subnetIds: subnetIds,

55

}).name,

56

vpcSecurityGroupIds: [networkStack.getOutput("databaseSecurityGroupId")],

57

// ... other properties

58

});

59

```

60

61

### Cross-Organization References

62

63

```typescript

64

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

65

66

// Reference stack from different organization

67

const sharedInfra = new pulumi.StackReference("shared-infrastructure", {

68

name: "shared-org/common-infrastructure/production",

69

});

70

71

// Get shared resources

72

const sharedVpc = sharedInfra.getOutput("vpcId");

73

const sharedDnsZone = sharedInfra.getOutput("dnsZoneId");

74

75

// Use in current stack

76

const service = new aws.ecs.Service("app-service", {

77

cluster: sharedInfra.getOutput("ecsClusterId"),

78

taskDefinition: taskDefinition.arn,

79

subnets: sharedInfra.getOutput("privateSubnetIds"),

80

});

81

```

82

83

### Handling Secret Outputs

84

85

```typescript

86

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

87

88

const dbStack = new pulumi.StackReference("database-stack", {

89

name: "myorg/database/production",

90

});

91

92

// Get secret output (returns Output<any>)

93

const dbPassword = dbStack.getOutput("masterPassword");

94

95

// Get output details to check if secret

96

const passwordDetails = dbStack.getOutputDetails("masterPassword");

97

98

passwordDetails.apply(details => {

99

if (details.secretValue !== undefined) {

100

console.log("Password is stored as secret");

101

} else {

102

console.log("Password is plain text");

103

}

104

});

105

106

// Use secret in resource

107

const application = new aws.ecs.TaskDefinition("app-task", {

108

containerDefinitions: pulumi.jsonStringify([{

109

name: "app",

110

image: "myapp:latest",

111

environment: [

112

{

113

name: "DB_HOST",

114

value: dbStack.getOutput("endpoint"),

115

},

116

{

117

name: "DB_PASSWORD",

118

value: dbPassword, // Maintains secret status

119

},

120

],

121

}]),

122

});

123

```

124

125

### Conditional Stack References

126

127

```typescript

128

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

129

130

const config = new pulumi.Config();

131

const environment = config.require("environment");

132

133

// Reference different stacks based on environment

134

const infraStackName = environment === "production"

135

? "myorg/infrastructure/production"

136

: "myorg/infrastructure/staging";

137

138

const infraStack = new pulumi.StackReference("infra", {

139

name: infraStackName,

140

});

141

142

// Get environment-appropriate resources

143

const vpc = infraStack.getOutput("vpcId");

144

const certificateArn = infraStack.getOutput("sslCertificateArn");

145

```

146

147

### Multi-Stack Dependencies

148

149

```typescript

150

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

151

152

// Reference multiple related stacks

153

const networkStack = new pulumi.StackReference("network", {

154

name: "myorg/network/production",

155

});

156

157

const securityStack = new pulumi.StackReference("security", {

158

name: "myorg/security/production",

159

});

160

161

const monitoringStack = new pulumi.StackReference("monitoring", {

162

name: "myorg/monitoring/production",

163

});

164

165

// Combine outputs from multiple stacks

166

const webService = new aws.ecs.Service("web-service", {

167

cluster: networkStack.getOutput("ecsClusterId"),

168

taskDefinition: taskDefinition.arn,

169

loadBalancers: [{

170

targetGroupArn: networkStack.getOutput("webTargetGroupArn"),

171

containerName: "web",

172

containerPort: 80,

173

}],

174

serviceConnectConfiguration: {

175

enabled: true,

176

namespace: securityStack.getOutput("serviceConnectNamespace"),

177

},

178

});

179

180

// Export combined information

181

export const serviceEndpoint = pulumi.interpolate`https://${networkStack.getOutput("loadBalancerDnsName")}`;

182

export const monitoringDashboard = monitoringStack.getOutput("dashboardUrl");

183

```

184

185

### Error Handling

186

187

```typescript

188

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

189

190

const remoteStack = new pulumi.StackReference("remote", {

191

name: "external-org/shared-services/production",

192

});

193

194

// Safe access with fallbacks

195

const databaseUrl = remoteStack.getOutput("databaseUrl").apply(url => {

196

if (!url) {

197

throw new Error("Database URL not available from remote stack");

198

}

199

return url;

200

});

201

202

// Optional outputs with defaults

203

const cacheEndpoint = remoteStack.getOutput("cacheEndpoint").apply(endpoint =>

204

endpoint || "localhost:6379"

205

);

206

207

// Validate required outputs exist

208

const requiredOutputs = ["vpcId", "subnetIds", "securityGroupId"];

209

210

requiredOutputs.forEach(outputName => {

211

remoteStack.getOutput(outputName).apply(value => {

212

if (value === undefined || value === null) {

213

throw new Error(`Required output '${outputName}' is missing from remote stack`);

214

}

215

});

216

});

217

```

218

219

### Stack Reference Patterns

220

221

```typescript

222

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

223

224

// Utility function for consistent stack naming

225

function createStackReference(component: string, environment: string): pulumi.StackReference {

226

const org = pulumi.getOrganization();

227

const stackName = `${org}/${component}/${environment}`;

228

229

return new pulumi.StackReference(`${component}-${environment}`, {

230

name: stackName,

231

});

232

}

233

234

// Use with consistent naming pattern

235

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

236

237

const network = createStackReference("network", currentEnv);

238

const security = createStackReference("security", currentEnv);

239

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

240

241

// Helper for getting typed outputs

242

function getTypedOutput<T>(stackRef: pulumi.StackReference, outputName: string): pulumi.Output<T> {

243

return stackRef.getOutput(outputName) as pulumi.Output<T>;

244

}

245

246

// Usage with type safety

247

interface NetworkOutputs {

248

vpcId: string;

249

privateSubnetIds: string[];

250

publicSubnetIds: string[];

251

}

252

253

const networkOutputs = pulumi.all({

254

vpcId: getTypedOutput<string>(network, "vpcId"),

255

privateSubnetIds: getTypedOutput<string[]>(network, "privateSubnetIds"),

256

publicSubnetIds: getTypedOutput<string[]>(network, "publicSubnetIds"),

257

});

258

```

259

260

## Best Practices

261

262

- Use consistent stack naming conventions across your organization

263

- Handle missing outputs gracefully with appropriate defaults or errors

264

- Be mindful of secret outputs and maintain their secret status

265

- Use stack references to enforce separation of concerns between infrastructure layers

266

- Document the expected outputs from each stack for consumers

267

- Consider using typed interfaces for complex output structures

268

- Test stack references in non-production environments first

269

- Use organization-scoped stack names for shared infrastructure

270

- Plan for stack lifecycle management and migration strategies