Am I missing something (obvious?) or how can you s...
# general
c
Am I missing something (obvious?) or how can you sort a list of resources based on a Output<> property?
const sortedCerts = listOfCertificates.sort((a, b) => pulumi.all([a.domainName, b.domainName]).apply(([aName, bName]) => aName.localeCompare(bName)) );
Type 'OutputInstance<number>' is not assignable to type 'number'.
l
You can't sort now on a value that won't be known until after resources are deployed. You could sort the list inside an apply and return it as an Output<List> or whatever.
c
🤔 the sort is happening inside
apply()
though..
l
No, the decision that future-A is before or after future-B is happening in the apply(). You call sort() outside of the apply. It can't work.
The order cannot be known until the values you're ordering on are known. And they won't be known until after the deployment finishes. Your code finishes before the deployment starts.
Your Pulumi program, excluding the apply()s, is run to completion before the Pulumi engine starts deploying stuff. (Actually, I think it's more complicated than that, and stuff happens in parallel.. but it's safer to think about it this way!)
c
Resource X can use Resource Cs Output as an Input, so.. clearly pulumi is able to marshal the promises in order to allow this.
l
It's not happening at resource-construction time. Those values are kept as future values and not resolved until the engine is running.
They're not available outside of the engine. If you want your code to run inside of the engine, it has to be in an apply().
c
so in this context, where the Resource ( aws.acm.Certificate ) has multiple Outputs I need to consider ( .domainName and .arn ) its simply impossible to interact with both properties, since they need to be applied separately I guess.
l
No, you can interact with them. You just can't use values at resource-creation time that aren't available until resource-deployment time.
You can apply both values at the same time. But the code you run that has access to both (non-future) values runs after your Pulumi program finishes, and during the time that the engine is deploying your desired state.
Pulumi builds the graph of resources first: this is the "top level" of your runtime. Then, when the graph is fully built, it starts deploying the resources in whatever order it has worked out. During this phase, your callbacks (the apply()s) are run. This code has access to those future values.
This is why you can't use an Output as the first parameter to a resource constructor: you wouldn't be able to build the graph of resources until after the resource-deploy phase had started. but it doesn't start until after the graph of resources is built. Catch 22.
c
I'd have to see an example of this to understand I think.. using
pulumi.all
to resolve multiple properties and pass to apply I get, but not when dealing with a collection of resources. At any rate, thanks for your help and advice - I will just do this in boto3 instead, so much easier!
l
The problem isn't the collection of resources: it's that you're sorting on Outputs, which aren't ordered. You're trying to sort on the applied values, which are ordered (they're numbers). You could apply all the values of the collection, and create a new output containing a sorted collection. But it's not worth it. Just sort later, or don't sort at all!
c
the resource (ALB) that needs a list of certificates requires a specific sorting as it treats the first ARN differently...
l
Then you create the first certificate, and then all the other certificates. Is this to handle Subject Alternative Names? This is a recurring problem.
Don't put the main domain name in a collection at creation time. Just to that when you're creating the ALB.
c
SNI but yeah, its an annoying side-effect of how AWS treats attached certs
l
Yep. I've solved the same problem. Just keep the one that has to be first, separate. Then you can put it in the right place.
c
thanks again