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

wide-crayon-4093

09/07/2021, 5:51 AM
hey everyone, I've been trying to grasp the ApplyT cause I'm loosing the current scope trying to do this:
Copy code
pgaConfig := cluster.pgaPassword.Result.ApplyT(func(pgaPassword string) string {
  println(fmt.Sprintf("%v", cluster.cfg.Databases))
  return cluster.preparePgaConfig(pgaCfg.ApiKey, pgaPassword)
}).(pulumi.StringOutput)
if I have many 'cluster' resources, e.g iterating over an array of clusters and generating resources, then inside ApplyT
preparePgaConfig
is called on the last cluster, not each. How do I pass the 'context' in there?
b

bored-table-20691

09/07/2021, 6:08 AM
Can you share a bit more of your code? I feel you’re running into a typical go issue around closing over a loop variable
w

wide-crayon-4093

09/07/2021, 6:25 AM
here's an example that would make sense:
Copy code
func SetupPostgres(ctx *pulumi.Context, args *DataArgs, opts ...pulumi.ResourceOption) error {
  var postgresCfg ConfigPostgres
  config.New(ctx, "data").RequireObject("postgres", &postgresCfg)

  for _, instanceCfg := range postgresCfg.Instances {
    err := setupPostgresInstance(ctx, &instanceCfg, args, opts...)
    if err != nil {
      return err
    }
  }

  return nil
}

func setupPostgresInstance(
  ctx *pulumi.Context, cfg *ConfigPostgresInstance, args *DataArgs, opts ...pulumi.ResourceOption,
) error {
  instance := &PostgresInstance{
    Name:         cfg.Name,
    InstanceName: fmt.Sprintf("postgres-%s", cfg.Name),
  }

  instance.pgaPasswordName = fmt.Sprintf("%s-pga", instance.InstanceName)
  instance.pgaPassword, err = random.NewRandomPassword(ctx, instance.pgaPasswordName, &random.RandomPasswordArgs{
    Length:  <http://pulumi.Int|pulumi.Int>(24),
    Special: pulumi.Bool(false),
  }, opts...)
  if err != nil {
    return err
  }

  pgaConfig := instance.pgaPassword.Result.ApplyT(func(pgaPassword string) string {
    // instance here is the last element, not the current
    return instance.preparePgaConfig(pgaCfg.ApiKey, pgaPassword)
  }).(pulumi.StringOutput)

  return nil
}
i have a suspicion that i shouldn't be using pointers
b

bored-table-20691

09/07/2021, 6:36 AM
I believe so - you’re passing a reference to the loop variable itself, so it will change every time the loop iteration will change. The
ApplyT
callback function will not be invoked until it’s ready, and at that point, you’re referring to the last iteration of the loop most likely
w

wide-crayon-4093

09/07/2021, 6:37 AM
thanks, I'll try to rewrite it to avoid pointers
ta-da, not passing the pointer into the loop helped solving it. thank you! 💃
4 Views