# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Repository Overview This is an Ansible infrastructure management repository that manages a mixed environment including network services, monitoring, VPN infrastructure, and web applications. The codebase supports multiple operating systems (Debian, Ubuntu, AlmaLinux) and uses a role-based architecture for modularity. Note: Flatcar Container Linux VMs are provisioned by OpenTofu and configured via Butane/Ignition — they are NOT managed by Ansible. ## Common Commands ### Bootstrap New Hosts ```bash # Initial bootstrap (requires password) make bootstrap-init HOSTNAME=hostname ANSIBLE_HOST=ip_address # Full bootstrap with network config and reboot make bootstrap HOSTNAME=hostname ANSIBLE_HOST=ip_address ``` ### Run playbooks ```bash # Run main playbook ./run.sh # Run all plays on specific host ansible-playbook -l hostname playbook.yml # Run specific tags ansible-playbook -t caddy playbook.yml ``` ### Development Tasks ```bash # Gather facts from all hosts ansible -m setup all # Test changes on specific host ansible-playbook -l hostname playbook.yml # Check syntax ansible-playbook --syntax-check playbook.yml # Dry run ansible-playbook --check playbook.yml ``` ## Architecture ### Playbook Structure - `playbook.yml` - Main playbook for all configuration (common, firewall, DNS, Caddy, general, monitoring, PostgreSQL, prometheus stack, etc.) - `bootstrap.yml` - Initial host preparation - `netbox.yml` - Standalone NetBox deployment ### Role Organization Roles follow a standard structure with: - `tasks/main.yml` - Main task list - `handlers/main.yml` - Service restart handlers - `templates/` - Jinja2 templates for config files - `vars/` - Role-specific variables - `defaults/` - Default variable values ### Key Roles - `base` - Combined base configuration (users, SSH, sudo, packages) - `general` - General system configurations (motd, network, syslog, NFS, K3s) - `caddy` - Web server and reverse proxy - `firewall` - UFW/firewalld rule management - `ns` - BIND9 nameserver configuration - `tailscale` - Tailscale VPN setup - `monitor` - Icinga2 monitoring master - `prometheus` / `alertmanager` / `loki` / `grafana` / `node_exporter` - Prometheus monitoring stack - `netbox` - NetBox IPAM/DCIM - `pgbouncer` - PostgreSQL connection pooler - `librenms` - LibreNMS network monitoring - `mailcow` - Mailcow email server - `dokku` - Dokku PaaS - `aprsc` - APRS-IS server - `uisp` - Ubiquiti UISP - `syncthing` - Syncthing file sync ### Variable Precedence 1. Host-specific vars in `host_vars/` 2. Group vars in `group_vars/` 3. Role defaults in `roles/*/defaults/` 4. Base variables in `vars/` ### Service Dependencies - SSH configuration managed by base role - Firewall rules (UFW/firewalld) applied before service configs - Handlers ensure services restart when configs change - Tailscale VPN requires `TAILSCALE_AUTHKEY` (or `TAILSCALE_KEY`) environment variable - SSH key path defaults to `~/.ssh/ansible`; override via `ANSIBLE_SSH_PRIVATE_KEY_FILE` env var ## Key Patterns ### User Management - Ansible user (UID 10001) created on all hosts - SSH keys fetched from GitHub for authentication - Passwordless sudo configured for automation ### Network Services - DNS resolvers are Flatcar VMs managed via OpenTofu + Butane (see ../tofu/) - Nameservers configured via ns role - Caddy serves as reverse proxy for web services - Tailscale provides VPN connectivity ### Configuration Management - Templates use host-specific variables - Handlers manage service restarts - Fact caching improves performance - Collections required: ansible.posix, community.general, kubernetes.core, community.postgresql, community.proxmox, community.mysql ## Memories ### Playbook Defaults - The default ansible playbook is `playbook.yml`