one-shot action during pulumi stack initialization...
# general
one-shot action during pulumi stack initialization? I run a pulumi stack that manages resources on k8s. Upon creation of the stack I need a one-shot action (populate the database) Once this action is performed for a stack and until "pulumi destroy" it should never run again. Utilizing a k8s JOB for it is not quite the thing, because should the job spec (accidentally) update - "pulumi up" would rerun the job, leading to a disaster (database inadvertently reset) I could arrange a "workaround?" - make the program run conditionallly. Run the program twice with different flags 1. first run just creates a k8s job that populates the database (this type of program run is performed only once) 2. the second run (and all consequent runs) deletes the job (by not creating it's resource during the program run) and creates all other resources of the stack But maybe pulumi has some idiomatic way of doing this kind of thing?
Two approaches I think could work: 1. Use Pulumi automation -- you write a separate program that calls your one-off step when a flag is passed, and then runs your Pulumi stack, passing any necessary data from the one-off step as necessary. 2. Write a custom resource that e.g. uses Pulumi's
resources to run arbitrary commands. To prevent the disaster scenario, you could opt not to provide the
command (so that deleting the resource is a no-op -- requires manual clean-up from you), mark the resource as
protect: true
so that it's harder to delete it accidentally, or some combination of the two. Disclaimer: while I've used both Pulumi automation and protected resources, I might be a missing a case where these might not offer the kind of guarantees you are looking for!
there's 3: write a small dynamic provider.
Command or a dynamic provider is probably the best way to do this today. I do have a plan to add a builtin resource to handle these sorts of cases, but it needs some function callback groundwork in place in the engine first which should be coming soon.
@numerous-energy-27817 I wonder if you ever worked out a satisfactory solution? It occurred to me that one might use a flag in pulumi ESC environment for this. I can't remember if pulumi has a way of updating (rather than just reading) values in ESC, from within a pulumi program, but if so, it could be useful. Another way I'm thinking of is using the value of a secret as the input to your job. This wouldn't be possible in yaml, would require a full programming language Pseudocode thoughts
Copy code
if bootstrap_completed is empty or false {
   run bootstrap_database
   set secret bootstrap_completed = true // external secret within your environment, e.g. AWS Secrets Manager
If I'm not making some kind of huge logic flaw, this will only ever run once Scenario 1: new stack. Secret doesn't exist yet. bootstrap runs, secret gets set. Scenario 2: subsequent runs on existing stack. Secret exists and is true. bootstrap doesn't run.