https://pulumi.com logo
#getting-started
Title
# getting-started
f

freezing-vase-18205

01/12/2024, 4:09 PM
Hi all I have a question about outputs and the concrete types they represent. If I have a string output, it seems that in Go I can’t quite get the actual string with
pulumi.Sprintf
Copy code
hostname := pulumi.String("localhost").ToStringOutput()
url := pulumi.Sprintf("http://%s/", hostname)
where
url
is still pulumi.Output
f

fierce-terabyte-6114

01/12/2024, 4:14 PM
yeah, getting actual strings is quite odd. it has to do with the async promise/future nature of pulumi. you can only access the raw strings from the 'output' types by using
ApplyT
f

freezing-vase-18205

01/12/2024, 4:57 PM
right @fierce-terabyte-6114, and it seems that even then I can only access the actual value in the closure of ApplyT, e.g. I can’t return it to the function where I get a resource…
Actually, the end goal that I am pursuing is generating a YAML with certain output values from the created resources And I am quite puzzled what is the best way to do that. The only working method I found is
pulumi.All()
but then I need to add every single output I am interested in in that function
f

fierce-terabyte-6114

01/12/2024, 5:01 PM
yeah it wont actually return the string, its only available in the closure. i am in the same boat as you...
All
seems to be the only way to get multiple resources
f

freezing-vase-18205

01/12/2024, 5:05 PM
omg, what a timing exactly the same line of thought and unwillingness to give up on Go just yet 😄
s

salmon-account-74572

01/12/2024, 5:55 PM
I love using Go for my Pulumi programs (it’s one of the things that drew me to Pulumi before I joined the company), but it can make things a bit more complex at times. Working with Outputs is one of those times. That said, I have found that using Go with the Automation API can help somewhat. If memory serves correctly, fetching stack outputs from Automation API returns “normal” types (not Output-y types), and it helps create a clean separation between idempotent/declarative operations inside your Pulumi program and (potentially) imperative operations outside the Pulumi program.
f

fierce-terabyte-6114

01/12/2024, 5:56 PM
can you share a little bit more about this? i am pretty new to pulumi
f

freezing-vase-18205

01/12/2024, 8:25 PM
Love go as well, @salmon-account-74572 but looking at the
pulumi.All()
witchcraft made me switch right now to pulumi-Python. As much as I am less proficient in Py than in Go, the inability to easily work with output native types made it hard to justify Go choice
@fierce-terabyte-6114 I believe this is the API used to get exported outputs from Pulumi Cloud this is what
pulumi stack output
does
so I read both Py and TS docs (hoping that at least in TS where promises are native constructs) and it is all the same, to be honest. Still
all
+
apply
to get “real” values from the outputs For instance, the Py version is just a little bit better (since no type inference and can have named args):
Copy code
# renderYAML waits for outputs to be ready
# and renders the kubeone_cluster to a YAML file
def renderYAML(cp_host, cp_int_ip, cp_hostname, static_workers):
    def populate_spec(outputs):
        kubeone_cluster["apiEndpoint"]["host"] = outputs["cp_host"]
        kubeone_cluster["controlPlane"]["hosts"][0]["publicAddress"] = outputs[
            "cp_host"
        ]

        for worker_out in outputs["static_workers"]:
            kubeone_cluster["staticWorkers"]["hosts"].append(
                {
                    "publicAddress": worker_out[0],
                    "privateAddress": worker_out[0],
                    "sshUsername": "root",
                    "hostname": worker_out[1],
                    "bastion": outputs["cp_host"],
                }
            )

        # writing kubeone yaml to file
        with open("kubeone.yaml", "w") as f:
            yaml.dump(
                kubeone_cluster,
                f,
                sort_keys=False,
            )

    pulumi.Output.all(
        cp_host=cp_host,
        cp_int_ip=cp_int_ip,
        cp_hostname=cp_hostname,
        static_workers=static_workers,
    ).apply(populate_spec)