https://pulumi.com logo
Title
e

early-plastic-49211

11/11/2022, 1:37 PM
Sometimes, I need to "resolve" Inputs / Outputs with Apply to do some checks that do not actually require me to return another value based on those Inputs / Outputs (like
x.Apply(x => $"https://{x}")
). Right now, to do this, I do something like the following, but it feels wrong. Is there a better way to do that?
Input<string> variableToResolve; // Just to show you the type, let's assume there's a value

_ = variableToResolve.Apply(x =>
{
  methodRequiringValueAsString(x);
  return true; // This feels hacky
});
Also, let's say I wanted to verify what the value of
x
is, would it be valid to throw an exception inside the Apply block?
e

echoing-dinner-19531

11/11/2022, 4:07 PM
You could just throw an exception. We track every apply that's started and wait for all of them to finish before we call a program complete so we should pick up the exception. It is a bit odd though. What sort of things are those methods doing? If its just validation before passing on to other inputs I'd probably recommend doing it more like:
outputX = outputX.Apply(x => validateX(x); return x)
Such that anything using this value will only see it if it's been validated.
e

early-plastic-49211

11/11/2022, 4:19 PM
It does seem odd, but I don't see how else I can do it. The goal is to have classes that can reuse some logic, so the validation is done at the initialization of said class like that (on resource tags for example):
_ = args.Tags.Apply(t =>
{
  if (t["tier"] == "prod")
  {
    Common.ValidateTags(t);
  }

  return true;
});
Where an exception is thrown if the validation fails. Another use case that feels hacky is if I have to wait for a resource to be created, I literally discard the value:
_ = privateZone.Id.Apply(_ =>
{
  CreatePrivateEndpoint();
  return true;
});
Inside CreatePrivateEndpoint, I use "GetPrivateZone" which uses parameters from another part of the code (which doesn't use Inputs). This is to make the method more flexible (it supports private zones created from Pulumi and from the web console).
e

echoing-dinner-19531

11/11/2022, 4:32 PM
So why isn't that first one more like:
args.Tags = args.Tags.Apply(t =>
{
  if (t["tier"] == "prod")
  {
    Common.ValidateTags(t);
  }

  return t;
});
? The second one, you might want to look at the dependsOn resource option. Lets you delay the creation of other resources until one has resolved.
e

early-plastic-49211

11/11/2022, 4:34 PM
Oh wow, this does seem so much better. For the DependsOn option, it's a good idea too, I'll check if I can refactor the classes I've made to use that instead. Thanks a lot!