NixOps is a tool for deploying NixOS machines in a network or cloud. It takes as input a declarative specification of a set of “logical” machines and then performs any necessary steps or actions to realise that specification: instantiate cloud machines, build and download dependencies, stop and start services, and so on. NixOps has several nice properties:
It’s declarative: NixOps specifications state the desired configuration of the machines, and NixOps then figures out the actions necessary to realise that configuration. So there is no difference between doing a new deployment or doing a redeployment: the resulting machine configurations will be the same.
It performs fully automated deployment. This is a good thing because it ensures that deployments are reproducible.
It performs provisioning. Based on the given deployment specification, it will start missing virtual machines, create disk volumes, and so on.
It’s based on the Nix package manager, which has a purely functional model that sets it apart from other package managers. Concretely this means that multiple versions of packages can coexist on a system, that packages can be upgraded or rolled back atomically, that dependency specifications can be guaranteed to be complete, and so on.
It’s based on NixOS, which has a declarative approach to describing the desired configuration of a machine. This makes it an ideal basis for automated configuration management of sets of machines. NixOS also has desirable properties such as (nearly) atomic upgrades, the ability to roll back to previous configurations, and more.
It’s multi-cloud. Machines in a single NixOps deployment can be deployed to different target environments. For instance, one logical machine can be deployed to a local “physical” machine, another to an automatically instantiated Amazon EC2 instance in the eu-west-1 region, another in the us-east-1 region, and so on. NixOps arranges the necessary network configuration to ensure that these machines can communicate securely with each other (e.g. by setting up encrypted tunnels).
It supports separation of “logical” and “physical” aspects of a deployment. NixOps specifications are modular, and this makes it easy to separate the parts that say what logical machines should do from where they should do it. For instance, the former might say that machine X should run a PostgreSQL database and machine Y should run an Apache web server, while the latter might state that X should be instantiated as an EC2 m1.large machine while Y should be instantiated as an m1.small. We could also have a second physical specification that says that X and Y should both be instantiated as VirtualBox VMs on the developer’s workstation. So the same logical specification can easily be deployed to different environments.
It uses a single formalism (the Nix expression language) for package management and system configuration management. This makes it very easy to add ad hoc packages to a deployment.
It combines system configuration management and provisioning. Provisioning affects configuration management: for instance, if we instantiate an EC2 machine as part of a larger deployment, it may be necessary to put the IP address or hostname of that machine in a configuration file on another machine. NixOps takes care of this automatically.
It can provision non-machine cloud resources such as Amazon S3 buckets and EC2 keypairs.
From the NixOps User's Guide (manual)
The NixOps User's Guide provides an overview of the functionality and features of NixOps, as well as an up-to-date installation guide. Some other topics covered:
- Deploying to local targets:
- VirtualBox machine(s)
- Libvirtd (Qemu) machine(s)
- Existing NixOS machine(s)
- Deploying to clouds:
- Amazon EC2, Google Compute Engine, Microsoft Azure (Azure disabled since 2018)
- Hetzner, DigitalOcean
- Setting up DataDog cloud monitoring.