1. Pulumi promotes stacks as a way to have a singl...
# general
1. Pulumi promotes stacks as a way to have a single pulumi project/program that covers multiple environments like dev, staging, prod etc. Does it work well in practice? In my case environments differ quite a lot (e.g. k8s zonal cluster in dev env and regional in prod, or standard vs private gke clusters: these different setups require mutually exclusive configuration options; some resources are needed in dev env but not in prod and vice versa). I’m concerned that it will end up in a very complex pulumi program with a lot of `if`s and mutually exclusive configuration entries. Would this be an issue?
There's actually two approaches here: 1. Have one program with all your logic, and multiple stacks of this same program with different configuration. This will need `if`s and such in the program to be able to express all combiantions. 2. Have multiple programs, but allow those programs to share a set of shared "components" defined possibly in a different NPM/python package. Then the programs can be very different from one another if needed, but the shared logic can be puled into these shared components.
Option 2 is actually what I am testing right now (I created an npm package with ts module and use it as a dep in another project via git url) - thanks!
This is a good question so I’ll broadcast my thoughts here in case people want to have a separate discussion. I generally advise people to: • Group resources prioritized by (1) risk class, and (2) commonality. For example, the managed compute/storage/networking goes into one stack (or one set of stacks) and app code goes into another stack. This means primarily that app team does not have permissions to nuke the prod DB, etc., which is good. • Try to share low-level infrastructure, but don’t try too hard. The lower level you go, the less portable your code will be between environments. For example, you will have a completely different ingress stack in prod and staging — it is not necessary (or in some cases, possible) to completely replicate that. Classically this applies to AWS resources, but it also applies to low-level k8s resources, too. Stuff like
, persistent volume storage classes, etc. • Try hard to share app-level code between environments. Apps resources like
should have a “portable core” that can be deployed in a variety of places, hooking up to a variety of infrastructure. If it’s not portable you will probably cause yourself pain later.
👍 2
This is what I actually try to follow. It seems that having low-level infrastructure in one common program shared across environments like dev, staging, prod with stack per env might be tricky and complicated because of the issues raised above in the second bullet. The third bullet on the other hand promotes shared packages (e.g. npm for js/ts pulumi programs) that can be then composed and deployed in multiple pulumi programs. But it still doesn’t mean having one pulumi program for multiple envs with stack per env is that beneficial in most of my deployments (explosion of configuration options and number of `if`s in a pulumi program). Pulumi stacks might be more powerful than terraform workspaces but it still comes at a cost (and IMO quite high cost in complexity which doesn’t outweigh possible code duplication in pulumi program per env design - and BTW code duplication might be good or bad depending on the context). So still I am not convinced that having stacks as the first class concept and forced to be to handled them explicitly is that beneficial except of some small deployments that are unified across environments. In my case it would be so much easier to be able to work with an implicit default stack with an option to create other stacks if I really need to.