Are there any patterns for creating Pulumi resourc...
# general
f
Are there any patterns for creating Pulumi resource names based on output values? I suspect the answer is "No; don't do that"... we've got a project that we'd like to drive with stack outputs from another project, but aren't really able to create resources in the second stack that have meaningful names, since that information is technically an output from the stack reference. For now, we're just auto-generating resource names (e.g.
resource-{i}
, where
i
is just a counter), but I was curious if others had any guidance to provide here. Thanks!
l
"No; don't do that". I frequently wrap resources in thin objects that contain their name, in order to work around this. So if I have an array of (for example) policies that I want to attach to an array of roles, but the policies are created / managed elsewhere, then I'll pass around something like a PolicyInfo object that looks like
{ name: string; policy: aws.iam.Policy }
.
r
so to be clear here we're consuming a stack reference to another stack where resources are created, then creating "derivative" resources from the stack outputs of the other stack. Concretely, we're creating a Confluent Cloud API key, service account, and Kafka cluster in the "other" stack and then creating a Kafka topic and Kafka ACL in the "main" stack, consuming the API credentials and Kafka cluster bootstrap server URL via the stack reference. In particular, I'd like to be able to name the ACLs such that it's clear which service account they belong to, e.g.:
Copy code
for topic in topics:
        kafka.Acl(
            f"{topic.name}-{service_account_id}-{'write' if write else 'read'}-acl",
        ....  
        )
the
kafka.Acl
name must be a reified
str
, so I'd like to consume the
Output[T]
from the stack reference into a
str
(the particular value of concern here is
service_account_id
). Does that make sense?
There shouldn't be any actual pulumi execution graph issues here, as the values are definitely created by the time this "main" stack is run, it's just a matter of mechanically how can I consume an
Output[T]
and get a reified
T
?
l
Unfortunately there is an execution graph issue here, as stack references are not known to be resolved at the time they are requested. You know that they are, but Pulumi may have to wait for the other stack to finish upping, or wait for the values to come back from a remote backend. It's all asynchronous and can fail, so an Output is required.
Since you know the name of the stack, and the resources in the stack, can you use that knowledge to provide a fixed string value in the main stack?
You can create the resources inside an
apply()
, but that should be seen as a last option. Any other solution, including hardcoding, should be considered preferable.
r
hardcoding would be problematic because we'd have to know to change things in two places, the goal is to "drive" the main stack via the other stack
what's the issue with creating a resource inside an
.apply()
? I was under the impression that it wasn't even possible... if it is possible why is it bad?
l
Can you inject the configuration / name into both projects from one place?
r
that's a good idea, possibly
another thing I was thinking of is using an out-of-band system (e.g. Vault) instead of a stack output
l
It does work, you can safely do it. The problem is that
apply()
does not run during a preview. So previews will show that the resources will be deleted, and up will not delete them.
r
😬 yikes lol
ok, I see now
thanks :)
👍 1
l
Values retrieved via pulumi.Config are not Outputs, so if you can use that, problem solved?
r
hmmm, yeah that sounds like a promising approach
thanks a lot!
l
You need to use
require
not
get
, since
get
returns a Promise.
r
yeah, that's totally cool here though, I definitely want it to fail if the value is not present
👍 1
f
Thanks @little-cartoon-10569!
👍 1