Is creating resources inside an apply block accept...
# general
r
Is creating resources inside an apply block acceptable? I did not think it was recommended, but I see it in an example in the docs here: https://www.pulumi.com/registry/packages/aws/api-docs/acm/certificatevalidation/
b
It will work but resources declared within an apply block won't show up in your preview if it requires provisioning, because that apply block can't be executed until those values are known. So your preview will now be inconsistent, which is why it isn't recommended.
The example you linked doesn't have any resources declared within an apply though I don't think, unless I'm missing something. It looks like the apply gets closed before the
.map(...)
call where the resources are declared.
r
Oh interesting, you're right. That example seems to call
Object.entries
on a
pulumi.Output
type if I'm understanding it correctly. Wouldn't that have the same effect?
b
Hmm I'm not sure, that function is kind of hard to follow as it is written out without being in the IDE looking at it. It would be easy enough to test though, just declare a cert and use that example in a new Pulumi project and then run a preview and see what shows up. It stands to reason that Pulumi would not be able to infer how many SANs are on your cert at preview execution so it can't know how many validation options there will be, so if your method of declaring certificate validations is iterating through the validation options than there isn't a way to do it in such a way that Pulumi is aware of those declarations during preview. But if you as the developer know how many SANs you are putting on your cert, meaning it isn't a dynamic amount, then you also know how many validation options there will be. So you could do:
Copy code
var option1 = exampleCert.domainValidationOptions.apply(options => options[0]);
// declare first dns record
var option2 = exampleCert.domainValidationOptions.apply(options => options[1]);
// declare second dns record
Obviously that means if your cert's SAN count changes than you'd have to update the code, but if your preview being consistent is important to you it is an option.
e
We are thinking about how to handle dynamic number of resources better, but @bored-oyster-3147 comments are accurate as of now. I'd just point out that your last snippet can still put each of those options in an array rather than separate variables something like:
Copy code
var options = new Option[4];
for i in 0 to 4 do:
  options[i] = exampleCert.domainValidationOptions.apply(options => options[i]);
The array and loop aren't the problem, it's the unknown size that's tricky. In fact we could probably write a helper to do this for you, given an Output<T[]> and an expected size return an Output<T>[] of that size and throw an error if at update time the size didn't match. Raise a github issue if that sounds worthwhile.
🙌 1