Skip to content

0. CORE APIs

Nicolas Dao edited this page May 15, 2022 · 5 revisions

Table of contents

APIs

unwrap

The unwrap is similar to pulumi.ouput and pulumi.all, but goes the extra mile by also unwrapping the object's properties (if they were also outputs). This is especially usefull when dealing with Output of arrays. unwrap signature:

unwrap(o:Object[, fn:Function|props:[String]]): Output

Where:

  • o is expected to be a Pulumi Output, but it could also be any object or promise.
  • fn is a mapping function that maps o to another object (no primitive types allowed). If the underlying type of o is an array, this mapping function is applied to each array item.
  • props: Filtered list of mapping properties. For example, unwrap(o, x => ({ id:x.id, name:x.name })) is similar to unwrap(o, ['id', 'name'])

Examples:

const { unwrap } = require('@cloudlessopenlabs/pulumix')

const resource01 = ... // Output of type { id: Output<Number>, name:Output<String>, ...  }
const resource02 = ... // Output of arrays of items of type { id: Output<Number>, name:Output<String>, ... }

unwrap(resource01).apply(console.log) // -> { id:1, name:'hello', age:40 }
unwrap(resource02).apply(console.log) // -> [{ id:1, name:'hello', age:40 }, { id:2, name:'world', age:50 }]
unwrap(resource01, x => ({ id:x.id })).apply(console.log) // -> { id:1 }
unwrap(resource01, ['id']).apply(console.log) // -> { id:1 }
unwrap(resource02, x => ({ id:x.id })).apply(console.log) // -> [{ id:1 }, { id:2 }]
unwrap(resource02, ['id']).apply(console.log) // -> [{ id:1 }, { id:2 }]

getProject and getStack

Those 2 APIs offer a consistent way to get a project's details as well as reference a stack regardless of the backend used. To learn more about the motivation behind these APIs, please refer to the Why is the stack name convention different when the backend is not the default Pulumi? section.

const { getProject, getStack } = require('@cloudlessopenlabs/pulumix')

const { project, stack, fullStack } = getProject()
console.log(project) 	// e.g., 'my-other-project'
console.log(stack) 		// e.g., 'prod'
console.log(fullStack)	// e.g., 'prod' or 'my-other-project.prod'

const myOtherTask = getStack({ org:'my-org', project:'my-project', stack, backend:'s3' })

Annexes

Why is the stack name convention different when the backend is not the default Pulumi?

The cross-stack referencing is poorly engineered. By default, the Pulumi backend is managed by Pulumi itself at https://app.pulumi.com/. You must first create an account there (and possibly an organization). Moving from there, when you which to reference a project's stack into another, you use the following API:

const myOtherProdStack = new pulumi.StackReference('my-org/my-project/prod')

This convention creates the illusion that this stack is located under a file structure, but this is misleading. In reality, this stack's state (refered as the checkpoint file) only contains the stack (prod in our case). This file is stored under the propritary Pulumi backend which looks like a filesystem.

However, Pulumi is configured to use a different backend, this filesystem feature is lost. A custom backend is just a plain storage. It can only store checkpoint files, which are flat, which means that the input of the StackReference API can only be a stack rather than the combination of an organization, project and stack (NOTE: organizations are not supported with custom backends).

To overcome, this issue, the hack consists in including the project name in the stack name. Instead of using a stack named prod, use a stack named my-project.prod.

Referencing this stack becomes:

const myOtherProdStack = new pulumi.StackReference('my-project.prod')

Because this is inconsistent, we created a

const { getProject, getStack } = require('@cloudlessopenlabs/pulumix')

const { project, stack, fullStack } = getProject()
console.log(project) 	// e.g., 'my-other-project'
console.log(stack) 		// e.g., 'prod'
console.log(fullStack)	// e.g., 'prod' or 'my-other-project.prod'

const myOtherTask = getStack({ org:'my-org', project:'my-project', stack, backend:'s3' })
Clone this wiki locally