diff --git a/ansible/.DS_Store b/ansible/.DS_Store deleted file mode 100644 index bf9d32d..0000000 Binary files a/ansible/.DS_Store and /dev/null differ diff --git a/ansible/.gitignore b/ansible/.gitignore index 7d4624c..5dc068a 100644 --- a/ansible/.gitignore +++ b/ansible/.gitignore @@ -28,6 +28,9 @@ Thumbs.db *.pem vault-password.txt +# Downloaded Galaxy roles/collections +.ansible/ + # Temporary files tmp/ temp/ diff --git a/ansible/.vscode/settings.json b/ansible/.vscode/settings.json deleted file mode 100644 index 4110d79..0000000 --- a/ansible/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "ansible.python.interpreterPath": "/opt/homebrew/bin/python3" -} diff --git a/ansible/CLAUDE.md b/ansible/CLAUDE.md index 231ee35..66255b8 100644 --- a/ansible/CLAUDE.md +++ b/ansible/CLAUDE.md @@ -17,25 +17,22 @@ make bootstrap-init HOSTNAME=hostname ANSIBLE_HOST=ip_address make bootstrap HOSTNAME=hostname ANSIBLE_HOST=ip_address ``` -### Run Playbooks +### Run playbooks ```bash # Run main playbook ./run.sh -# Run all playbooks on specific host -make run-all HOSTNAME=hostname ANSIBLE_HOST=ip_address - -# Run general playbook -ansible-playbook general.yml +# Run all plays on specific host +ansible-playbook -l hostname playbook.yml # Run specific tags -ansible-playbook -t caddy general.yml +ansible-playbook -t caddy playbook.yml ``` ### Development Tasks ```bash # Gather facts from all hosts -make facts +ansible -m setup all # Test changes on specific host ansible-playbook -l hostname playbook.yml @@ -50,9 +47,9 @@ ansible-playbook --check playbook.yml ## Architecture ### Playbook Structure -- `playbook.yml` - Main playbook for common configuration, DNS, Tailscale, Caddy -- `general.yml` - General system setup including SNMP, K3s, Docker, syslog +- `playbook.yml` - Main playbook for all configuration (common, firewall, resolvers, 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: @@ -64,13 +61,22 @@ Roles follow a standard structure with: ### Key Roles - `base` - Combined base configuration (users, SSH, sudo, packages) -- `general` - General system configurations (motd, network, syslog) +- `general` - General system configurations (motd, network, syslog, NFS, K3s) - `caddy` - Web server and reverse proxy -- `ns` - Nameserver configuration -- `resolvers` - DNS resolver setup (Unbound) -- `docker` - Docker installation (stub) -- `k3s_servers` - Kubernetes K3s setup (stub) -- `snmp_clients` - SNMP client configuration (stub) +- `firewall` - UFW/firewalld rule management +- `ns` - BIND9 nameserver configuration +- `resolvers` - Unbound DNS resolver setup +- `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/` @@ -79,10 +85,11 @@ Roles follow a standard structure with: 4. Base variables in `vars/` ### Service Dependencies -- SSH configuration managed by common role -- Firewall rules (firewalld) applied before service configs +- 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_KEY` environment variable +- 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 @@ -101,7 +108,7 @@ Roles follow a standard structure with: - Templates use host-specific variables - Handlers manage service restarts - Fact caching improves performance -- Collections required: ansible.posix, netbox.netbox +- Collections required: ansible.posix, community.general, kubernetes.core, community.postgresql, community.proxmox, community.mysql ## Memories diff --git a/ansible/Makefile b/ansible/Makefile index cf67b72..c9ae3bf 100644 --- a/ansible/Makefile +++ b/ansible/Makefile @@ -58,9 +58,6 @@ run-all: install-ssh-key: ssh-copy-id $(ANSIBLE_HOST) -setup-user: install-ssh-key - ./setup-user.sh install $(ANSIBLE_HOST) - reboot: ssh -i ~/.ssh/ansible ansible@$(ANSIBLE_HOST) -t "sudo reboot" diff --git a/ansible/README.md b/ansible/README.md index 4b988f2..1eb65cd 100755 --- a/ansible/README.md +++ b/ansible/README.md @@ -5,19 +5,32 @@ This repository contains Ansible playbooks and roles for managing infrastructure ## Directory Structure ``` -├── playbook.yml # Main playbook for common configuration -├── general.yml # General system setup playbook +├── playbook.yml # Main playbook (common, firewall, DNS, monitoring, etc.) ├── bootstrap.yml # Bootstrap playbook for new hosts -├── roles/ # Ansible roles -│ ├── base/ # Base configuration (users, SSH, system) -│ ├── general/ # General system configurations -│ ├── caddy/ # Caddy web server -│ ├── ns/ # Nameserver configuration -│ ├── resolvers/ # DNS resolver setup -│ └── ... # Other roles -├── group_vars/ # Group-specific variables -├── host_vars/ # Host-specific variables -└── hosts # Inventory file +├── netbox.yml # Standalone NetBox deployment playbook +├── hosts # Inventory file +├── ansible.cfg # Ansible configuration +├── requirements.yml # Collection and role dependencies +├── group_vars/ # Group-specific variables +│ ├── all/ # Global variables +│ ├── bind9_servers/ # BIND9 zone configurations +│ └── resolvers/ # Resolver configurations +├── host_vars/ # Host-specific variables +├── vars/ # Legacy base variables +├── roles/ # Ansible roles (26 roles) +│ ├── base/ # Base configuration (users, SSH, system) +│ ├── general/ # General system configurations +│ ├── caddy/ # Caddy web server +│ ├── firewall/ # UFW/firewalld management +│ ├── ns/ # BIND9 nameserver +│ ├── resolvers/ # Unbound DNS resolver +│ ├── tailscale/ # Tailscale VPN +│ ├── monitor/ # Icinga2 monitoring +│ ├── prometheus/ # Prometheus monitoring stack +│ └── ... # Other roles (see playbook.yml for all) +├── baseline/ # Proxmox baseline configuration +├── fact_cache/ # Ansible fact cache (gitignored) +└── findings.md # Audit findings and recommendations ## Quick Start @@ -26,8 +39,8 @@ This repository contains Ansible playbooks and roles for managing infrastructure # For hosts with existing user access make bootstrap-init HOSTNAME=hostname ANSIBLE_HOST=ip_address -# For hosts with only root access -make bootstrap-init-root HOSTNAME=hostname ANSIBLE_HOST=ip_address +# Full bootstrap with network config and reboot +make bootstrap HOSTNAME=hostname ANSIBLE_HOST=ip_address ``` ### Run playbooks @@ -44,11 +57,17 @@ ansible-playbook -t caddy playbook.yml ## Inventory Groups -- `vntx_servers` - VNTX network services -- `app_servers` - Application servers -- `home_servers` - Home network devices -- `tailscale_home` - Devices using Tailscale VPN +- `vntx_servers` - VNTX network services (logs, radius, vpn, netbox, unimus, monitor, librenms, uisp) +- `home_servers` - Home network services (skippy, mail, dokku, aprs, staging, prom) +- `bind9_servers` - BIND9 authoritative nameservers +- `resolvers` - Unbound DNS resolvers - `caddy_servers` - Servers running Caddy web server +- `monitoring_servers` - Icinga2 monitoring master +- `prometheus_servers` - Prometheus monitoring stack +- `postgresql_servers` - PostgreSQL database servers +- `proxmox_servers` - Proxmox virtualization hosts + +See `hosts` file for the full inventory. ## Key Features @@ -57,4 +76,11 @@ ansible-playbook -t caddy playbook.yml - Role-based configuration management - Support for multiple OS families (Debian, Ubuntu, AlmaLinux) - Tailscale VPN integration -- Caddy web server with reverse proxy configuration +- Caddy web server with automatic SSL +- BIND9 authoritative DNS with DNSSEC +- Unbound DNS resolvers +- Icinga2 monitoring with PagerDuty integration +- Prometheus/Grafana/Loki monitoring stack +- NetBox IPAM/DCIM +- Proxmox VM provisioning +- LibreNMS network monitoring diff --git a/ansible/findings.md b/ansible/findings.md new file mode 100644 index 0000000..548c51f --- /dev/null +++ b/ansible/findings.md @@ -0,0 +1,125 @@ +# Ansible Repo Audit — Findings + +> Generated 2026-06-04 after auditing ~70 role files, 7 playbooks/configs, 21 host_vars, and 50+ templates. + +## Completed Fixes + +- **Removed all Forgejo references** — deleted `roles/forgejo/`, removed forgejo play from `playbook.yml`, removed `forgejo_servers` group from `hosts`, removed forgejo vars from `host_vars/git.mcintire.me.yml`, removed docker-mirror CNAME from DNS zone. +- **Fixed hardcoded SSH private key paths** — replaced all 20 occurrences of `/Users/graham/.ssh/id_ed25519` and `/Users/graham/.ssh/ansible` with `ansible_ssh_private_key_file: "{{ lookup('env', 'ANSIBLE_SSH_PRIVATE_KEY_FILE') | default('~/.ssh/ansible', true) }}"` in `group_vars/all/all.yml`. Set `ANSIBLE_SSH_PRIVATE_KEY_FILE` env var to override. +- **Fixed `community.mysql` collection** — added to `requirements.yml` and installed (fixes monitor role crash). +- **Removed broken `setup-user` Makefile target** — referenced non-existent `setup-user.sh`. +- **Fixed tracking issues** — `git rm --cached` for 5 `.DS_Store` files and `.vscode/settings.json`; added `.ansible/` to `.gitignore`. +- **Fixed stale documentation** — updated `CLAUDE.md` and `README.md` to reflect actual playbook structure, roles, inventory groups, and collections. + +--- + +## 🔴 Security (fix immediately) + +| # | Issue | Location | +|---|-------|----------| +| 1 | **Plaintext secrets in `.envrc`** — Tailscale auth key, PowerDNS API key, PostgreSQL password, Proxmox root password in plaintext on disk. Use `ansible-vault` or a secrets manager. | `.envrc:3,6,9,14` | +| 2 | **Hardcoded cloud-init password** — `cipassword` in plaintext for BIND9 VM. Anyone with repo access can SSH in as `debian`. | `playbook.yml:159` | +| 3 | **Hardcoded SSH public key** — Same `ed25519` key in playbook, `setup-host.sh`, and `base/files/ansible.pub`. Not vaulted. Rotate + move to vault. | `playbook.yml:106`, `setup-host.sh:17`, `base/files/ansible.pub` | + +--- + +## 🔴 Broken Infrastructure (will fail at runtime) + +| # | Issue | Location | +|---|-------|----------| +| 5 | **`general.yml` does not exist** — Referenced by 3 Makefile targets plus docs. Content was merged into `playbook.yml` but Makefile was never updated. | `Makefile:40,56,68` | +| 6 | **No `Dockerfile` at repo root** — All `build-*`, `run-*`, `push-*` Makefile targets fail. `base-latest`/`base-local` reference non-existent sub-targets. | `Makefile:3-30` | +| 8 | **`geerlingguy.postgresql` not in `requirements.yml`** — Role referenced in `playbook.yml:73` for `postgresql_servers` but not installable via `ansible-galaxy`. | `playbook.yml:73`, `requirements.yml` | +| 9 | **`alpine` role referenced but doesn't exist** — `include_role: name=alpine` will crash on any Alpine host. | `roles/base/tasks/main.yml:46-48` | +| 10 | **`db.aprs.me` has host_vars but no inventory entry** — Orphaned host_vars, Ansible never loads them. | `host_vars/db.aprs.me.yml`, `hosts` | + +--- + +## 🔴 Runtime Crashes (undefined template variables) + +| # | Issue | Location | +|---|-------|----------| +| 12 | **`ntpserver` undefined** — No default. Inconsistent with `base.ntp.server` used elsewhere. | `roles/base/templates/ntp.conf.j2:45` | +| 13 | **`template_run_date` undefined** — No default on `.strftime()` call. MOTD template crashes. | `roles/general/templates/etc/motd.j2:2` | +| 14 | **`deb_mirror` undefined** — No default, 4 references across the template. | `roles/general/templates/etc/apt/sources.list.j2` | +| 15 | **`sshd.*` dict entirely undefined** — 5 nested references (`permit_root_login`, `forwarding.*`) with no defaults. | `roles/general/templates/etc/ssh/sshd_config.j2:25,61-64` | +| 16 | **`interfaces` undefined** — No default guard on `{% if interfaces | length > 0 %}`. | `roles/general/templates/etc/network/interfaces.j2:8` | +| 17 | **`nfs_exports` undefined** — No default. Only defined in `skippy.w5isp.com.yml`. Crashes on other hosts. | `roles/general/templates/etc/exports.j2:3` | + +--- + +## 🟡 Logic Bugs + +| # | Issue | Location | +|---|-------|----------| +| 18 | **Firewall role runs twice** on every non-Proxmox host — once via `base` role's `include_role` and once via explicit firewall play. | `playbook.yml:18-25`, `roles/base/tasks/main.yml:50-55` | +| 19 | **SSH `-t` flag in wrong position** — Placed after hostname where it's treated as a remote command, not a local SSH option. | `Makefile:43,65` | +| 20 | **`ansible_user` in `[ssh_connection]` section** — Silently ignored by Ansible. Should be `remote_user` under `[defaults]`. | `ansible.cfg:32` | +| 21 | **`run.sh` masks playbook failures** — `tee` pipeline without `set -o pipefail` always exits 0. | `run.sh:18` | +| 22 | **`playbook_handlers.yml` is orphaned** — Defines `Restart firewalld` handler but is never imported by any playbook. | `playbook_handlers.yml` | +| 23 | **`changed_when: true` on idempotent commands** — `removes` prevents re-execution but `changed_when` overrides natural detection. | `roles/debian/tasks/main.yml:5`, `roles/general/tasks/udp-gro-fix.yml:27`, `roles/mailcow/tasks/main.yml:156` | +| 24 | **`run-local` mounts wrong path** — `${PWD}/run/fact_cache` doesn't exist. `dirs` creates `tmp/fact_cache` which is never used. | `Makefile:10,34` | +| 25 | **`TAILSCALE_AUTHKEY` vs `TAILSCALE_KEY` mismatch** — `.envrc` exports `TAILSCALE_AUTHKEY` but docs say role expects `TAILSCALE_KEY`. | `.envrc:3` vs `CLAUDE.md` | +| 26 | **`bootstrap.yml` second play unconditionally uses `become_method: sudo`** — Will hang if `graham` needs sudo password and `-K` not provided. | `bootstrap.yml:71-81` | +| 27 | **`mail.mcintire.me` and `git.mcintire.me` use bare `ansible_host=mail`/`ansible_host=git`** — DNS resolution depends on control node's search domain. | `hosts:24,51` | +| 28 | **Variable naming inconsistency** — Some templates use flat names (`nameservers`), some use nested (`network.nameservers`). | `resolv.conf.j2` vs `group_vars/all/all.yml` | + +--- + +## 🟡 Best Practice / Lint Violations + +| # | Issue | Location | +|---|-------|----------| +| 29 | **~100+ non-FQCN module references** — `apt:`, `service:`, `template:` instead of `ansible.builtin.*` throughout every role. | All roles | +| 30 | **`mode` values without proper quoting** — `644`, `0755`, `00644` used instead of `'0644'`, `'0755'`. | Multiple files | +| 31 | **`become: yes` / `gather_facts: no`** — Uses deprecated `yes`/`no` forms instead of `true`/`false`. | `playbook.yml`, `bootstrap.yml`, `netbox.yml` | +| 32 | **`inject_facts_as_vars` is deprecated** — Will be removed in future Ansible. | `ansible.cfg:3` | +| 33 | **Tasks missing `name:`** — Several unnamed task lists. | `roles/base/tasks/users.yml`, `roles/general/tasks/debian/motd.yml`, `roles/debug/tasks/main.yml` | +| 34 | **`partial-become` bug** — `become_user: librenms` without `become: yes`. | `roles/librenms/tasks/main.yml:78` | +| 35 | **`risky-shell-pipe` without pipefail** | `roles/general/tasks/udp-gro-fix.yml:13` | +| 36 | **`.ansible-lint` config is minimal** — Profile `min`, no excluded paths, no `warn_list`. Skips deprecated rule `403`. | `.ansible-lint` | + +--- + +## 🟡 Dead Code & Stale Files + +| # | Issue | Location | +|---|-------|----------| +| 37 | **`icinga2-container/` and `debug/` roles exist but never referenced** in any playbook. | `roles/icinga2-container/`, `roles/debug/` | +| 38 | **`mailcow` and `syncthing` roles exist but no play applies them.** | `roles/mailcow/`, `roles/syncthing/` | +| 39 | **`geerlingguy.docker` and `geerlingguy.kubernetes` never used** in any playbook. | `requirements.yml:15-19` | +| 40 | **`graylog2.graylog` and `bertvv.bind` never used** — Entire `roles/requirements.yml` appears legacy. | `roles/requirements.yml` | +| 41 | **`collections/requirements.yml` is redundant** — Lists `ansible.posix` and `netbox.netbox` without version pins. | `collections/requirements.yml` | +| 42 | **49/56 fact_cache files are stale** — 40 use old `s1_` naming convention, 9 are decommissioned hosts. | `fact_cache/` | +| 43 | **`home_cluster` and `dns_servers` groups** — Defined but never targeted by any play. | `hosts` | +| 44 | **`node_exporter_servers` is a pure alias** for `prometheus_servers` (1 host). | `hosts` | + +--- + +## 🟢 Previously Fixed + +| # | Issue | Fix | +|---|-------|-----| +| 4 | Hardcoded Forgejo runner token in host_vars | Deleted with forgejo cleanup | +| 7 | `setup-user.sh` doesn't exist | Removed broken Makefile target | +| 11 | `community.mysql.mysql_db` module not found | Added `community.mysql` to `requirements.yml` and installed | +| 45 | 5 `.DS_Store` files tracked by git | `git rm --cached` | +| 46 | `.vscode/settings.json` tracked despite gitignore | `git rm --cached` | +| 47 | `.ansible/` directory not in `.gitignore` | Added to `.gitignore` | +| 48 | Stale `CLAUDE.md` (references `general.yml`, missing roles, wrong commands) | Rewritten with accurate playbooks, roles, collections, commands | +| 49 | Stale `README.md` (wrong directory tree, incomplete groups) | Rewritten with accurate structure and inventory groups | + +--- + +## Recommended Top 10 Fixes + +1. **Rotate all 4 plaintext secrets in `.envrc`** and move to `ansible-vault` +2. **Add `geerlingguy.postgresql` to `requirements.yml`** — will crash otherwise +3. **Restore `general.yml` or update Makefile/docs** to point to `playbook.yml` +4. **Add defaults for 4 undefined template variables** (`ntpserver`, `template_run_date`, `deb_mirror`, `sshd.*`) — will crash at runtime +5. **Remove `alpine` role reference** in `roles/base/tasks/main.yml` or create the role +6. **Fix SSH `-t` flag placement** in Makefile reboot targets +7. **Fix `ansible.cfg`** — move `ansible_user` to `[defaults]` as `remote_user` +8. **Add `set -o pipefail`** to `run.sh` +9. **Add `become: yes`** to the librenms clone task at `roles/librenms/tasks/main.yml:78` +10. Fix firewall role double-run or remove duplicate diff --git a/ansible/group_vars/all/all.yml b/ansible/group_vars/all/all.yml index a73836f..1ba950d 100644 --- a/ansible/group_vars/all/all.yml +++ b/ansible/group_vars/all/all.yml @@ -1,6 +1,9 @@ --- # Global variables for all hosts +# SSH key for Ansible connections - override per-host if needed +ansible_ssh_private_key_file: "{{ lookup('env', 'ANSIBLE_SSH_PRIVATE_KEY_FILE') | default('~/.ssh/ansible', true) }}" + # Timezone configuration timezone: America/Chicago diff --git a/ansible/group_vars/bind9_servers/mcintire.me.yml b/ansible/group_vars/bind9_servers/mcintire.me.yml index 16dc366..96e6c8c 100644 --- a/ansible/group_vars/bind9_servers/mcintire.me.yml +++ b/ansible/group_vars/bind9_servers/mcintire.me.yml @@ -27,7 +27,6 @@ mcintire_me_zone: - _acme-challenge.ha.mcintire.me. IN CNAME _acme-challenge.q1l09qiycnaagngmjsg1qas0rhqcfoou.ui.nabu.casa. - autodiscover.mcintire.me. IN CNAME mail.w5isp.com. - autoconfig.mcintire.me. IN CNAME mail.w5isp.com. - - docker-mirror.mcintire.me. IN CNAME git.mcintire.me. - em977211.mcintire.me. IN CNAME return.smtp2go.net. - s977211._domainkey.mcintire.me. IN CNAME dkim.smtp2go.net. - link.mcintire.me. IN CNAME track.smtp2go.net. diff --git a/ansible/group_vars/proxmox_servers.yml b/ansible/group_vars/proxmox_servers.yml index a0e83d7..8944bd5 100644 --- a/ansible/group_vars/proxmox_servers.yml +++ b/ansible/group_vars/proxmox_servers.yml @@ -1,7 +1,6 @@ --- ansible_user: root ansible_python_interpreter: /usr/bin/python3 -ansible_ssh_private_key_file: /Users/graham/.ssh/id_ed25519 ansible_ssh_common_args: '-o StrictHostKeyChecking=accept-new' firewall_enabled: false diff --git a/ansible/host_vars/aprs.w5isp.com.yml b/ansible/host_vars/aprs.w5isp.com.yml index dfed613..bb565cb 100644 --- a/ansible/host_vars/aprs.w5isp.com.yml +++ b/ansible/host_vars/aprs.w5isp.com.yml @@ -2,7 +2,6 @@ ansible_user: graham ansible_host: 204.110.191.232 ansible_python_interpreter: /usr/bin/python3 -ansible_ssh_private_key_file: /Users/graham/.ssh/id_ed25519 ansible_ssh_common_args: '-o StrictHostKeyChecking=accept-new' firewall_default_incoming: allow diff --git a/ansible/host_vars/db.aprs.me.yml b/ansible/host_vars/db.aprs.me.yml index f03dbbb..15d82fa 100644 --- a/ansible/host_vars/db.aprs.me.yml +++ b/ansible/host_vars/db.aprs.me.yml @@ -2,7 +2,6 @@ ansible_user: graham ansible_host: 10.0.15.22 ansible_python_interpreter: /usr/bin/python3 -ansible_ssh_private_key_file: /Users/graham/.ssh/id_ed25519 ansible_ssh_common_args: '-o StrictHostKeyChecking=accept-new' firewall_enabled: false diff --git a/ansible/host_vars/db.w5isp.com.yml b/ansible/host_vars/db.w5isp.com.yml index a734047..fc80676 100644 --- a/ansible/host_vars/db.w5isp.com.yml +++ b/ansible/host_vars/db.w5isp.com.yml @@ -2,7 +2,6 @@ ansible_user: graham ansible_host: 10.0.15.30 ansible_python_interpreter: /usr/bin/python3 -ansible_ssh_private_key_file: /Users/graham/.ssh/id_ed25519 ansible_ssh_common_args: '-o StrictHostKeyChecking=accept-new' firewall_trusted_subnets: diff --git a/ansible/host_vars/dokku.w5isp.com.yml b/ansible/host_vars/dokku.w5isp.com.yml index 80e258b..03d3f2d 100644 --- a/ansible/host_vars/dokku.w5isp.com.yml +++ b/ansible/host_vars/dokku.w5isp.com.yml @@ -2,7 +2,6 @@ ansible_user: ansible ansible_host: 204.110.191.218 ansible_python_interpreter: /usr/bin/python3 -ansible_ssh_private_key_file: /Users/graham/.ssh/ansible ansible_ssh_common_args: '-o StrictHostKeyChecking=accept-new' firewall_allow_rules: diff --git a/ansible/host_vars/git.mcintire.me.yml b/ansible/host_vars/git.mcintire.me.yml index 2aca7cf..9f901ba 100644 --- a/ansible/host_vars/git.mcintire.me.yml +++ b/ansible/host_vars/git.mcintire.me.yml @@ -1,6 +1,5 @@ --- ansible_user: ansible -ansible_ssh_private_key_file: /Users/graham/.ssh/id_ed25519 ansible_python_interpreter: /usr/bin/python3 ansible_ssh_common_args: '-o StrictHostKeyChecking=accept-new' public_ip: 172.245.56.83 @@ -19,14 +18,6 @@ firewall_allow_rules: - port: 443 proto: tcp comment: HTTPS - - port: 2222 - proto: tcp - comment: Forgejo SSH - -# Forgejo runner -forgejo_runner_token: "I7rqgwumFl3BjuXnaEfroto7RHxGhsIUzM0lgMmM" -forgejo_runner_name: "vm1-runner" - # This server is a secondary/slave nameserver bind_zone_role: secondary diff --git a/ansible/host_vars/librenms.vntx.net.yml b/ansible/host_vars/librenms.vntx.net.yml index 1e11aa2..4e64943 100644 --- a/ansible/host_vars/librenms.vntx.net.yml +++ b/ansible/host_vars/librenms.vntx.net.yml @@ -2,7 +2,6 @@ ansible_user: graham ansible_host: 204.110.191.227 ansible_python_interpreter: /usr/bin/python3 -ansible_ssh_private_key_file: /Users/graham/.ssh/id_ed25519 ansible_ssh_common_args: '-o StrictHostKeyChecking=accept-new' firewall_allow_rules: diff --git a/ansible/host_vars/logs.vntx.net.yml b/ansible/host_vars/logs.vntx.net.yml index e4bbf51..8debaf7 100644 --- a/ansible/host_vars/logs.vntx.net.yml +++ b/ansible/host_vars/logs.vntx.net.yml @@ -2,5 +2,4 @@ ansible_user: ansible ansible_host: 204.110.191.229 ansible_python_interpreter: /usr/bin/python3 -ansible_ssh_private_key_file: /Users/graham/.ssh/ansible ansible_ssh_common_args: '-o StrictHostKeyChecking=accept-new' diff --git a/ansible/host_vars/monitor.vntx.net.yml b/ansible/host_vars/monitor.vntx.net.yml index fea98d1..5f93679 100644 --- a/ansible/host_vars/monitor.vntx.net.yml +++ b/ansible/host_vars/monitor.vntx.net.yml @@ -2,7 +2,6 @@ ansible_user: graham ansible_host: 204.110.191.241 ansible_python_interpreter: /usr/bin/python3 -ansible_ssh_private_key_file: /Users/graham/.ssh/id_ed25519 ansible_ssh_common_args: '-o StrictHostKeyChecking=accept-new' firewall_allow_rules: diff --git a/ansible/host_vars/netbox.vntx.net.yml b/ansible/host_vars/netbox.vntx.net.yml index ed8c98f..f3cabdb 100644 --- a/ansible/host_vars/netbox.vntx.net.yml +++ b/ansible/host_vars/netbox.vntx.net.yml @@ -4,7 +4,6 @@ ansible_user: graham ansible_host: 204.110.191.243 ansible_python_interpreter: /usr/bin/python3 -ansible_ssh_private_key_file: /Users/graham/.ssh/id_ed25519 ansible_ssh_common_args: '-o StrictHostKeyChecking=accept-new' # This host's network is configured out of band; don't let the general role diff --git a/ansible/host_vars/ns1.as393837.net.yml b/ansible/host_vars/ns1.as393837.net.yml index 54c6120..22b0ba1 100644 --- a/ansible/host_vars/ns1.as393837.net.yml +++ b/ansible/host_vars/ns1.as393837.net.yml @@ -1,6 +1,5 @@ --- ansible_user: debian -ansible_ssh_private_key_file: /Users/graham/.ssh/id_ed25519 ansible_python_interpreter: /usr/bin/python3 ansible_ssh_common_args: '-o StrictHostKeyChecking=accept-new' public_ip: 204.110.191.222 diff --git a/ansible/host_vars/prom.w5isp.com.yml b/ansible/host_vars/prom.w5isp.com.yml index 119bbb1..c1354f0 100644 --- a/ansible/host_vars/prom.w5isp.com.yml +++ b/ansible/host_vars/prom.w5isp.com.yml @@ -2,7 +2,6 @@ ansible_user: ansible ansible_host: 10.0.15.31 ansible_python_interpreter: /usr/bin/python3 -ansible_ssh_private_key_file: /Users/graham/.ssh/ansible ansible_ssh_common_args: '-o StrictHostKeyChecking=accept-new' network: diff --git a/ansible/host_vars/radius.vntx.net.yml b/ansible/host_vars/radius.vntx.net.yml index 3adcdcd..3e17a68 100644 --- a/ansible/host_vars/radius.vntx.net.yml +++ b/ansible/host_vars/radius.vntx.net.yml @@ -2,7 +2,6 @@ ansible_user: graham ansible_host: 204.110.191.248 ansible_python_interpreter: /usr/bin/python3 -ansible_ssh_private_key_file: /Users/graham/.ssh/id_ed25519 ansible_ssh_common_args: '-o StrictHostKeyChecking=accept-new' firewall_allow_rules: diff --git a/ansible/host_vars/resolver1.vntx.net.yml b/ansible/host_vars/resolver1.vntx.net.yml index 4a4ed77..20fd506 100644 --- a/ansible/host_vars/resolver1.vntx.net.yml +++ b/ansible/host_vars/resolver1.vntx.net.yml @@ -2,5 +2,4 @@ ansible_user: graham ansible_host: 204.110.191.240 ansible_python_interpreter: /usr/bin/python3 -ansible_ssh_private_key_file: /Users/graham/.ssh/id_ed25519 ansible_ssh_common_args: '-o StrictHostKeyChecking=accept-new' diff --git a/ansible/host_vars/resolver2.vntx.net.yml b/ansible/host_vars/resolver2.vntx.net.yml index 5aa0a68..f915653 100644 --- a/ansible/host_vars/resolver2.vntx.net.yml +++ b/ansible/host_vars/resolver2.vntx.net.yml @@ -2,5 +2,4 @@ ansible_user: graham ansible_host: 204.110.191.250 ansible_python_interpreter: /usr/bin/python3 -ansible_ssh_private_key_file: /Users/graham/.ssh/id_ed25519 ansible_ssh_common_args: '-o StrictHostKeyChecking=accept-new' diff --git a/ansible/host_vars/skippy.w5isp.com.yml b/ansible/host_vars/skippy.w5isp.com.yml index 1202266..7970484 100644 --- a/ansible/host_vars/skippy.w5isp.com.yml +++ b/ansible/host_vars/skippy.w5isp.com.yml @@ -2,7 +2,6 @@ ansible_user: ansible ansible_host: skippy ansible_python_interpreter: /usr/bin/python3 -ansible_ssh_private_key_file: /Users/graham/.ssh/ansible ansible_ssh_common_args: '-o StrictHostKeyChecking=accept-new' network: diff --git a/ansible/host_vars/staging.towerops.net.yml b/ansible/host_vars/staging.towerops.net.yml index 0d6197c..b2c10c7 100644 --- a/ansible/host_vars/staging.towerops.net.yml +++ b/ansible/host_vars/staging.towerops.net.yml @@ -2,7 +2,6 @@ ansible_user: graham ansible_host: staging ansible_python_interpreter: /usr/bin/python3 -ansible_ssh_private_key_file: /Users/graham/.ssh/id_ed25519 ansible_ssh_common_args: '-o StrictHostKeyChecking=accept-new' firewall_allow_rules: diff --git a/ansible/host_vars/uisp.vntx.net.yml b/ansible/host_vars/uisp.vntx.net.yml index eed7578..554dba6 100644 --- a/ansible/host_vars/uisp.vntx.net.yml +++ b/ansible/host_vars/uisp.vntx.net.yml @@ -2,7 +2,6 @@ ansible_user: graham ansible_host: 204.110.191.224 ansible_python_interpreter: /usr/bin/python3 -ansible_ssh_private_key_file: /Users/graham/.ssh/id_ed25519 ansible_ssh_common_args: '-o StrictHostKeyChecking=accept-new' firewall_allow_rules: diff --git a/ansible/host_vars/unimus.vntx.net.yml b/ansible/host_vars/unimus.vntx.net.yml index 960f7eb..ff4f1a3 100644 --- a/ansible/host_vars/unimus.vntx.net.yml +++ b/ansible/host_vars/unimus.vntx.net.yml @@ -2,5 +2,4 @@ ansible_user: ansible ansible_host: 204.110.191.238 ansible_python_interpreter: /usr/bin/python3 -ansible_ssh_private_key_file: /Users/graham/.ssh/ansible ansible_ssh_common_args: '-o StrictHostKeyChecking=accept-new' diff --git a/ansible/host_vars/vpn.vntx.net.yml b/ansible/host_vars/vpn.vntx.net.yml index 65d4b08..3db1a25 100644 --- a/ansible/host_vars/vpn.vntx.net.yml +++ b/ansible/host_vars/vpn.vntx.net.yml @@ -2,7 +2,6 @@ ansible_user: ansible ansible_host: 204.110.191.247 ansible_python_interpreter: /usr/bin/python3 -ansible_ssh_private_key_file: /Users/graham/.ssh/ansible ansible_ssh_common_args: '-o StrictHostKeyChecking=accept-new' firewall_trusted_subnets: diff --git a/ansible/hosts b/ansible/hosts index 278a2f9..733c71d 100755 --- a/ansible/hosts +++ b/ansible/hosts @@ -53,9 +53,6 @@ git.mcintire.me ansible_host=git [dns_servers:children] bind9_servers -[forgejo_servers] -git.mcintire.me - [uisp_servers] uisp.vntx.net diff --git a/ansible/playbook.yml b/ansible/playbook.yml index de2282b..ab9a8eb 100644 --- a/ansible/playbook.yml +++ b/ansible/playbook.yml @@ -206,15 +206,6 @@ tags: - general -- name: Configure Forgejo servers - hosts: forgejo_servers - become: yes - gather_facts: true - tags: - - forgejo - roles: - - forgejo - - name: Configure LibreNMS servers hosts: librenms_servers become: yes diff --git a/ansible/requirements.yml b/ansible/requirements.yml index baa49de..1155b85 100644 --- a/ansible/requirements.yml +++ b/ansible/requirements.yml @@ -11,6 +11,8 @@ collections: version: ">=3.0.0" # Required for PostgreSQL management - name: community.proxmox version: ">=1.0.0" # Required for Proxmox VM management + - name: community.mysql + version: ">=3.0.0" # Required for Icinga2 MySQL management roles: - name: geerlingguy.docker diff --git a/ansible/roles/.DS_Store b/ansible/roles/.DS_Store deleted file mode 100644 index b03ace0..0000000 Binary files a/ansible/roles/.DS_Store and /dev/null differ diff --git a/ansible/roles/forgejo/defaults/main.yml b/ansible/roles/forgejo/defaults/main.yml deleted file mode 100644 index d808530..0000000 --- a/ansible/roles/forgejo/defaults/main.yml +++ /dev/null @@ -1,16 +0,0 @@ ---- -forgejo_home: /opt/forgejo -forgejo_version: "15.0.0" -forgejo_http_port: 3000 -forgejo_ssh_port: 2222 -forgejo_domain: git.mcintire.me -forgejo_root_url: "https://{{ forgejo_domain }}" - -# App settings -forgejo_app_name: "Forgejo" - -# Runner settings -forgejo_runner_version: "12.8.2" -forgejo_runner_token: "" -forgejo_runner_name: "default-runner" -forgejo_runner_labels: "docker:docker://node:20-bookworm,ubuntu-latest:docker://ubuntu:latest,ubuntu-22.04:docker://ubuntu:22.04" diff --git a/ansible/roles/forgejo/handlers/main.yml b/ansible/roles/forgejo/handlers/main.yml deleted file mode 100644 index 979ade3..0000000 --- a/ansible/roles/forgejo/handlers/main.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -- name: restart forgejo - systemd: - name: forgejo - state: restarted - daemon_reload: true - -- name: restart caddy - systemd: - name: caddy - state: reloaded diff --git a/ansible/roles/forgejo/tasks/main.yml b/ansible/roles/forgejo/tasks/main.yml deleted file mode 100644 index 0e5fc02..0000000 --- a/ansible/roles/forgejo/tasks/main.yml +++ /dev/null @@ -1,152 +0,0 @@ ---- -# Install Docker -- name: Install prerequisites for Docker - apt: - name: - - ca-certificates - - curl - - gnupg - - lsb-release - - git - state: present - update_cache: true - -- name: Add Docker's official GPG key - ansible.builtin.get_url: - url: https://download.docker.com/linux/debian/gpg - dest: /usr/share/keyrings/docker-archive-keyring.asc - mode: '0644' - -- name: Add Docker repository - ansible.builtin.deb822_repository: - name: docker - types: deb - uris: https://download.docker.com/linux/debian - suites: "{{ ansible_distribution_release }}" - components: stable - architectures: "{{ ansible_architecture | replace('x86_64', 'amd64') }}" - signed_by: /usr/share/keyrings/docker-archive-keyring.asc - state: present - -- name: Install Docker packages - apt: - name: - - docker-ce - - docker-ce-cli - - containerd.io - - docker-compose-plugin - state: present - update_cache: true - -- name: Ensure Docker service is started and enabled - systemd: - name: docker - state: started - enabled: true - -# Create Forgejo directories -- name: Create forgejo directories - file: - path: "{{ item }}" - state: directory - mode: '0755' - loop: - - "{{ forgejo_home }}" - - "{{ forgejo_home }}/data" - -- name: Create runner directory with correct permissions - file: - path: "{{ forgejo_home }}/runner" - state: directory - mode: '0777' - -- name: Deploy docker-compose file - template: - src: docker-compose.yml.j2 - dest: "{{ forgejo_home }}/docker-compose.yml" - mode: '0644' - notify: restart forgejo - -- name: Pull container images - command: docker compose pull - args: - chdir: "{{ forgejo_home }}" - register: pull_result - changed_when: "'Pulling' in pull_result.stdout or 'Downloaded' in pull_result.stderr" - -- name: Deploy systemd service for Forgejo - template: - src: forgejo.service.j2 - dest: /etc/systemd/system/forgejo.service - owner: root - group: root - mode: '0644' - notify: restart forgejo - -- name: Reload systemd daemon - systemd: - daemon_reload: true - -- name: Start and enable Forgejo service - systemd: - name: forgejo - state: started - enabled: true - -# Install and configure Caddy -- name: Check if Caddy GPG key exists - stat: - path: /usr/share/keyrings/caddy-stable-archive-keyring.asc - register: caddy_gpg_key - -- name: Add Caddy GPG key - ansible.builtin.get_url: - url: "https://dl.cloudsmith.io/public/caddy/stable/gpg.key" - dest: /usr/share/keyrings/caddy-stable-archive-keyring.asc - mode: '0644' - when: not caddy_gpg_key.stat.exists - -- name: Add Caddy repository - ansible.builtin.deb822_repository: - name: caddy-stable - types: deb - uris: https://dl.cloudsmith.io/public/caddy/stable/deb/debian - suites: any-version - components: main - signed_by: /usr/share/keyrings/caddy-stable-archive-keyring.asc - state: present - -- name: Install Caddy - apt: - name: caddy - state: present - update_cache: true - -- name: Configure Caddy for Forgejo - template: - src: Caddyfile.j2 - dest: /etc/caddy/Caddyfile - owner: root - group: root - mode: '0644' - notify: restart caddy - -- name: Ensure Caddy is started and enabled - systemd: - name: caddy - state: started - enabled: true - -- name: Wait for Forgejo to be ready - uri: - url: "http://localhost:{{ forgejo_http_port }}/" - method: GET - status_code: - - 200 - - 302 - validate_certs: false - timeout: 30 - register: result - until: result.status in [200, 302] - retries: 12 - delay: 5 diff --git a/ansible/roles/forgejo/templates/Caddyfile.j2 b/ansible/roles/forgejo/templates/Caddyfile.j2 deleted file mode 100644 index a79cef4..0000000 --- a/ansible/roles/forgejo/templates/Caddyfile.j2 +++ /dev/null @@ -1,3 +0,0 @@ -{{ forgejo_domain }} { - reverse_proxy localhost:{{ forgejo_http_port }} -} diff --git a/ansible/roles/forgejo/templates/docker-compose.yml.j2 b/ansible/roles/forgejo/templates/docker-compose.yml.j2 deleted file mode 100644 index 34bc282..0000000 --- a/ansible/roles/forgejo/templates/docker-compose.yml.j2 +++ /dev/null @@ -1,37 +0,0 @@ ---- -services: - forgejo: - image: codeberg.org/forgejo/forgejo:{{ forgejo_version }} - container_name: forgejo - restart: unless-stopped - environment: - - USER_UID=1000 - - USER_GID=1000 - - FORGEJO__server__DOMAIN={{ forgejo_domain }} - - FORGEJO__server__SSH_DOMAIN={{ forgejo_domain }} - - FORGEJO__server__ROOT_URL={{ forgejo_root_url }} - - FORGEJO__server__SSH_PORT={{ forgejo_ssh_port }} - - FORGEJO__server__SSH_LISTEN_PORT=22 - volumes: - - {{ forgejo_home }}/data:/data - - /etc/timezone:/etc/timezone:ro - - /etc/localtime:/etc/localtime:ro - ports: - - "127.0.0.1:{{ forgejo_http_port }}:3000" - - "{{ forgejo_ssh_port }}:22" - - runner: - image: code.forgejo.org/forgejo/runner:{{ forgejo_runner_version }} - container_name: forgejo-runner - restart: unless-stopped - user: root - depends_on: - - forgejo - environment: - - DOCKER_HOST=unix:///var/run/docker.sock - volumes: - - {{ forgejo_home }}/runner:/data - - /var/run/docker.sock:/var/run/docker.sock - - /etc/timezone:/etc/timezone:ro - - /etc/localtime:/etc/localtime:ro - command: ["sh", "-c", "if [ ! -f /data/.runner ]; then forgejo-runner register --no-interactive --instance {{ forgejo_root_url }} --token {{ forgejo_runner_token }} --name {{ forgejo_runner_name }} --labels '{{ forgejo_runner_labels }}'; fi; forgejo-runner daemon"] diff --git a/ansible/roles/forgejo/templates/forgejo.service.j2 b/ansible/roles/forgejo/templates/forgejo.service.j2 deleted file mode 100644 index a336a2d..0000000 --- a/ansible/roles/forgejo/templates/forgejo.service.j2 +++ /dev/null @@ -1,15 +0,0 @@ -[Unit] -Description=Forgejo Git Service -After=docker.service -Requires=docker.service - -[Service] -Type=oneshot -RemainAfterExit=yes -WorkingDirectory={{ forgejo_home }} -ExecStart=/usr/bin/docker compose up -d -ExecStop=/usr/bin/docker compose down -TimeoutStartSec=0 - -[Install] -WantedBy=multi-user.target diff --git a/ansible/roles/general/.DS_Store b/ansible/roles/general/.DS_Store deleted file mode 100644 index bcb5e3b..0000000 Binary files a/ansible/roles/general/.DS_Store and /dev/null differ diff --git a/ansible/roles/general/files/.DS_Store b/ansible/roles/general/files/.DS_Store deleted file mode 100644 index e412cbf..0000000 Binary files a/ansible/roles/general/files/.DS_Store and /dev/null differ diff --git a/ansible/roles/general/tasks/.DS_Store b/ansible/roles/general/tasks/.DS_Store deleted file mode 100644 index 812fc5b..0000000 Binary files a/ansible/roles/general/tasks/.DS_Store and /dev/null differ