https://pulumi.com logo
#general
Title
# general
c

calm-quill-21760

02/25/2020, 10:23 PM
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

white-balloon-205

02/25/2020, 10:23 PM
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

ripe-lighter-13633

02/25/2020, 10:24 PM
thank you guys … trying…
w

white-balloon-205

02/25/2020, 10:25 PM
No
apply
there. But there is a
pulmi.interpolate
to build a the strings using
Output
s.
r

ripe-lighter-13633

02/25/2020, 10:27 PM
Hey @white-balloon-205, tried your approach, still getting
Calling [toString] on an [Output<T>] is not supported.
w

white-balloon-205

02/25/2020, 10:29 PM
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

ripe-lighter-13633

02/25/2020, 10:31 PM
@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

white-balloon-205

02/25/2020, 10:32 PM
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

ripe-lighter-13633

02/25/2020, 10:32 PM
knowing that you need 2
interpolate()
and 1
all().apply()
is very tricky in my opinion
Thank you so much
w

white-balloon-205

02/25/2020, 10:33 PM
FWIW - You could also do all of this with just a single
.all().apply()
and no
interpolate
.
r

ripe-lighter-13633

02/25/2020, 10:35 PM
I think showing how you can refine over and over in the blog post could be very helpful
👍 1
w

white-balloon-205

02/25/2020, 10:36 PM
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

ripe-lighter-13633

02/25/2020, 10:37 PM
👏 that worked! wow!… thank you
good lord it’s much simpler
2 Views