80 lines
2.5 KiB
Markdown
80 lines
2.5 KiB
Markdown
# 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
|
|
cd tofu/ami-builder
|
|
./publish-ami.sh --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. 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
|
|
./publish-ami.sh --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`.
|