https://pulumi.com logo
g

gray-city-50684

11/15/2018, 4:35 PM
hi, is it possible to generate YAML from the Kubernetes objects defined in Pulumi? The use-case I have in mind: injecting sidecar containers to a Deployment (linkerd2, with CLI).
c

creamy-potato-29402

11/15/2018, 4:35 PM
You mean, emit YAML objects to a text file?
It’s not directly supported, no. But why not just inject the sidecar inside the pulumi program?
g

gray-city-50684

11/15/2018, 4:36 PM
yes, so I can transform it with the CLI and read it back
c

creamy-potato-29402

11/15/2018, 4:36 PM
ah the linkerd2 CLI?
g

gray-city-50684

11/15/2018, 4:36 PM
yes
c

creamy-potato-29402

11/15/2018, 4:36 PM
You could shell out and then pass the result to the constructor.
I forget the exact syntax, but something like
new k8s.apps.v1.Deployment("app", JSON.parse(execSync("... command ...", {...}))
or something.
g

gray-city-50684

11/15/2018, 4:39 PM
what I mean is, I defined a Deployment with Pulumi code (no YAML). But the CLI needs YAML to transform it. I can re-implement the transformation they do in Pulumi (you showed it to me once, I use it to do some Azure workarounds) I just thought I ask if there is a way to transform Pulumi objects to the corresponding YAML, before I start doing anything.
w

white-balloon-205

11/15/2018, 5:56 PM
@gray-city-50684 We have thoughts to extend the
transformations
callback that is available on
Chart
(https://github.com/pulumi/pulumi-kubernetes/blob/master/sdk/nodejs/helm.ts#L16) to be available on more resources. This gives you a callback that will get called with the inputs that are planned to create with, and the opportunity to step in and make changes/additions prior to creation. If something like this was available on all Kubernetes resources, you could then shell out to the CLI tool from within that callback. Would that address this scenario for you? Or do you ned to see all of the YAML for the entire program prior to passing it to the CLI tool?
g

gray-city-50684

11/15/2018, 6:01 PM
Well, this particular CLI tool (linkerd2) transforms only YAML’s, and it looks for Deployment definitions there (as far as I can tell from my tests). So if I would start from YAMLs that would work I guess. But in my case I defined the Deployment with Pulumi objects, so there is no YAML to begin with.
My thought was to “convert” the Pulumi objects to YAML, do the transformation with the CLI and then read it back into a ConfigGroup
w

white-balloon-205

11/15/2018, 6:03 PM
If you could get YAML for just the
Deployment
based on the Pulumi
new k8s.app.v1.Deployment
- is that sufficient? Or do you need all the resources you defined in Pulumi at once?
g

gray-city-50684

11/15/2018, 6:05 PM
I just started to test Linkerd2, but with the tests I ran, it only changes Deployment objects - so yes, for my use-case it would work.
m

microscopic-florist-22719

11/15/2018, 6:18 PM
Do you need the YAML for the deployment before it is submitted to the API server?
If so, I think that you could probably use `js-yaml`'s
safeDump
to dump the inputs you'd normally pass to
k8s.app.v1.Deployment
then invoke
linkerd2
and use a
ConfigFile
or just re-read the YAML using `js-yaml`'s
safeLoad
and then pass the inputs to
new k8s.app.v1.Deployment
g

gray-city-50684

11/15/2018, 6:27 PM
will the js-yaml way work if I have code like
serviceAccountName: serviceAccount.metadata.apply(meta => meta.name)
in the new k8s.app.v1.Deployment’s definition?
m

microscopic-florist-22719

11/15/2018, 6:28 PM
Yes, but you'll need to do it in an apply
lemme whip up a quick example
g

gray-city-50684

11/15/2018, 6:28 PM
thanks
m

microscopic-florist-22719

11/15/2018, 6:30 PM
hm, that may not be as simple as I had hoped
@white-balloon-205 is there a particular reason that we don't allow a resource's args bag to be an Input<>?
or is that just an oversight?
w

white-balloon-205

11/15/2018, 6:31 PM
I expect we've never had a use case in the past 🙂. Not sure if there is anything deeper that would prevent supporting that.
m

microscopic-florist-22719

11/15/2018, 6:33 PM
there isn't anything that I can think of
okay, so here's the code I want to write:
Copy code
const deployment = new k8s.apps.v1.Deployment("app", {
	// some args that may include `Output<T>` values
});

->

const deploymentArgs = pulumi.output({
	// some args that may include `Output<T>` values	
}).apply(args => {
	// args is now fully-resolved.

	// dump to a file with js-yaml
    const tmpYaml = tmp.fileSync();
	fs.writeFileSync(tmpYaml.fd, jsyaml.safeDump(args));

	// invoke linkerd2 as appropriate and parse and return the yaml
    const yamlText = childProcess.execSync(`linkerd2 ${tmpYaml.name}`).toString();
	return jsyaml.safeLoad(yamlText);
});
const deployment = new k8s.apps.v1.Deployment("app", deploymentArgs);
but the last line--the creation of the
Deployment
--won't work today b/c its second argument cannot be an
Output<T>
.
as a workaround, you can write this code:
Copy code
const deploymentArgs = pulumi.output({
	// some args that may include `Output<T>` values	
}).apply(args => {
	// args is now fully-resolved.

	// dump to a file with js-yaml
    const tmpYaml = tmp.fileSync();
	fs.writeFileSync(tmpYaml.fd, jsyaml.safeDump(args));

	// invoke linkerd2 as appropriate and parse and return the yaml
    const yamlText = childProcess.execSync(`linkerd2 ${tmpYaml.name}`).toString();
	return jsyaml.safeLoad(yamlText);
});
const deployment = deploymentArgs.apply(args => new k8s.apps.v1.Deployment("app", args));
with the cautionary note that if any part of the deployment args is unknown during a preview, you will not see the deployment being created
it will be created at runtime, though
g

gray-city-50684

11/15/2018, 6:40 PM
thx, I will give it a try tomorrow
m

microscopic-florist-22719

11/15/2018, 6:51 PM
filed https://github.com/pulumi/pulumi/issues/2210 to track Input<> arg bags