https://pulumi.com logo
#aws
Title
j

jolly-activity-81321

09/04/2023, 7:44 AM
Hey everyone, Can anyone help me out with a simple problem? I'd like to convert
pulumi.StringOutput
(EC2 instance public IP) to native string in Go. I was trying with
pulumi.Sprintf()
or with
pulumi.ApplyT()
with no success:
Copy code
stringValue := pulumi.String("Hello, World!").ToStringOutput()

fmt.Printf("%s", stringValue.ApplyT(func(s string) string {
		return s
}))
m

melodic-tomato-39005

09/04/2023, 8:48 AM
Hi Martins,
Apply
is the correct approach, but the
Printf
needs to be inside the callback function. See the example and explanation here.
j

jolly-activity-81321

09/04/2023, 9:19 AM
Hey Thomas
I tried with
All
, same thing, basically
Copy code
stringValue := pulumi.String("Hello, World!").ToStringOutput()
	fmt.Println(pulumi.All(stringValue).ApplyT(func(args []interface{}) (string, error) {
		s := args[0]
		return fmt.Sprintf("%v", s), nil
	}).(pulumi.StringOutput))

//Outputs {0xc00047a460}
Outputs
{0xc00047a460}
where I expected
"Hello, World!"
m

melodic-tomato-39005

09/04/2023, 9:28 AM
You have two print statements here. The inner one should work, no? The outer one cannot work because
Apply
returns again an
Output
.
Also, using
All
is unnecessarily cumbersome if you have only one value,
ApplyT
is easier.
j

jolly-activity-81321

09/04/2023, 9:29 AM
I had it in the initial example, you said I needed
All
🙂
ok, so
m

melodic-tomato-39005

09/04/2023, 9:30 AM
Hi Martins,
Apply
is the correct approach
?
j

jolly-activity-81321

09/04/2023, 9:35 AM
hmm
so again, tried this:
Copy code
stringValue := pulumi.String("Hello, World!").ToStringOutput()
	original := stringValue.ApplyT(func(s string) (string, error) {
		return fmt.Sprintf("%v", s), nil
	})
	fmt.Printf("the parsed string is: %s", original)
I mean, there should be super-simple way...
m

melodic-tomato-39005

09/04/2023, 9:46 AM
I suggest you give these docs another read. They have more examples, too. There’s a reason you can only access the string inside
Apply
, it’s how Pulumi’s whole model of tracking dependencies works.
Also note that there’s
Export
for when you want to use a value outside of your Pulumi program, or in another one
j

jolly-activity-81321

09/04/2023, 1:36 PM
which suggests that using
Copy code
s := pulumi.Sprintf("%s", stringValue)
would work and give me a meaningful value... it does not...
Export
is for exporting the value for use in a different stack, isn't it?
I'm working in the same stack.
m

melodic-tomato-39005

09/04/2023, 1:46 PM
pulumi.Sprintf
is a helper wrapping
pulumi.Apply
. I think your examples above used
fmt.Sprintf
, which is different. But yes,
pulumi.Sprintf
with an argument of type
pulumi.StringOutput
should work.
j

jolly-activity-81321

09/04/2023, 1:47 PM
Copy code
stringValue := pulumi.String("Hello, World!").ToStringOutput()
	s := pulumi.Sprintf("%s", stringValue)
	fmt.Println(s)
the output is
Copy code
{0xc0001a82a0}
😢
m

melodic-tomato-39005

09/04/2023, 1:50 PM
Oh, I see. Well,
s
is again a
StringOutput
, not a
string
. Basically, the raw value wrapped by an Output cannot escape
Apply
and friends. Your logic working with the raw values needs to live in the callbacks to `Apply`/`All`/etc.
that’s this section:
If you need to access an output’s plain value—for example, to compute a derived, new value, or because you want to log it—you have these options:
Apply: a callback that receives the plain value, and computes a new output
Lifting: directly read properties off an output value
Interpolation: concatenate string outputs with other strings directly
j

jolly-activity-81321

09/04/2023, 2:33 PM
Yeah, could be. But then again - why even bothering making those helper functions under
printf.go
from Pulumi's PoW?
hell, my program is reduced to minimum, nothing working 😄
Copy code
func main() {
	stringValue := pulumi.String("Hello, World!").ToStringOutput()
	s := pulumi.Sprintf("%s", stringValue)
	fmt.Println(s)
}
m

melodic-tomato-39005

09/04/2023, 2:37 PM
That’s not expected to work.
s
is a StringOutput, not a string, so you can’t print it. The print needs to happen inside an
Apply
, i.e., in the `Apply`’s callback. Like in the example in the docs:
Copy code
myPet.ID().ApplyT(func(id string) error {
    fmt.Printf("Hello, %s!", id)
	return nil
})
similar to the nodejs promise/callback model.
j

jolly-activity-81321

09/04/2023, 2:42 PM
Thanks Thomas for your patience 🙂
I think I just have to wrap my head around it once again
m

melodic-tomato-39005

09/04/2023, 2:44 PM
No problem at all. The input/output model feels different to a lot of people. It helps if you’re worked with promises and callbacks but it’s not required.
j

jolly-activity-81321

09/04/2023, 3:06 PM
@melodic-tomato-39005 I think I found a way
1.
ctx.Export("publicIp", instance.PublicIp)
to export the value. I am provisioning EC2 instances in this case. 2. And then you can access it after running `Up`:
Copy code
upRes, err := stack.Up(ctx, stdoutStreamer)
	if err != nil {
		log.Fatal(err)
	}

	master.publicIp = fmt.Sprintf("%s", upRes.Outputs["publicIp"].Value)
I'm getting my string value now, yay 🎉
m

melodic-tomato-39005

09/04/2023, 7:28 PM
Yep, that would be the way to access your string outside of your Pulumi stack. Either in another stack, or just in another non-Pulumi program. In one Pulumi program with one stack, though, that’s unnecessary. The string value is accessible inside the
Apply
/`All` callback functions.
2 Views