hi all! I've been doing a lot of work with the AWS...
# general
l
hi all! I've been doing a lot of work with the AWS CDK during the last 3-4 years and am finding myself using Pulumi for the first time. In CDK it's relatively easy to have a single codebase deploy different stacks, and you'd list the stacks using
cdk ls
and then deploy one of them using
cdk deploy <stack name>
. This was very nice for us especially around managing fleets of kubernetes clusters etc, we would be able to test an update on a single cluster before deploying it to all, since each cluster was its own cdk stack. I'm finding myself a little unsure how to do something similar with pulumi, without having to resort to "cheating". I'd like to contain all our clusters in a single codebase, but I don't necesarily want to deploy a change to all clusters at the same time. Is my only option to create a pulumi "app" per cluster, or is there some easier way of doing this?
l
As of late, my preferred layout has been something like this:
Copy code
project/
├─ node_modules/
├─ db-1/
│  ├─ index.ts
│  ├─ Pulumi.dev.yaml
│  ├─ Pulumi.prod.yaml
│  ├─ Pulumi.yaml
├─ db-2/
│  ├─ index.ts
│  ├─ Pulumi.dev.yaml
│  ├─ Pulumi.prod.yaml
│  ├─ Pulumi.yaml
├─ cluster-1/
│  ├─ index.ts
│  ├─ Pulumi.dev.yaml
│  ├─ Pulumi.staging.yaml
│  ├─ Pulumi.prod.yaml
│  ├─ Pulumi.yaml
├─ .gitignore
├─ package.json
├─ README.md
In each
Pulumi.yaml
, you can set
main: index.ts
so it uses the index in the current folder rather than the entrypoint as defined in
package.json
. Each db/cluster is a separate pulumi 'project', and each project can have multiple stacks (environments). I'm not sure if this is perfectly applicable to your situation, but thought it might give some ideas on how you can lay stuff out.
l
thanks! and it does. Yep I'm heading in that direction myself after some thinking. I guess a pulumi project (with a Pulumi.yaml file) is the "smallest atomic" unit so that's the way we have to split them up.
l
I've recently been moving my company from CDK to Pulumi so we had a similar point where we had to find analogies to explain the differences in projects/stacks between the two. It's weirdly hard to explain, because they're similar but also kinda very different. CDK assumes that all of your infrastructure is going to live in a single app consisting of many stages (environments) containing many stacks, whereas pulumi expects you to have multiple projects and each project may have multiple stacks (environments)
not that I would ever actually put a significant amount of infra in a single CDK app because 'cloudformation has decided to nuke all your infra without showing it in the diff' happens far more often than should be permitted for a modern iac tool
l
yup, I find myself also struggling with the "translation". That aside, I'm finding Pulumi a pleasant experience tho there are some things to "unlearn" from cdk.
l
Haha, thankfully I went from Terraform to CDK and then to Pulumi which is basically terraform, so it clicked pretty easily for me, but I still find it difficult to explain. If you find a good way to explain it to my colleagues who only have experience with CDK, do let me know
The biggest thing that threw me when starting off in pulumi after spending a while in CDK is that once defined, resources aren't mutable - so if you want to say, pass a policy around and have multiple components add statements onto that policy, you've gotta make an object to do that rather than creating a policy and pass it around to be mutated by each component
l
basically terraform just without the horribleness of hcl 🙂 One area I wish pulumi was stronger at, is state management. In terraform you define the backend/state as part of the declarative "thing". In Pulumi that's completely hidden, and (IMHO) far too difficult to discover. I'd like to (for instance) ensure that noone runs a "pulumi up" operation while being logged in to the wrong backend or otherwise have something bad in their config. It seems like it's all driven by environment vars and a non-enforcable set of yaml attrs. That's my big gripe with pulumi right now I think.
oh that's good info. Yeah, cdk has a lot of these "helper methods" that mutate objects
l
I think I agree - the yaml parts of pulumi are a bit difficult to enforce or even add schemas and stuff to. I even started building out a little tool to generate a json schema to allow for
# yaml-language-server: $schema=..
, but pulumi's published schemas are a bit lacking at the moment. I'd really like to see full programmatic control of the stack config without having to go down the automation api path
l
yup same. Most of my cdk work is python-based, and there we imported each environment (or variant or whatever) as a python module which was class-backed and testable. On those classes we could validate all kinds of stuff like "if kubernetes version is higher than x, make sure y is higher than z" etc. So we could basically unittest our entire codebase including configs. pulumi seems to just assume all environment-specific config is placed in yaml files. imho this is the most brittle part of iac, that's where you definetely want to have relatively strong typing so you can validate everything using a real programming language.
for now we're programmatically looking at the current "stack name" to conditionally load the right config class to get around it.
anyway good to know I'm not alone in the "cdk to pulumi" camp 🙂
l
heh I was trying to find a similar solution to dynamically load things based on stack names - not being able to programmatically set names leads to annoying non-solutions like this:
Copy code
const goodProjectName = Environment.expectedProjectNameRegex.test(this.projectName)
    if (!goodProjectName) {
      void log.warn(`The project name (${this.projectName}) does not follow the expected production project format of {servicename}-{scope}. This may cause issues with dynamic imports.`)
    }
blehhh!
l
fun! 🙂
hm maybe its possible to do something with the pulumi automation api, looks like that that can replace the pulumi cli and give programmatic control over the entire process like stack creation/selection etc.
l
I went down that rabbit hole for a bit. It probably would solve the problem, but unfortunately means that teaching pulumi to my developers would be far more of a chore, as they can't just follow pulumi's getting started guides to know how to interact with our iac
l
yeah, that's a very good point.
l
One advantage of CDK is you really can hack deeply into its inner-workings because it's all just JS. Can't do the same with Pulumi because once you go further than one layer deep into resources, you're blocked by a black box RPC call that you can't modify the inner workings of
l
hm yeah. We never had to do much cdk hacking tbh - we got what we need from the regular api's + escape hatches and the so-called aspects
l
Fair enough