Also, I can see how to make the creation of a drop...
# getting-started
h
Also, I can see how to make the creation of a droplet depend on the creation of a bucket — what I can’t see is how to block until the bucket is created before writing my user data from a template file for that droplet. If the user data file itself were a Pulumi resource, then it could depend on the bucket’s creation, and the droplet could depend on that, but I don’t see any generic file provider, and I’m not sure how to use the cloud-init provider in this case. Am I missing something conceptual?
A simple script that creates a bucket, prints the bucket_domain_name, then exports the bucket_domain_name gives me as output <pulumi.output.Output object at 0x1075f18e0> for the print during the pulumi up and “blah-12345.nyc3.digitaloceanspaces.com” for the exported variable. What I want to do in my Python script is block until the output is the actual name, and nothing in the inputs-and-outputs docs explains how to do that, at least in a way that makes sense to me haha.
a
I’m very new to pulumi, but isn’t this what
apply
is for?
I don’t think testing it with print will work, because the return value of the apply is still an output, but I think it should cause pulumi up to wait for the bucket domain name to become available before doing anything that makes use of the new output
l
There's the cloud-init provider that might be useful? https://www.pulumi.com/registry/packages/cloudinit/api-docs/getconfig/
getConfig()
creates user data, and it can depend on other resources.
h
I thought that was what
apply
was for as well, but when I tried, it didn’t seem to matter. 😞
There’s also a PR and some comments in the documentation that you shouldn’t need
apply
if you’re getting one object’s internals for another.
l
Yes, you shouldn't need to. Also, you should try to avoid creating anything in an
apply
, it causes side effects.
What I want to do in my Python script is block until the output is the actual name
This isn't quite correct. Possibly you can do this (I don't know how Python's asynchronous support works), but you probably shouldn't. Instead, you can either 1. do you printing inside the apply, which can be useful in debugging circumstances, or 2. export the value from the stack, and Pulumi will print it for you whenever it changes (or whenever you ask it to).
h
It’s what I want, though it may not be the right thing to do.
Exporting from the stack doesn’t help, unless I have two separate stacks, one for the bucket and one for the droplet.
I can’t share the code, but my user data includes a reference to the bucket’s short name. I need that short name to create the user data, I need the user data to create the droplet.
l
If you want to build a droplet with an input value that is an output value from the bucket, you don't need to get any output value from the bucket as a string. Instead, you pass the output value directly to the constructor of the droplet.
h
I confess I believe you are incorrect.
l
If you want to use the name inside another string, then you build the string in apply, and pass the resulting output to the droplet.
Not the string.
h
Again, you are incorrect
What I need is the name of the bucket as a string
Because my user data is generated from a template
And that template has a spot in it for the bucket’s name again as a string
l
The typescript equivalent would be
Copy code
const userdata = bucket.bucket.apply(bucketName => `Your big string includes ${bucketName}`);
h
The template also has twelve other variables
l
Then you need to use the Python equivalent of
pulumi.all()
.
h
The twelve other variables are all strings
Not objects
l
Then my example code is correct.
Copy code
const val1 = "X";
const val2 = "Y";
const userdata = bucket.bucket.apply(bucketName => `Your big string includes ${bucketName} and ${val1} and ${val2}`);
The point it,
userdata
is an output not a string, and you pass it to your resource constructor. You don't pass a string to it.
h
Give me a second
The droplet’s user_data argument can actually be an Output ?
l
I don't know that resource. Let me check.
But in general, all constructor args are Inputs, which are unions of Outputs and base types (in this case, string).
h
I have to go, but I will follow this path further later tonight
👍 1
l
Yes, seems to be fine. The Typescript is fine. Unforatuntely the API docs always leave out the "Input" bit because it's assumed, but that means that I'm never sure if there's a bug for that one field....
h
Thank you for the breakthrough
Have to go
https://www.pulumi.com/registry/packages/cloudinit/api-docs/getconfig/#filename_python sigh, the cloud-init stuff appears to need a filename to read off the filesystem. I don’t think this can be tricked into being replaced with an output — unless there’s a plain file provider hiding out somewhere.
no wait, my bad, that’s not technically correct
filename is just to be attached in the MIME stuff, it’s content I need to fold/spindle/mutilate
Okay, that’s strange — the cloud-init object is created, and exported correctly, but not included in the resources that are created and destroyed.
The good news is that @little-cartoon-10569 was completely correct: I was able to embed the correct bucket name into the user data and have that user data attached to the droplet. The bad news is that the user data’s not being respected, most likely due to the multipart MIME bit, but that’s something I can discuss with DigitalOcean. Thank you again for your patience, and now I’m confident I can get this to work.
👍 1