Skip to content

Instantly share code, notes, and snippets.

@AaronFriel
Last active February 9, 2022 01:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AaronFriel/fa4d88781f339c2c26791a08b9c50c0e to your computer and use it in GitHub Desktop.
Save AaronFriel/fa4d88781f339c2c26791a08b9c50c0e to your computer and use it in GitHub Desktop.
TypeScript pulumi.all() and output#apply()
import * as pulumi from '@pulumi/pulumi';
import { PulumiFn } from '@pulumi/pulumi/automation';
type Node = {
role: pulumi.Output<string>;
};
// 'simple' way of faking an output is to wrap it in a promise, which should test our ability to
// wait on its value via pulumi.all, pulumi.output:
function mkOutputString(value: string): pulumi.Output<string> {
return pulumi.output(Promise.resolve(value));
}
// Create output "nodes" that are a lot like real resources, they are output objects, but you can
// also access the keys of the object & those are outputs as well.
function mkNode(role: string): pulumi.Output<pulumi.UnwrappedObject<Node>> {
return pulumi.output(
Promise.resolve({
role: mkOutputString(role),
}),
);
}
const nodes = [
mkNode("foo"), // an output containing keys that are also outputs
mkNode("bar"), // likewise
];
const k0sConfig = pulumi.all(nodes).apply((nodes) => ({
spec: nodes.map((n) => ({
// 💥💥💥💥💥
// kind: mkOutputString("bar"),
// 💥💥💥💥💥
// ^ if I uncomment this, I get the same error you did
role: n.role,
})),
}));
// With line 32 commented out, this works:
k0sConfig.apply((cfg) => pulumi.log.info(JSON.stringify(cfg)));
// But with line 32 uncommented, I get an error pretty printed as follows:
const error = {
"spec": [
{
"kind": "Calling [toJSON] on an [Output<T>] is not supported.\n\nTo get the value of an Output as a JSON value or JSON string consider either:\n 1: o.apply(v => v.toJSON())\n 2: o.apply(v => JSON.stringify(v))\n\nSee https://pulumi.io/help/outputs for more details.\nThis function may throw in a future version of @pulumi/pulumi.",
"role": "foo"
},
{
"kind": "Calling [toJSON] on an [Output<T>] is not supported.\n\nTo get the value of an Output as a JSON value or JSON string consider either:\n 1: o.apply(v => v.toJSON())\n 2: o.apply(v => JSON.stringify(v))\n\nSee https://pulumi.io/help/outputs for more details.\nThis function may throw in a future version of @pulumi/pulumi.",
"role": "foo"
}
]
};
// Fix is to pulumi.output() everything all at once:
const k0sctrl = mkNode('kubernetes-kind');
const k0sConfig2 = pulumi
.output({ nodes, k0sctrl })
// ^ declare _all_ of the inputs to our apply function
.apply(({ nodes, k0sctrl }) => ({
spec: nodes.map((n) => ({
kind: k0sctrl.role,
// consuming it here
role: n.role,
})),
}));
k0sConfig2.apply((cfg) => pulumi.log.info(JSON.stringify(cfg)));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment