question does anyone know how to properly work wit...
# golang
s
question does anyone know how to properly work with a Export from a stack that contains json that was created by
pulumi.StringMap
trying to process it in another stack but getting a pointer address instead of the value. trying some thing along the lines of
Copy code
stackName := config.Require(ctx, "network:vpc")
		region := config.Require(ctx, "aws:region")
		s := fmt.Sprintf("%s-%s-subnets", region, stackName)
		subnets := other.GetStringOutput(pulumi.String(s))
		fmt.Println(string(subnets.ToStringOutput()))
some reason ToStringOutput only returns a pulumi.StringOutput and not a string like I would expect it to be .
f
This is very common scenario. The output is a Pulumi (stringOutput in your case) type not string, so you need to do the modifications inside an apply. There is some more info here: https://leebriggs.co.uk/blog/2021/05/09/pulumi-apply
s
I'm trying to fetch the value of the stack export. So that I can loop over this case some subnets. this export holds something like this
Copy code
{
  "appsubnet1": "subnet-0f13eee47334ba908",
  "appsubnet2": "subnet-0abfb3303f52ff8da",
  "appsubnet3": "subnet-0025bfd931231a002",
  "datasubnet1": "subnet-0144df74657bbe02b",
  "datasubnet2": "subnet-0c8fab9ea0ba72507",
  "datasubnet3": "subnet-05f5adb7c8fb4427e",
  "publicsubnet1": "subnet-02db54b375451331f",
  "publicsubnet2": "subnet-0ea9b849dd585d88e",
  "publicsubnet3": "subnet-0c8c0a5b1824a8a93"
}
b
It’s going to be very very painful to do this - if you need to use it in another stack, I would strongly consider converting it to an actual JSON string and then parsing it back on the other side. Handling complex types (e.g. array or map) in an export is very challenging.
s
i'm fine converting it to json, but the issue is how do you pull that stack export into another stack and make it usable
hrm...
Copy code
unc (v *vpcSetup) Export() {
	v.CREATE.ctx.Export(fmt.Sprintf("vpc-%s-name", v.Items().conf.Name), pulumi.String(v.Items().conf.Name))
	v.CREATE.ctx.Export(fmt.Sprintf("vpc-%s-id", v.Items().conf.Name), v.Items().vpc.ID())

	s := make(map[string]string, len(v.Items().subnets))
	for name, subnet := range v.Items().subnets {
		n := strings.Split(name, "_")
		s[n[1]] = fmt.Sprintf("%s", subnet.ID())
	}
	sJ, _ := json.Marshal(s)

	v.CREATE.ctx.Export(fmt.Sprintf("%s_subnets", v.Items().conf.Name), pulumi.String(string(sJ)))

	rt := make(map[string]string, len(v.Items().routeTables))
	for name, routeTable := range v.Items().routeTables {
		n := strings.Split(name, "_")
		rt[n[1]] = fmt.Sprintf("%s", routeTable.ID())
	}
	rtJ, _ := json.Marshal(rt)

	v.CREATE.ctx.Export(fmt.Sprintf("%s_route-tables", v.Items().conf.Name), pulumi.String(string(rtJ)))

}
that only gives me a json object of pointers
b
You likely need to marshal it to JSON in an apply block
So it would be something like:
Copy code
... make an array of all the subnet IDs ...

idMap := pulumi.All(subnetIDs).ApplyT(func(ids []interface{}) string {
  ... cast it to a string and build a map ...
  ... marshal to json
  ... return the json
}

ctx.Export("...", idMap)
s
interesting as we trying this
Copy code
func main() {
	networkSubnets := make(map[string]string, 10)

	pulumi.Run(func(ctx *pulumi.Context) error {
		conf := config.New(ctx, "")
		stack, err := pulumi.NewStackReference(ctx, "boost/network/dev", nil)
		if err != nil {
			return fmt.Errorf("error retrieveing stack reference: %v", err)
		}
		stackName := conf.Require("vpc")
		region := conf.Require("aws-region")
		s := fmt.Sprintf("%s-%s_subnets", stackName, region)
		outputs := stack.GetOutput(pulumi.String(s))
		sj := pulumi.All(outputs).ApplyT(func(subnets []interface{}) string {
			for name, subnet := range subnets[0].(map[string]interface{}) {
				fmt.Println("Name:", name, "=>", "Subnet:", subnet)
				// HIT THIS WITH MY BIG ASS HAMMER
				networkSubnets[name] = subnet.(string)
			}
			s, _ := json.Marshal(networkSubnets)
			return string(s)

		})
		fmt.Println(sj)
		return nil
	})

}
and getting this as output
Copy code
Type                 Name            Plan       Info
 +   pulumi:pulumi:Stack  stack-test-dev  create     10 messages
 
Diagnostics:
  pulumi:pulumi:Stack (stack-test-dev):
    {0x140002f4bd0}
    Name: appsubnet1 => Subnet: subnet-0f13eee
    Name: appsubnet2 => Subnet: subnet-0abfb33
    Name: datasubnet1 => Subnet: subnet-0144df
    Name: datasubnet3 => Subnet: subnet-05f5ad
    Name: appsubnet3 => Subnet: subnet-0025bfd
    Name: publicsubnet3 => Subnet: subnet-0c8c
    Name: datasubnet2 => Subnet: subnet-0c8fab
    Name: publicsubnet1 => Subnet: subnet-02db
    Name: publicsubnet2 => Subnet: subnet-0ea
Seems that the pulumi.All().ApplyT happens after the fun. So its not possible to use a stack reference in a this aspect with out building all additional information inside a applyT. So for us to get the subnets from out network stack for our eks clusters we can't do that unless we build a fuction that creates the cluster inside the applyt
this is def a down fall of how stackreference is currently created. As stackreferences already exist and shouldn't be a await (async) call, they should be just calls to pulumi's api and return in the order of the function instead of at the end of the function execution.
This is something I really hope that pulumi fixes sooner then later, I hear theirs a engineer thats talking with the CTO about is problem and I hope they fix it as its the number 1 issue I constantly am reading about pulumi