Hey everyone, @cole-h and I have been working together on a Terraform provider for Hydra. Today it can managed projects and jobsets. It includes an importer so you can migrate from a manually configured Hydra server really easily. Check it out!
This is very interesting! Now I immediatly asked myself: what was the motivation of using terraform/hcl over nix as the configuration language?
I could kind of come up with an answer myself but it didn’t convince me all the way and would go something like “terraform / hcl is better suited over nix for remote APIs”.
What where your considerations?
Don’t really want to talk for @grahamc here, just my own view of things:
From my experience, managing mutable state is very hard with Nix. You can’t just nuke a DB every time you want to apply changes, so a tool that has a concept of state transitions is better suited for this job. That’s what Terraform is pretty good at, it always checks the current state before applying any change.
It would of course be nice if Hydra was better at letting itself manage with Nix, but a lot of its configuration is done via its database for ease of querying.
I’d also like to add that Terraform doesn’t necessitate the use of HCL. I’m using both Nix and CUE to generate JSON that is then consumed by Terraform. I find them much more suited to the task, because Nix is pretty much a full programming language, and CUE provides better typing guarantees.
The root of the decision was that terraform is a ubiquitous tool for managing cloudy resources, and integrates with existing infrastructure really nicely. It was relatively very easy to make a “correct” provider for Hydra + Terraform. Of course as manveru notes, it doesn’t matter if you use HCL or generate JSON with Nix or …
Thanks to both! I guess this answers a long standing question of mine on how to get a handle on remote stateful resources “the nix way”. Of course, it will be interesting to see how
nomia wants to fit into this scheme of things.
I’d imagine this provides a better managed experience when there is some coupling between the jobs being done and the infrastructure required. For example one may want to Terraform to bring up particular hardware as workers for particular jobsets. Or if Hydra is performing a function closer to a continuous service rather than just checking builds.
That holds true as long as the receiving end of the API is not capable of gracefully reconciling declarative configurations. Unfortunately, this is still more often than not, the case.
→ I can see how
terraform elegantly bridges the gap, in the meantime until — in an ideal world — all configuration APIs have been tought to expose a strictly declarative interface.
There is also a nice post from y-comb that comes to my mind, here:
Configuration isn’t code isn’t data. Data belongs in a database. Code belongs in a codebase. Configuration doesn’t. Ideally config should be reduced down to keys and values and stored anywhere where it’s easy to push to the environment where the code runs.
(I don’t agree with the rest of that post)
On the topic of Nix as a configuration language for Hydra: There is support for declarative jobsets in Hydra, see GitHub - shlevy/declarative-hydra-example: An example illustrating declarative hydra projects
I’ve used this successfully to create complex jobsets purely from Nix expressions in git repos. Hydra will handle these jobsets in two stages: it has a “meta-jobset” that watches a repo for changes and evaluates any jobsets provided. The evaluation will then trigger the creation of the real jobsets. This approach can be a bit confusing at times, but I found it worked fine in practice.
The project where I used this setup has moved away from Hydra so I can’t tell you anything about the current state of declarative jobsets in Hydra.