Skip to content

Setup a New Machine: Post-Deployment Checklist

Duration: 5–15 minutes (optional; mostly verification and cleanup)

This phase handles tasks that cannot be automated and must happen after nixos-anywhere deployment. In most cases with a complete configuration, this phase is minimal or empty.

Prerequisites

You must have completed Setup New Machine - Deployment:

nixos-anywhere completed successfully ✅ Target system rebooted ✅ System is reachable (via Tailscale or SSH) ✅ Temporary deployment files cleaned up from admin host

Step 1: Verify Core Functionality

1.1 System Identity

Confirm the machine has the correct identity:

# Log into target
ssh root@${TARGET_HOSTNAME}

# Verify hostname
hostname
# Should print: ${TARGET_HOSTNAME}

# Verify NixOS version
nixos-version

1.2 Storage and Filesystems

Verify disk layout is correct:

# Check disks and partitions
lsblk

# Check mount points
mount | grep -E "^/(dev|/)"

# Check available space
df -h

1.3 Network Connectivity

Verify network is working:

# Check IP addresses
ip addr show

# Check routing
ip route show

# Test internet connectivity
ping 8.8.8.8  # or any external host

1.4 Secrets Decryption (if configured)

Verify secrets were decrypted and placed in /run/secrets/:

# List available secrets
ls -la /run/secrets/

# Verify a secret is readable
cat /run/secrets/tailscale/authKey
# Should print the actual secret value, not encrypted text

If this fails: - Check SSH host key exists: ls -la /etc/ssh/ssh_host_ed25519_key - Check age key can be found by sops-nix - Review systemd logs: journalctl -u systemd-sops-setup

1.5 Verify LUKS Encryption (if using disk encryption)

If your target uses LUKS encryption, verify it's working:

# Check that LUKS partition is open
ssh root@${TARGET_IP} "dmsetup status"
# Should show something like: luks: 0 [some numbers] crypt

Delete the temporary password file from the admin host:

# On admin host
rm -f /tmp/${TARGET_HOSTNAME}-luks-password.txt

Note on the USB keyfile: - The USB keyfile remains on your USB device and is used automatically when the USB is present during boot - The /key/ directory on the target is a temporary mount point used during installation - You can safely remove the USB from the target now - Keep the USB key in a safe place as a backup for unlocking if needed!

Step 2: Verify Tailscale (if configured)

If Tailscale is enabled in the NixOS configuration:

# On target
tailscale status
# Should show: Connected

# On target, check if SSH is enabled
tailscale status | grep ssh
# If "ssh" appears, Tailscale SSH is active

# From admin host, verify reachability
ping <target-tailscale-ip>
# Should respond

# Attempt SSH via Tailscale
ssh root@${TARGET_HOSTNAME}  # May work if DNS is configured
# or
ssh root@<target-tailscale-ip>

If Tailscale didn't auto-connect: - Verify tailscale/authKey secret is present (Step 1.4) - Check Tailscale service logs: journalctl -u tailscaled - Review configuration: cat /etc/nixos/hosts/${TARGET_HOSTNAME}/configuration.nix | grep -A5 tailscale

Step 3: Verify SSH Host Keys

The target's SSH host keys should have been deployed and are now active:

# From admin host, verify the host key
ssh-keyscan ${TARGET_HOSTNAME} 2>/dev/null | grep -v "^#"

# Check that the key matches what you expect
cat /etc/ssh/ssh_host_ed25519_key.pub  # On target

If you regenerated SSH host keys and want the same keys on the next deployment, they're now in place.

Step 4: Attic Cache Authentication (Optional)

If your NixOS configuration uses binary caching from Attic, the cache client should be pre-configured. However, authentication tokens must be set up.

4.1 Generate Attic Token (if cache not done during pre-deployment)

On the attic server (if you have one), generate a token for the new machine:

# On attic server
docker exec attic atticadm make-token \
  -f /attic/attic.toml \
  --sub snyssen \
  --validity 365d \
  --create-cache "snyssen-*" \
  --push "snyssen-*" \
  --pull "snyssen-*" \
  --configure-cache "snyssen-*"

This outputs a token like: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

4.2 Log Into Attic on Target

On the target machine, authenticate with the token:

# On target
attic login snyssen-infra https://attic.snyssen.be ${ATTIC_TOKEN}
# Replace ${ATTIC_TOKEN} with the token from step 4.1

Verify it works:

# Should succeed
attic cache list

For persistent cache authentication across reboots, add the token to the target's secrets:

# On admin host
just sops-update nix/hosts/${TARGET_HOSTNAME}/data/secrets.yaml

Add:

attic:
  authToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Then update the NixOS configuration to load it:

# nix/hosts/${TARGET_HOSTNAME}/configuration.nix
sops.secrets."attic/authToken" = {
  sopsFile = ./data/secrets.yaml;
  path = "/root/.config/attic/credentials.toml";
};

After the next nixos-rebuild, attic authentication will be automatic.

Step 5: Manual Configuration (if needed)

For any configuration that cannot be automated through NixOS (hardware tweaks, BIOS settings, etc.), perform those now. Examples:

  • BIOS settings: Power management, boot order, virtualization flags
  • Physical hardware: Verify all drives are recognized, fans working, etc.
  • Network: Configure static IPs, VPN connections not in Nix
  • Users: Set passwords for non-root users (if not declarative)

Step 6: Commit Configuration to Git

Once the machine is stable and verified, commit your new NixOS configuration:

# On admin host
git add nix/hosts/${TARGET_HOSTNAME}/
git commit -m "Add NixOS configuration for ${TARGET_HOSTNAME}"
git push

This ensures your machine's configuration is version-controlled and can be reproduced.

Step 7: Document (Optional)

If the new machine requires operational documentation, add it to the repository:

# Add or update documentation
vim docs/machines/${TARGET_HOSTNAME}.md
# Describe purpose, hardware, special config, etc.

git add docs/machines/${TARGET_HOSTNAME}.md
git commit -m "Document ${TARGET_HOSTNAME} machine"
git push

Summary

✅ System identity verified ✅ Storage and networking verified ✅ Secrets decrypted and accessible ✅ Tailscale connected (if configured) ✅ SSH host keys in place ✅ Attic cache authenticated (optional) ✅ Any manual configuration completed ✅ Configuration committed to git

Troubleshooting

System won't boot

  • Check that hardware configuration was properly generated
  • Verify disko config matches actual hardware
  • Boot into a live environment and check logs in /var/log

Secrets not decrypting

  • Verify age key exists: ls /etc/ssh/ssh_host_ed25519_key
  • Check age key is readable by sops: cat /etc/ssh/ssh_host_ed25519_key
  • Review sops-nix activation logs: journalctl -u sops

Can't SSH in

  • Verify SSH server is enabled: systemctl status sshd
  • Check SSH keys are in place (if deploying user keys): ls ~/.ssh/
  • Verify firewall allows SSH: nft list ruleset or iptables -L
  • Check for IP/network issues: ip addr and ip route

Tailscale won't connect

  • Verify authKey secret exists: /run/secrets/tailscale/authKey
  • Check tailscale service: systemctl status tailscaled
  • Manually start: tailscale up -auth-key=${AUTHKEY}
  • View logs: journalctl -u tailscale-autoconnect

What's Next?

Your machine is now ready for use. Depending on its purpose:

  • Desktop: Install additional packages, set up user environments in Home Manager
  • Server: Configure services (containers, databases, monitoring)
  • Hypervisor: Set up virtual machines

All further configuration changes should be made through the NixOS configuration files (Nix, Home Manager, Ansible) and deployed with nixos-rebuild or deploy-rs.