The place where we differ is:
* YAML instead of JSON
* A lot of python based tooling to do the plumbing
* We don't always rely on terraform for provisioning everything so we have monitoring of new resources in AWS and policies on how those untagged resources will be treated
Good to know that there are more people thinking in a similar way. Validates our approach. :)
Would love to chat in person to learn more about the setup and exchange ideas if you are up for it.
If you want to email me at email@example.com, we can sort a virtual coffee.
This looks way more legible to me:
(service make-it-rain (gocardless/make-it-rain)
;; Example service called make-it-rain, powering a dashboard of falling
;; gold coins whenever anyone takes a payment via GoCardless.
;; Banking teams love money, which is why they created this dashboard.
;; It's officially owned by banking-integrations, but core-banking
;; sometimes optimise the React code.
;; It consumes data about new payments from Google Pub/Sub, and has a
;; separate Google Cloud Platform project for each of its environments,
;; of which there are two: staging and production.
;; By default, every environment should have banking-integrations as
;; admins, and core-banking as operators (they provide on-call cover
;; for the falling gold coins).
(* (admins banking-integrations)
(argocd.new (cluster compute-staging-brava)
;; Unlike most services, the production environment should permit
;; a non-engineering team to open consoles. Sometimes we take a
;; manual payment outside of GoCardless, and banking-operations
;; open a make-it-rain console and run a script, so we don't miss
;; any gold coins.
(argocd.new (cluster compute-banking)
I think there's a huge win in having a more man-readable, machine-computable format that JSON or Jsonnet: as the system and the tooling grow, I think eventually the Jsonnet will become an unreadable mess of spaghetti (some might argue the example already is!), while a well-thought-out S-expression alternative would not, I think, have the same problem.
The primary reason we choose Jsonnet for the registry library was because it's already become our data munger of choice at GoCardless, and we're keen to limit the number of tools we use to make our work more accessible to people outside our team, along with our new joiners.
So while your example works really quite beautifully for this use case, we'd naturally prefer to choose a tool that can work for all our use cases. And Jsonnet has a bit win over the language you've sketched here, in its inheritance and mixin semantics, which allow us to write configuration like complex Kubernetes manifests that are composeable and allow flexible overriding of fields from the caller.
Someone else has mentioned dhall-lang in the comments. We looked at this and several alternatives before we began a push for Jsonnet about a year ago- we ended up choosing Jsonnet over these because:
- Jsonnet has first-class support in Golang, our primary language for infrastructure code
- Everyone who knows JSON already knows how to write valid Jsonnet. This was important, as we expect application engineers to contribute to the Jsonnet config, and asking them to learn something totally novel is a bit much
- There were several tools like Ksonnet and Tanka from which we could take inspiration, especially around managing of Kubernetes resources, which was the big motivation behind a total revamp
If I were working on a team solo, I think dhall-lang would look really appealing to me. I like strongly typed languages and have a bit of experience in Haskell, so it looks very normal to me. That said, cuelang (https://github.com/cuelang/cue) looks super interesting, though it has a very different take to Jsonnet.
This is a roundabout way of saying I really like your example, and I see our choice of Jsonnet as another version of our choice of Golang: the network effects were too great to ignore, and it's good enough to work for almost everything, if not the best in any one area.