whoami
Many-hats Engineer at Bowtie (remote, very early stage start-up)
Likes
emacs
π)
We'll talk about specific technologies(whoops!) but in general:
What are some high-leverage ways to scale operational engineering?
How do we approach novel tools and evaluate benefits and drawbacks?
The startup experience is many-hats devops:
CONGRATS!!! IT'S YOUR PROBLEM NOW CYA
"There's a catch-all solution for this"
…maybe. But weβre going to think smaller
βοΈ 9 Different platforms
β
βοΈ Configuration management
β
π Developer experience
β
π§ͺ Testing
some secret, third thing
n
platforms to support!What if we tried something really different
github.com/NixOS/nixpkgs
)…really, anything that ends up being files (container tarballs, etc.)
Impossible to ship built artifacts to targets with mismatched dependencies:
$ ./exe libstdc++.so.6: cannot open shared object file: No such file or directory
Not only shared libraries, but all kinds of dependencies: in-$PATH
programs, toolchain versions, etc.
Changes to real-world time, downloads, and build environment (like environment variables) can't impact build viability
Every input to your build is hashed based upon its contents
Buried lede: nix has total knowledge of how to build software
Buried lede: nix has total knowledge of how to build software
Buried lede: nix has total knowledge of how to build software
What if we took the intermediate form of our system configuration – the abstract form – and then constructed different end results?
(this is sort of analogous to a Puppet catalog or a CloudFormation JSON if you squint)
What if we took the intermediate form of our system configuration – the abstract form – and then constructed different end results?
What if we took the intermediate form of our system configuration – the abstract form – and then constructed different end results?
{ imports = [ nixos-generators.nixosModules.all-formats ]; services = { caddy.enable = true; minio.enable = true; }; }
Compile a system into arbitrary forms:
$ nix build .#qcow $ file result/nixos.qcow2 result/nixos.qcow2: QEMU QCOW Image (v3) $ nix build .#vmware $ file result/nixos-vmware-x86_64-linux.vmdk result/nixos-vmware-x86_64-linux.vmdk: VMware4 disk image
--- - name: Install nomad package: name: nomad state: latest notify: - restart nomad
Ansible for imperative configuration steps
β
{ services.nomad.enable = true; }
Nix for declarative configuration state
infinite recursion
)exec
again
README
, good luck"docker-compose.yml
and virtual environments
{ devshells.default = mkShell { packages = [ rustc python311 nodejs_20 ]; }; }
{ devshells.default = mkShell { }; }
{ devshells.default = mkShell { inputsFrom = [ backend restapi frontend ]; }; }
$PATH
devshell
via nix develop .
$ cd src/project
(full disclosure: direnv
makes this possible with an .envrc
)
Results: pretty good β
(Nothing personal)
%!#$&ing YAML
libsystemd
for Rust)
devshell
! (toolchains, libraries, utilities)nixosTest
framework makes it easy to spawn and test virtual machinesnixosTest { name = "network-appliance"; nodes.appliance = { lib, pkgs, ... }: { services.nginx.enable = true; networking.firewall.allowedTCPPorts = [ 80 ]; }; testScript = /* python */ '' appliance.wait_for_unit("nginx.service") appliance.succeed("curl http://localhost") ''; }
Thank you!
Happy to hallway-track chat about: