https://pulumi.com logo
Title
r

refined-pilot-45584

12/27/2022, 9:57 AM
Hey All, Is there an easy way to Append a pulumi.String(“Hello”) object to a Pulumi.StringArray object. I am trying implement something like this…
var denyPorts pulumi.StringArray
for _, denyPort := range local.DenyPorts {
	append(denyPorts, pulumi.String(denyPort))
}
I basically receive the following error:
append(denyPorts, pulumi.String(denyPort)) (value of type pulumi.StringArray) is not used
I assume there must be a way to combine pulumi.String and pulumi.StringArray If not what would be the suggested approach? Is there a different way to convert a []string object in go to pulumi.StringArray? Thanks in advance.
s

salmon-account-74572

12/29/2022, 5:01 PM
Disclaimer: I’m not a Golang expert. Maybe try defining
denyPorts
as a standard string array (
[]string
),
append
your items to it, and then reference it in the resource declaration as
pulumi.StringArray(denyPorts)
(or similar, might need to tweak the syntax there with braces instead).
r

refined-pilot-45584

12/29/2022, 6:12 PM
I will have a crack at this tomorrow for sure and report back.
Hey @salmon-account-74572 I think this approach may have worked. However I get stuck with the concepts of how to handle appending to a Specific Pulumi Array Type … For Example. A Golang Object of Type: compute.FirewallAllowArray{} and it takes a type of compute.FirewallAllowArgs{} as it’s nested object. So ideally Go Slice Native Declaration: [FirewallAllowArgs]FirewallAllowArray… I don’t know how to append a “FirewallAllowArgs” object to a “FirewallAllowArray” object. Specifically I am trying to do this:
// Create Pulumi Firewall Array Object
fwAllowArray := compute.FirewallAllowArray{}
// Create Multiple Pului Array Argument Object (Dynamic Allow Rules)
for _, rule := range MyRules {
   fwAllowArgs := compute.FirewallAllowArgs{
       Protocol: pulumi.String(rule.Protocol),
       Ports: pulumi.ToStringArray(rule.Ports) 
   }
   append(fwAllowArray, fwAllowArgs) <---- ERROR HERE *
}


* This bit Doesn't Work, I understand why cause its not a Native Slice and Append isn't understanding the underlying struct, BUT HOW does one dynamically add ArgsStrcuts to ArrayStructs with Go in Pulumi....? understanding this would really unlock me as it is a pattern is see time and time again with Array & ArrayArgs objects in Pulumi.
s

salmon-account-74572

01/03/2023, 2:12 PM
Let me ping some folks internally and see if someone more well-versed in the Go SDK can weigh in on this.
r

refined-pilot-45584

01/03/2023, 2:35 PM
Thanks so much would appreciate this;
s

salmon-account-74572

01/03/2023, 3:02 PM
One of the engineers gave me this code:
func Append(ctx context.Context, arr StringArrayInput, str StringInput) StringArrayOutput {
	return AllWithContext(ctx, arr, str).ApplyTWithContext(ctx, func(ctx context.Context, vars []interface{}) []string {
		arr := vars[0].([]string)
		str := vars[1].(string)
		return append(arr, str)
	}).(StringArrayOutput)
}
That doesn’t directly address the
FirewallAllowArray
portion of your question, I don’t think, but it might unlock a pattern that would work there. Personally, I need to study it a bit more to fully grok it. 🙂
e

echoing-dinner-19531

01/03/2023, 3:03 PM
I've just raised https://github.com/pulumi/pulumi/issues/11756 to track that we should support this better
s

salmon-account-74572

01/03/2023, 3:05 PM
Thanks @echoing-dinner-19531! (Both for creating the issue and for supplying the code snippet above!)
r

refined-pilot-45584

01/03/2023, 3:38 PM
Thanks @echoing-dinner-19531 appreciate this; I myself and @adventurous-apartment-93389 been looking to build out some serious GCP patterns and (with Bias) we chose Go as the first stop and this has been a big sticking point for us the last few days. I think i would be awesome to get this one patched across any ArrayBased Object.
Am I right in thinking though the the explicit use of
AppendWithContext
is the current way forward?
e

echoing-dinner-19531

01/03/2023, 3:48 PM
We normally have X and XWithContext methods in the Go SDK for anything that internally is an Apply. The fun with this will be Go doesn't actually have method overloads, so these will probably have to be on the type itself somehow. So not totally sure what we would do here, but the method implementation itself is sound you can copy paste that for now.
w

white-balloon-205

01/03/2023, 5:27 PM
FWIW - I think the answer to the original question is simpler. In Go, append is used like
arr = append(arr, item)
, and doing so in your example above should work like you expect:
fwAllowArray := compute.FirewallAllowArray{}
        for _, rule := range MyRules {
			fwAllowArgs := compute.FirewallAllowArgs{
				Protocol: pulumi.String(rule.Protocol),
				Ports:    pulumi.ToStringArray(rule.Ports),
			}
			fwAllowArray = append(fwAllowArray, fwAllowArgs)
		}
Here's a complete example:
package main

import (
	"<http://github.com/pulumi/pulumi-gcp/sdk/v6/go/gcp/compute|github.com/pulumi/pulumi-gcp/sdk/v6/go/gcp/compute>"
	"<http://github.com/pulumi/pulumi/sdk/v3/go/pulumi|github.com/pulumi/pulumi/sdk/v3/go/pulumi>"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		MyRules := []struct {
			Protocol string
			Ports    []string
		}{
			{"tcp", []string{"80", "443"}},
			{"udp", []string{"53"}},
		}
		network, err := compute.NewNetwork(ctx, "my-network", &compute.NetworkArgs{})
		if err != nil {
			return err
		}

		// Firewall
		var fwAllowArray compute.FirewallAllowArray
		for _, rule := range MyRules {
			fwAllowArray = append(fwAllowArray, compute.FirewallAllowArgs{
				Protocol: pulumi.String(rule.Protocol),
				Ports:    pulumi.ToStringArray(rule.Ports),
			})
		}

		firewall, err := compute.NewFirewall(ctx, "fw-allow-http-https-udp53", &compute.FirewallArgs{
			Network:      network.ID(),
			Allows:       fwAllowArray,
			SourceRanges: pulumi.StringArray{},
		})
		if err != nil {
			return err
		}

		ctx.Export("id", firewall.ID())
		return nil
	})

}
r

refined-pilot-45584

01/04/2023, 3:14 PM
Hey Gents (@salmon-account-74572, @echoing-dinner-19531 & @white-balloon-205). Firstly I want to say thanks for the collaboration. Really found it helpful on both closing my knowledge gap and building out some of our content. Been diving into the example and details. I have reworked the example into my overall solution and yep, it does work. 100% So thanks very much; I think where I got tied up is trying to find the balance between using Pulumi specific functions and types vs go native programming structures and functions. Thanks again for your help. If I find more elements like this I will certainly be asking about them cause I am trying to build out some very detailed Google Architectures which might be mutually beneficial going forward.
s

salmon-account-74572

01/04/2023, 4:14 PM
Happy to help, Tim! (Not that I was much help, except in bringing in the right folks!) Let us know how we can help further, happy to continue to collaborate.