# NixOS ZFS EC2 AMI Builder This project publishes a matched EC2 AMI artifact: - root volume: bootable NixOS EC2 image - secondary volume: preseeded ZFS pool mounted at `/nix` The root snapshot and `/nix` snapshot are registered together in one AMI block device mapping. Runtime deployments should consume the AMI ID directly and should not independently choose a `/nix` snapshot. The image is intentionally project-agnostic. It provides NixOS, ZFS, SSM, flakes, and systemd ordering so the Nix daemon waits for `/nix`. The final AMI also disables the default shell-oriented `amazon-init` service and enables a small generic service that treats EC2 user-data as `/etc/nixos/flake.nix`, then runs `nixos-rebuild switch --flake /etc/nixos`. ## Publish The normal flow builds on a temporary EC2 instance, so your local machine does not need to be the same architecture as the target AMI: ```bash nix run ./tofu/ami-builder#publish-ami -- --builder-instance-type t4g.large ``` `publish-ami.sh` applies this OpenTofu project to create a temporary builder instance and `/nix` volume. The builder user data installs a ZFS-capable NixOS boot generation, reboots once, seeds the ZFS `/nix` volume, installs the final boot generation that expects `/nix`, and powers off. After the instance is stopped, `publish-ami.sh` creates the final AMI from the stopped instance, tags the AMI and snapshots, writes `artifact.json`, and then destroys the temporary builder resources without a confirmation prompt. Use `--keep-builder` when debugging. The OpenTofu state in this directory owns only temporary builder resources. The published AMI and its snapshots are created by the script and are not in OpenTofu state, so `tofu destroy` here can clean up the builder without deregistering the AMI. Pass extra OpenTofu variables after `--`: ```bash nix run ./tofu/ami-builder#publish-ami -- --builder-instance-type t4g.large -- \ -var base_nixos_ami_id=ami-... ``` ## Artifact Metadata The final AMI is tagged with: - `Architecture` - `InputHash` - `BuilderGitRev` - `FlakeLockRev` - `RootSnapshotId` - `NixSnapshotId` - `NixosSystemClosure` Do not deregister the AMI or delete either snapshot while runtime deployments use it. ## Artifact Cleanup List published AMIs and cross-reference qx-deploy runtime registry records: ```bash nix run ./tofu/ami-builder#ami-artifacts -- list ``` Delete an unused AMI and its root and `/nix` snapshots: ```bash nix run ./tofu/ami-builder#ami-artifacts -- delete --ami-id ami-... ``` The delete command refuses to delete AMIs referenced by runtime deployment registry records unless you pass `--force`.