docs
docs copied to clipboard
Add back in information about creating resources in `apply`
Problem description
We used to include a note that when you created resources in an apply() there resource outputs were unknown so there may be side-effects:
(from https://web.archive.org/web/20240127231146/https://www.pulumi.com/docs/concepts/inputs-outputs/)
It seems to have gone missing
Double-check my info here, but:
- I believe
applywill run in preview if the unknowns are satisfied. - I am certain that in some circumstances, creating resources in an
applyis unavoidable (e.g. adding routes to every route table in the AWSX VPC). This typically happens when needing to iterate over types likepulumi.Output<string[]>because the length of the list cannot be known until the resources are provisioned.
Here's a first draft of the content. Feedback welcome.
Note that the code in an
applywill not run duringpulumi previewunless all dependent values are known. This means that you should avoid creating Pulumi resources in anapplywhenever possible because when resources are created withinapply, thepulumi previewoutput may not necessarily match the actual actions taken duringpulumi apply.There are some edge cases where creating resources in
applyis necessary. The most common case for creating resources inapplyis when you need to iterate over a list output type, e.g.,pulumi.Output<string[]>, for example adding a tag to every public subnet in theawsx.ec2.Vpccomponent. In this case, the length of the list of strings cannot be determined until the VPC component has been provisioned because the number of public subnets in the VPC is variable and based on a variable length input (the list of availability zones).
@thoward to look into this and determine what's accurate vs what we've published.
For my use case described above, the length of the list must truly be unknown. If you're creating an AWSX VPC, and you already know you will have 3 AZs, you can just do something like:
const vpc = new awsx.ec2.Vpc("my-vpc");
const subnetId1 = vpc.publicSubnetIds.apply(ids => id[0]);
const subnetId2 = vpc.publicSubnetIds.apply(ids => id[1]);
const subnetId3 = vpc.publicSubnetIds.apply(ids => id[2]);
[subnetId1, subnetId2, subnetId3].forEach(id => {
// add some routes to a routing table, etc
});
This would obviate the need to create resources in an apply.