What about something like this? ```import * as aws...
# general
c
What about something like this?
Copy code
import * as aws from "@pulumi/aws";
import * as pulumi from "@pulumi/pulumi";


export function generateMachinesYaml(
    masters: aws.ec2.Instance[],
    workers: aws.ec2.Instance[]
) {
    let results: any[] = [];
    for (let i = 0; i < masters.length; i++) {
        const m = masters[i];
        pulumi
            .all([m.id, m.publicIp, m.privateIp])
            .apply(([id, publicIp, privateIp]) =>
                results.push({
                    id,
                    publicIp,
                    privateIp,
                    label: "master"
                })
            );
    }
    let listItems: string[] = [];
    for (let i = 0; i < workers.length; i++) {
        const m = workers[i];
        pulumi
            .all([m.id, m.publicIp, m.privateIp])
            .apply(([id, publicIp, privateIp]) =>
                listItems.push(
                    `- apiVersion: <http://cluster.k8s.io/v1alpha1|cluster.k8s.io/v1alpha1>
  kind: Machine
  metadata:
    name: $id}
    namespace: weavek8sops
    labels:
      set: "worker"
  spec:
    versions:
      kubelet: 1.14.1
      controlPlane: 1.14.1
    providerSpec:
      value:
        apiVersion: baremetalproviderspec/v1alpha1
        kind: BareMetalMachineProviderSpec
        public:
          address: ${publicIp}
          port: 22
        private:
          address: ${privateIp}
          port: 22`
                ))
            .apply(() => {
                // listItems = listItems.join("\n");
                const yaml =
                    `apiVersion: v1
kind: List
items: ${listItems}`;
                return yaml;
            });
    }
}
w
FWIW - here's my take on it as well:
Copy code
export function generateMachinesYaml(masters: aws.ec2.Instance[], workers: aws.ec2.Instance[]): pulumi.Output<string> {
    const results = [];
    for(const instance of masters) {
        results.push({ label: "master", instance: instance });
    }
    for(const instance of workers) {
        results.push({ label: "worker", instance: instance });
    }
    const listItems = results.map(({ instance, label}) => pulumi.interpolate`- apiVersion: <http://cluster.k8s.io/v1alpha1|cluster.k8s.io/v1alpha1>
  kind: Machine
  metadata:
    name: ${instance.id}
    namespace: weavek8sops
    labels:
      set: ${label}
  spec:
    versions:
      kubelet: 1.14.1
      controlPlane: 1.14.1
    providerSpec:
      value:
        apiVersion: baremetalproviderspec/v1alpha1
        kind: BareMetalMachineProviderSpec
        public:
          address: ${instance.publicIp}
          port: 22
        private:
          address: ${instance.privateIp}
          port: 22`
    ).join("\n");
    const yaml = pulumi.interpolate`apiVersion: v1
    kind: List
    items:
    ${listItems}
    `;
    return yaml;
}
cc @ripe-lighter-13633
r
thank you guys … trying…
w
No
apply
there. But there is a
pulmi.interpolate
to build a the strings using
Output
s.
r
Hey @white-balloon-205, tried your approach, still getting
Calling [toString] on an [Output<T>] is not supported.
w
Ahh - sorry - hadn't tested - this hopefully works:
Copy code
export function generateMachinesYaml(masters: aws.ec2.Instance[], workers: aws.ec2.Instance[]): pulumi.Output<string> {
    const results = [];
    for(const instance of masters) {
        results.push({ label: "master", instance: instance });
    }
    for(const instance of workers) {
        results.push({ label: "worker", instance: instance });
    }
    const listItems = results.map(({ instance, label}) => pulumi.interpolate`- apiVersion: <http://cluster.k8s.io/v1alpha1|cluster.k8s.io/v1alpha1>
  kind: Machine
  metadata:
    name: ${instance.id}
    namespace: weavek8sops
    labels:
      set: ${label}
  spec:
    versions:
      kubelet: 1.14.1
      controlPlane: 1.14.1
    providerSpec:
      value:
        apiVersion: baremetalproviderspec/v1alpha1
        kind: BareMetalMachineProviderSpec
        public:
          address: ${instance.publicIp}
          port: 22
        private:
          address: ${instance.privateIp}
          port: 22`
    );
    const listString = pulumi.all(listItems).apply(parts => parts.join("\n"))
    const yaml = pulumi.interpolate`apiVersion: v1
    kind: List
    items:
    ${listString}
    `;
    return yaml;
}
And does use one
.all().apply()
.
r
@white-balloon-205 that worked! Thank you… Can we please add an example like this one on the documentation to avoid this being reported every other day? I saw many other examples running into the same issue
but each with a different approach
and different solution
w
We are going to do a deep dive blog post on this soon. Will see about putting a couple more complete examples like this in the programming model docs as well.
👍 2
r
knowing that you need 2
interpolate()
and 1
all().apply()
is very tricky in my opinion
Thank you so much
w
FWIW - You could also do all of this with just a single
.all().apply()
and no
interpolate
.
r
I think showing how you can refine over and over in the blog post could be very helpful
👍 1
w
FWIW - I think this would work too - and is potentially even "simpler"?
Copy code
export function generateMachinesYaml(masters: aws.ec2.Instance[], workers: aws.ec2.Instance[]): pulumi.Output<string> {
    const results = [];
    for(const instance of masters) {
        results.push({ label: "master", id: instance.id, publicIp: instance.publicIp, privateIp: instance.privateIp });
    }
    for(const instance of workers) {
        results.push({ label: "worker", id: instance.id, publicIp: instance.publicIp, privateIp: instance.privateIp });
    }
    return pulumi.all(results).apply(instances => {
        const listItems = instances.map(({ label, id, publicIp, privateIp }) => `- apiVersion: <http://cluster.k8s.io/v1alpha1|cluster.k8s.io/v1alpha1>
        kind: Machine
        metadata:
          name: ${id}
          namespace: weavek8sops
          labels:
            set: ${label}
        spec:
          versions:
            kubelet: 1.14.1
            controlPlane: 1.14.1
          providerSpec:
            value:
              apiVersion: baremetalproviderspec/v1alpha1
              kind: BareMetalMachineProviderSpec
              public:
                address: ${publicIp}
                port: 22
              private:
                address: ${privateIp}
                port: 22`).join("\n");
        return `apiVersion: v1
        kind: List
        items:
        ${listItems}
        `;  
    });
}
r
👏 that worked! wow!… thank you
good lord it’s much simpler