NixOS Infrastructure Operator (NIO) provides a GitOps approach to managing bare-metal and virtual machines running NixOS.
./install.sh# Create Secret with SSH key
kubectl create secret generic worker-ssh-key \
--from-file=ssh-privatekey=~/.ssh/id_rsa \
--namespace=defaultkubectl apply -f examples/machine-example.yaml# For private repositories
kubectl create secret generic git-credentials \
--from-literal=token=your-github-token \
--namespace=defaultkubectl apply -f examples/nixosconfiguration-example.yamlkubectl get machine worker-01 -o yamlExpected status after successful application:
status:
hasConfiguration: true
appliedConfiguration: "worker-config"
appliedCommit: "a1b2c3d4e5f6..."
lastAppliedTime: "2025-01-21T08:30:00Z"kubectl get nixosconfiguration worker-config -o yamlThe operator always tracks the Git commit hash from which the configuration was applied. This ensures:
- Reproducibility: Any engineer can run
git show <commit>to exactly reproduce the system state - Auditability: Complete transparency of which configuration version is running on the machine
- Reliability: The hash is only saved after the entire operation completes successfully
-
Full Installation (
fullInstall: true):- Uses
nixos-anywhere --kexec - Suitable for initial OS installation
- Performs complete system reinstallation
- Uses
-
Update (
fullInstall: false):- Uses
nixos-rebuild switch --flake - Suitable for updating existing systems
- Preserves state and data
- Uses
When deleting NixosConfiguration:
- Machine status is cleaned
- Removal configuration is applied if specified (
onRemoveFlake) - Ensures clean state removal
spec:
flake: ".#worker"
fullInstall: falseadditionalFiles:
- path: "secrets/database-password"
value:
secretRef:
name: db-secret
- path: "config/custom.nix"
value:
inline: |
{ config, pkgs, ... }:
{
services.postgresql.enable = true;
}
- path: "facts/system-info"
value:
nixosFacter: truespec:
onRemoveFlake: "hosts/minimal.nix"kubectl logs -l app=nixos-operator -n nixos-operator-systemkubectl get events --field-selector involvedObject.name=worker-configEnsure that:
- Machine IP address is accessible from the Kubernetes cluster
- SSH key is correctly configured in the Secret
- SSH user has permission to execute commands
- Use Git Tags: For production, use tags instead of branches
- Secure Secrets: Use external secret management systems
- Monitor Status: Regularly check appliedCommit status
- Test Configurations: Apply first in test environments
- Use Backup: Configure safe removal procedures
- Developer pushes changes to Git
- Operator automatically detects changes
- Configuration is applied to target machine
- Commit hash is recorded in Machine status
- Engineers can verify appliedCommit for audit purposes
apiVersion: nio.homystack.com/v1alpha1
kind: Machine
metadata:
name: worker-01
spec:
hostname: worker-01
ipAddress: 192.168.1.100
sshUser: root
sshKeySecretRef:
name: worker-ssh-keyapiVersion: nio.homystack.com/v1alpha1
kind: NixosConfiguration
metadata:
name: worker-config
spec:
gitRepo: "https://github.com/your-org/nixos-configs.git"
flake: ".#worker"
fullInstall: false
machineRef:
name: worker-01
credentialsRef:
name: git-credentials- Check network connectivity between Kubernetes cluster and target machine
- Verify SSH key is correctly configured
- Ensure SSH service is running on target machine
- Check Git repository accessibility
- Verify credentials for private repositories
- Review operator logs for specific error messages
- Ensure SSH user has sudo privileges if required
- Check file permissions in target directories
- Verify SSH key permissions on the operator side