February 24, 2025·5 min read·engineeringnixdeploymentaws

Determinate's NixOS AMIs deploy cached system configurations

Determinate's new EC2 images combine AWS authentication with FlakeHub's resolved store paths. Instances can apply a published NixOS closure without evaluating its configuration locally.

A binary cache removes compilation from a deployment only after the deploying machine knows which store path it needs. Evaluating a NixOS configuration can still consume resources before that cache lookup happens. Determinate's new NixOS AMIs combine a prepared base image with published output-path metadata so an instance can obtain its target system without repeating that evaluation locally.

The February 24 announcement introduces images for AMD64 and ARM64 Linux. They include Determinate Nix and the fh command-line tool. Their intended deployment path authenticates the instance to FlakeHub and then applies a NixOS configuration already published to its cache.

Nix's declarative system model is central to how I manage personal infrastructure. This is an interesting deployment option because it separates deciding the system's store path from installing that system on a new machine. The instance can consume the result of the published configuration instead of reproducing all the work needed to identify it.

Evaluation and realization are separate work

Determinate's earlier resolved store paths explanation describes the distinction. Nix ordinarily evaluates the target derivation's store path, then determines whether it can fetch the result from a cache or must build it. A cache hit does not imply that evaluation was free or absent.

FlakeHub's resolved-path facility stores an already calculated store path for a flake output reference. A client can request that mapping directly. The resulting path identifies the artifact to fetch, so the deployment machine does not need to evaluate the flake itself to discover that path.

This moves work into publication. The earlier article says publishers enable output-path inclusion so the flake's output paths are evaluated and stored in FlakeHub's database. Deployment then consumes that published metadata along with cached artifacts. A source reference alone is not enough to obtain the same benefit if the corresponding outputs and cache content have not been prepared.

The distinction is useful for small instances or repeated launches. Each new instance still needs to download and activate its system. It can avoid repeating evaluation that already produced a published answer. The announcement does not provide a general timing guarantee, so the mechanism is a better description than a fixed claim about deployment speed.

Authentication uses the AWS context

The announced workflow starts with determinate-nixd login aws. Determinate Nixd uses AWS Security Token Service for the FlakeHub login path. The resulting access allows the instance to fetch the organization's permitted content through the tools included in the image.

The second command applies a named NixOS configuration from the published flake.

determinate-nixd login aws
fh apply nixos "my-org/my-flake/*#nixosConfigurations.my-nixos-configuration"

The announcement's example says fh pulls the target closure from FlakeHub Cache without evaluating the store path. The flake reference and output name identify the desired system configuration. Authentication and artifact selection remain separate parts of the sequence, even though both fit into a short startup script.

That separation matters operationally. A machine can start from the image successfully while lacking access to the target organization's cache content. It can also authenticate correctly while requesting an output that was not published as intended. The two commands express distinct requirements, so successful image launch alone does not establish that the desired system has been applied.

The image is a deployment starting point

The AMI provides an operating environment with the required tools already present. The target flake supplies the system configuration subsequently applied to that environment. This makes the base image and the deployed configuration two independently selected inputs to instance creation.

The announcement demonstrates selecting an image through an aws_ami data source usable with Terraform or OpenTofu. Its filters include the publisher account, the determinate/nixos/epoch-1/* name family, and the architecture. An EC2 resource then uses the selected image and supplies the login and apply commands as startup data.

This is compatible with a declarative division of responsibilities. The infrastructure configuration chooses the instance and base image. The NixOS output describes the desired system installed on it. Keeping that relationship visible helps explain which change belongs to image selection and which belongs to the system configuration.

The example's use of the most recent matching AMI is a selection policy, not a fixed artifact identity. Likewise, the wildcard in the FlakeHub reference selects according to that service's version resolution. The earlier resolved-path article documents exact-version constraints as well as broader constraints. Choosing a moving selector or an exact version changes what a repeated launch requests.

Version selection remains an explicit policy

The resolved-path article gives * as the latest-release selector and =0.1.2 as an exact match example. Those are meaningful choices even when deployment does not evaluate locally. Avoiding evaluation does not freeze the output selected by a moving reference. A later launch using the same wildcard may request another published release.

The image selector and flake selector can therefore change independently. Pinning the configuration does not pin the base image selected by a most-recent AMI query. Selecting a particular image does not freeze a wildcard configuration reference. A deployment description needs both policies to explain what another launch will install.

Published metadata becomes part of deployment

Avoiding local evaluation requires trusting the publication process to associate the intended output reference with the intended store path. The deploying host receives the published answer instead of calculating it from source. That does not make the answer arbitrary, but it makes publication and permissions part of the deployment's operational dependencies.

The earlier article says resolved paths follow FlakeHub permissions, including access controls for private flakes. The AMI announcement also identifies a paid FlakeHub plan and cached NixOS closures as prerequisites for its intended workflow. This is a service-integrated deployment option, with the cache and metadata service supplying part of the process.

I find the division useful when a deployment is meant to consume a previously prepared system. Nix already provides a concrete system result, and an instance need not calculate its identity again merely to retrieve it. The practical requirement is to publish the output mapping and closure together so startup has both the artifact identity and the bytes needed to apply it.