Streamline access to stack outputs with OutputDetails

Posted on

You can use the new StackReference.getOutputDetails method to get output values from other stacks directly—without calling Output.apply.

What are Stack References?

If you already understand stack references, skip on to Introducing OutputDetails.

Stack references are a useful feature of Pulumi that you can use to access output values from one stack in another.

For instance, let’s say you have a ’network’ stack that provisions an AWS VPC, and an ‘app’ stack that deploys your application on an EC2 instance in that VPC. The app stack can reference the output of the network stack to obtain the VPC ID, which it needs to configure the EC2 instance.

const network = new pulumi.StackReference("acmecorp/network/other");
const vpcId = network.getOutput("vpcId");

The getOutput method above returns an Output value that holds the result. You can call Output.apply to perform transformations on the output value. As an example, if you need to extract a subnet ID from a JSON string in the output, you can use the following code:

const subnetConfig = network.getOutput("subnetConfig");
const subnetId = subnetConfig.apply(output => JSON.parse(output).subnetId);

This approach works but is limited because the output value obtained from the apply transformation is also an Output value. You cannot access or manipulate this value directly, and you must continue to use apply repeatedly to consume the value.

As an aid in resolving this problem, we have introduced OutputDetails. These provide direct access to the output of one stack from another stack.

Introducing OutputDetails

We’ve added a new method, StackReference.getOutputDetails, to allow direct access to output values from stack references. This method can be used as follows:

const vpcIdDetails = await network.getOutputDetails("vpcId");
const vpcId = vpcIdDetails.value;

Unlike the getOutput method, the resulting value is a plain value, not an Output value. As a result, there is no need to call apply repeatedly to transform or consume the value.

Revisiting the previous example of extracting a value from a JSON string, getOutputDetails can be used as shown below:

const subnetConfig = (await network.getOutputDetails("subnetConfig")).value;
const subnetId = JSON.parse(subnetConfig).subnetId;
console.log(`Using subnet ID ${subnetId}`);

What about secrets?

getOutputDetails can also be used to access secret outputs generated by the referenced stack. For example, if the referenced stack sets up a database and produces the password as a stack output, you can access it as follows:

const passwordDetails = await dbStack.getOutputDetails("databasePassword");
const password = passwordDetails.secretValue;

Can we do this for all Output values?

Unfortunately, it is not feasible to do this to every Output value. Stack references are unique in that the referenced stack must already have deployed for the reference to be resolved. Therefore, when the stack reference is created, the outputs of the referenced stack are available immediately. This is not the case for other Output values. Their values only become available as pulumi update runs, so we cannot access them in the same way.

Availability

This feature is available in all stable SDKs for Pulumi, starting from v3.55.0. Give it a spin and share your thoughts with us on Slack!