Hey, all. :wave: I'm somewhat new to Pulumi, and ...
# automation-api
g
Hey, all. 👋 I'm somewhat new to Pulumi, and doing my first real work with the automation API in Go. I have two apps, one that creates resources in a stack, and another that uses the same stack to modify the resources. Ideally, I'd like to use an inline function in both cases. What I can't figure out is how to ensure I make just the modification I want, without deleting the resources already in the stack. With the CLI, I gather you'd run an import (maybe?), but the import functions in the API seem not to affect the inline function (which makes sense to me). Looking up each resource in the second app's inline function does work, but it's slow and cumbersome. Is there a better way that I'm missing?
l
What are you putting into the 2nd project's code? You should be leaving all the resources in there, all the time. You don't put just the changes you want in there: that is what causes all the other resources to be deleted.
g
Thanks! That much I'm pretty clear on. What I'm coding is kind of a handoff: one system programmatically creates infrastructure, and another (run by a different user with access to the .pulumi directory on cloud storage) makes modifications.
But the code creates unique IDs for the objects (to avoid conflicts at the provider level), so if I copy the code verbatim, I get different objects.
I suppose it might be faster to look up those IDs and then run the code over again. I'll look at that. But it would be ideal to be able to look at the existing stack programmatically and say, "I want a resource representing this already-created object". And the API makes it seem like I should be able to do that. But if that's an anti-pattern, that would also be helpful to know.
l
Stacks aren't per-user (normally). The best thing to do is for both users to use the same stack. No handover.
g
I think maybe I haven't been clear. I'm only using one stack. The app that creates the stack populates it with a set of resources that can be claimed and modified by users of the second app.
FWIW, I've realized that for my use case, a library that can recreate those resources exactly in both apps has a lot of advantages. But I'm curious if producing inline code objects from existing stack resources is possible. It could be useful down the road to be able to read and modify the contents of a stack using an inline function, if the modifying code isn't already somehow aware of every single thing in the stack.
(Thanks for bearing with me on this.)
l
I don't understand why two records of a single resource is needed.
g
I'm not trying to make two records in the stack.
The inline function starts from scratch. So if I run Up() with an empty function, everything existing in the stack is deleted. If I only want to (say) create a single resource in the stack, I need a way to get the other resources that are already there represented in the function, so they aren't deleted.
l
If you run Up on code that has already been upped, then you're not starting from scratch. The existing resoruces exist, and the new Up will be modifying them. If you are starting from scratch (and therefore, stuff is being created in duplicate), then you have a problem with the way your state is being managed.
I'm definitely missing something. Is anything special happening with the source code? Are both users using the same source code, the same state file, and the same credentials?
g
I think that's the confusion. They're using different source code, but the same state file and credentials.
l
Then you need to change the way you're working. There is a 1:1 relationship between source code and state file. Two different source code files cannot use the same state.
A resource is either managed or not managed. It cannot be doubly-managed.
You could remove resources from one state then import them to another, but why? Why not just hand the state over? That's the intention of state.
g
That's what I'm doing.
But the source code isn't static.
l
That's your problem.
g
This isn't like with normal Pulumi, where I have my code in a directory with my yaml files, and it doesn't change.
l
Since you're changing the code, you must change the state. You cannot hand the existing state over without also handing the code over. The problem, unfortunately, is your business process.
g
I do understand that.
I'm not confused about why I'm having trouble.
Sorry this is so complicated. 🙂
l
The technical solution isn't complicated, I don't think. It's just different from your original intention
Instead of creating the resources in devA's code, then asking devB to adopt them, you should just give devA's code to devB. The idea of creating the resources in one place and managing them in another is not something that's built into Pulumi.
g
Unfortunately, that solution only works if the code is static. As soon as the code is doing something like generating a unique ID, the second run doesn't produce the same resources as the first.
But I know that Pulumi can import resources that it doesn't manage, and start managing them. I think that's all I'm talking about doing— but I have the state, which seems like it should be an advantage. But it sounds like Pulumi doesn't have a way to use that: I'd have to import the resources as if they were unmanaged. Do I have that right?
l
You could create a new stack, export it and the original stack, and carefully move bits of JSON from one file to the other. You'd need to change some provider URNs probably. It'd be tricky. Honestly, if you're generating code, then it should be easy to generate the pulumi import commands at the same time. However there is another alternative: since you're creating unique IDs per target user, then I think you should consider creating a target stack for that user too. And then just handing that stack over. You don't need to use the same stack every time you run the code: you can tweak your devA code to change the stack name each time you're starting from scratch.
Even better, if you do that, you could use a non-inline Pulumi project called from your automation-api app. Then you could just copy that project file to the target user. Then they'd have the (non-automation-api) Pulumi project, the standalone stack, and no need to import and remove anything to or from a state.
Plus, that's the way that non-inline projects are intended to be used, so if you need help here on the Slack, the answerers will have a better understanding of your situation.
g
Hmm. That idea of a non-automation-API stack to start with is an interesting one. It would definitely work for my use-case. Thanks again for all the time you spent on this! I appreciate it.
l
You can use an automation-api program to run a non-inline project. The project is separate from automation-api. Automation-api provides a convenience feature that allows you to put the project code directly into the automation-api program, but this isn't required (and, in my opinion, is a conflation of ideas that runs the risk of confusing people reading the code). Keeping the two things separate is a good idea in many (all?) cases.