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

clever-kite-79772

08/01/2023, 2:42 PM
Hi All, I tried to find the answer but I couldn't Can I in golang pulumi export map of objects? For example I create 5 key-pair and I'd like to export map[string]*ec2.KeyPair. When I try to use:
Copy code
type KeyPairExport struct {
	KeyName pulumi.StringOutput `pulumi:"key_name"`
	Id      pulumi.StringOutput `pulumi:"id"`
}

		pairResources := make(map[pulumi.String]KeyPairExport)
		for _, kp := range keyPairs {
			nkp, _ := ec2.NewKeyPair(ctx, kp.Name, &ec2.KeyPairArgs{
				KeyName:   pulumi.String(environment + "-key-pair-" + kp.Name),
				PublicKey: pulumi.String("ssh-rsa key"),
				Tags:      tags,
			})
			pairResources[pulumi.String(kp.Name)] = KeyPairExport{
				KeyName: nkp.KeyName,
				Id:      nkp.KeyPairId,
			}

		}

		ctx.Export("key-pairs", pairResources)
I get the error:
Copy code
./main.go:65:27: cannot use pairResources (variable of type map[pulumi.String]KeyPairExport) as pulumi.Input value in argument to ctx.Export: map[pulumi.String]KeyPairExport does not implement pulumi.Input (missing method ElementType)
f

fierce-ability-58936

08/02/2023, 12:01 AM
That's because
map
is not an
pulumi.Input
Also since you've got the keys of the map as strings why don't just use
string
? Then to iterate over it after using
pulumi.Map
for the type and
string
for the key I get
Copy code
util.go:110:28: cannot use KeyPairExport{…} (value of type KeyPairExport) as pulumi.Input value in assignment: KeyPairExport does not implement pulumi.Input (missing method ElementType)
As
KeyPairExport
again is not an
Input
, so maybe marshalling to json is acceptable? Not sure about a better way
Copy code
type KeyPairExport struct {
		KeyName pulumi.StringOutput `pulumi:"key_name"`
		Id      pulumi.StringOutput `pulumi:"id"`
	}

	pairResources := pulumi.Map{}
	for _, kp := range keyPairs {
		nkp, _ := ec2.NewKeyPair(ctx, kp.Name, &ec2.KeyPairArgs{
			KeyName:   pulumi.String(environment + "-key-pair-" + kp.Name),
			PublicKey: pulumi.String("ssh-rsa key"),
		})
		pairResources[kp.Name] = pulumi.JSONMarshal(KeyPairExport{
			KeyName: nkp.KeyName,
			Id:      nkp.KeyPairId,
		})

	}

	ctx.Export("key-pairs", pairResources)
at least this compiles.
c

clever-kite-79772

08/02/2023, 8:11 AM
Thank you very much. I'll try it.
Unfortunately, it doesn't work:
Copy code
error: an unhandled error occurred: program failed:
waiting for RPCs: json: error calling MarshalJSON for type pulumi.StringOutput: Outputs can not be marshaled to JSON
The error happens in this line:
Copy code
ctx.Export("key-pairs", pairResources)
If I comment it - everything works.
f

fierce-ability-58936

08/02/2023, 9:19 PM
Well, true that, it even says so in the doc
The Pulumi Go SDK does not currently support serializing or deserializing maps with unknown values.
How about
Copy code
pairResources[kp.Name] = pulumi.Sprintf("%s:%s", nkp.KeyName, nkp.KeyPairId)
?
c

clever-kite-79772

08/02/2023, 10:43 PM
In this case I have string instead of map. I'd like to keep map to properly process resources with StackReference.
I have this solution now:
Copy code
pairResources[kp.Name] = pulumi.All(nkp.KeyName, nkp.KeyPairId).ApplyT(func(v []any) KeyPairExport {
				return KeyPairExport{
					KeyName: v[0].(string),
					Id:      v[1].(string),
				}
			})
But not sure if it's a good solution..
f

fierce-ability-58936

08/02/2023, 10:44 PM
But I see what you're trying to do, sorry might not fit into your use case but why not use https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Connect-using-EC2-Instance-Connect.html? (and https://github.com/springload/aws-ssh to simplify connecting). So that ssh problem totally goes away 🙂
c

clever-kite-79772

08/02/2023, 10:46 PM
It doesn't help a lot as key-pair is just an example - I have for example EKS cluster with many worker nodes divided by labels - they need specific configuration. But thank you very much the links - it could be very useful anyway 🙂
If someone will be interested in the solution - I fixed it with this code:
Copy code
pairResources := pulumi.StringMapMap{}
		for _, kp := range keyPairs {
			nkp, _ := ec2.NewKeyPair(ctx, kp.Name, &ec2.KeyPairArgs{
				KeyName:   pulumi.String(environment + "-key-pair-" + kp.Name),
				PublicKey: pulumi.String(kp.PublicKey),
				Tags:      tags,
			})

			pairResources[kp.Name] = pulumi.StringMap{
				"key_name":    nkp.KeyName,
				"key_pair_id": nkp.KeyPairId,
			}
		}
		ctx.Export("key-pairs", pairResources)
The main idea - the correct datatype is
StringMapMap