pulumi / docs

All things Pulumi docs!
https://pulumi.com
Apache License 2.0
128 stars 221 forks source link

Add back in information about creating resources in `apply` #12459

Open pierskarsenbarg opened 3 months ago

pierskarsenbarg commented 3 months ago

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:

Image

(from https://web.archive.org/web/20240127231146/https://www.pulumi.com/docs/concepts/inputs-outputs/)

It seems to have gone missing

jkodroff commented 3 months ago

Double-check my info here, but:

  1. I believe apply will run in preview if the unknowns are satisfied.
  2. I am certain that in some circumstances, creating resources in an apply is unavoidable (e.g. adding routes to every route table in the AWSX VPC). This typically happens when needing to iterate over types like pulumi.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 apply will not run during pulumi preview unless all dependent values are known. This means that you should avoid creating Pulumi resources in an apply whenever possible because when resources are created within apply, the pulumi preview output may not necessarily match the actual actions taken during pulumi apply.

There are some edge cases where creating resources in apply is necessary. The most common case for creating resources in apply is 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 the awsx.ec2.Vpc component. 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 commented 3 days ago

@thoward to look into this and determine what's accurate vs what we've published.

jkodroff commented 2 days ago

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.