-
Notifications
You must be signed in to change notification settings - Fork 0
0. CORE APIs
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 mapso
to another object (no primitive types allowed). If the underlying type ofo
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 tounwrap(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 }]
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' })
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' })