Add reproducible Nix dev environment
Replace the Python venv with a Nix devshell pinning ansible-core 2.21.3, ansible-lint, yamllint and a Python with proxmoxer/requests. The Python dependencies share the interpreter that runs ansible, so pve-*.yml plays on implicit localhost can import proxmoxer without inventory changes. The shellHook exports absolute ANSIBLE_CONFIG, ANSIBLE_INVENTORY, ANSIBLE_ROLES_PATH and ANSIBLE_COLLECTIONS_PATH, so commands work from the repository root as well as from ansible/. Also un-ignore .envrc, which the global gitignore hides, and ignore the stray .ansible/ runtime directory. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GTocXkGUUazHdKKd3r9k71
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
# direnv: load the Nix dev shell defined in flake.nix
|
||||
# Enable once per checkout with: direnv allow
|
||||
use flake
|
||||
@@ -20,3 +20,9 @@ __pycache__/
|
||||
.direnv/
|
||||
result
|
||||
result-*
|
||||
|
||||
# direnv shell hook lives in the repo (global gitignore hides it)
|
||||
!.envrc
|
||||
|
||||
# Ansible local runtime dir (facts cache, locks)
|
||||
.ansible/
|
||||
|
||||
Generated
+27
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1787498568,
|
||||
"narHash": "sha256-9i/VTdusq/+NM/tz+J1Re+ojkMB8MBf0QshnYfzHz30=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "56c02bc00adcf003215cc4bd996d6efaf4cff188",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
{
|
||||
description = "HomeLab infras — reproducible Ansible control-plane dev shell";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs }:
|
||||
let
|
||||
systems = [ "x86_64-linux" "aarch64-linux" ];
|
||||
forAllSystems = f:
|
||||
nixpkgs.lib.genAttrs systems (system: f nixpkgs.legacyPackages.${system});
|
||||
in
|
||||
{
|
||||
devShells = forAllSystems (pkgs:
|
||||
let
|
||||
# One Python environment carrying ansible-core *and* the libraries the
|
||||
# modules import in-process (community.proxmox needs proxmoxer +
|
||||
# requests). Ansible sets ansible_python_interpreter for the implicit
|
||||
# localhost to sys.executable, so `hosts: localhost` and
|
||||
# `delegate_to: localhost` tasks pick these up automatically.
|
||||
pythonEnv = pkgs.python3.withPackages (ps: with ps; [
|
||||
ansible-core
|
||||
proxmoxer
|
||||
requests
|
||||
]);
|
||||
in
|
||||
{
|
||||
default = pkgs.mkShell {
|
||||
name = "homelab-infras";
|
||||
|
||||
packages = [
|
||||
pythonEnv
|
||||
pkgs.ansible-lint
|
||||
pkgs.yamllint
|
||||
pkgs.git
|
||||
pkgs.jq
|
||||
pkgs.openssh
|
||||
pkgs.curl
|
||||
pkgs.gnumake
|
||||
];
|
||||
|
||||
shellHook = ''
|
||||
repo_root="$(${pkgs.git}/bin/git rev-parse --show-toplevel 2>/dev/null || pwd)"
|
||||
ansible_dir="$repo_root/ansible"
|
||||
|
||||
if [ -f "$ansible_dir/ansible.cfg" ]; then
|
||||
# ansible.cfg spells its paths relative to ansible/, so pin them
|
||||
# absolutely here — that makes the shell usable from the repo
|
||||
# root as well as from inside ansible/.
|
||||
export ANSIBLE_CONFIG="$ansible_dir/ansible.cfg"
|
||||
export ANSIBLE_INVENTORY="$ansible_dir/inventory/hosts.yml"
|
||||
export ANSIBLE_ROLES_PATH="$ansible_dir/roles"
|
||||
export ANSIBLE_COLLECTIONS_PATH="$ansible_dir/collections"
|
||||
else
|
||||
echo "warn: $ansible_dir/ansible.cfg not found — run commands from ansible/" >&2
|
||||
fi
|
||||
|
||||
# Banner goes to stderr so `nix develop --command ...` keeps a
|
||||
# clean stdout for scripting.
|
||||
{
|
||||
_ver_ansible="$(ansible --version 2>/dev/null | head -n1 | tr -d '[]' | awk '{print $3}')"
|
||||
_ver_lint="$(NO_COLOR=1 ansible-lint --version 2>/dev/null | tail -n1 | awk '{print $2}')"
|
||||
_ver_yaml="$(yamllint --version 2>/dev/null | awk '{print $2}')"
|
||||
_ver_py="$(python3 --version 2>&1 | awk '{print $2}')"
|
||||
|
||||
echo "HomeLab infras dev shell"
|
||||
echo " ansible-core $_ver_ansible"
|
||||
echo " ansible-lint $_ver_lint"
|
||||
echo " yamllint $_ver_yaml"
|
||||
echo " python $_ver_py (proxmoxer, requests)"
|
||||
echo ""
|
||||
echo "ANSIBLE_CONFIG=$ANSIBLE_CONFIG"
|
||||
echo ""
|
||||
echo "Galaxy collections are NOT installed automatically. Run once:"
|
||||
echo " ansible-galaxy collection install -r $ansible_dir/requirements.yml -p $ansible_dir/collections"
|
||||
echo ""
|
||||
|
||||
unset _ver_ansible _ver_lint _ver_yaml _ver_py
|
||||
} >&2
|
||||
'';
|
||||
};
|
||||
});
|
||||
|
||||
formatter = forAllSystems (pkgs: pkgs.nixpkgs-fmt);
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user