cleanup: remove forgejo, fix ssh key paths, fix tracking issues, update docs

- Remove forgejo role, play, group, host_vars, and DNS references
- Replace hardcoded /Users/graham/.ssh/ paths with env var lookup
- Remove broken setup-user Makefile target
- Add community.mysql collection to requirements.yml
- Add .ansible/ to .gitignore
- git rm --cached .DS_Store files and .vscode/settings.json
- Update CLAUDE.md and README.md to reflect actual state
- Add findings.md with audit results
This commit is contained in:
Graham McIntire 2026-06-04 14:27:31 -05:00
parent 46f55cdad8
commit 6f0d308fea
No known key found for this signature in database
GPG key ID: F4ABF488E6029E59
42 changed files with 205 additions and 320 deletions

BIN
ansible/.DS_Store vendored

Binary file not shown.

3
ansible/.gitignore vendored
View file

@ -28,6 +28,9 @@ Thumbs.db
*.pem
vault-password.txt
# Downloaded Galaxy roles/collections
.ansible/
# Temporary files
tmp/
temp/

View file

@ -1,3 +0,0 @@
{
"ansible.python.interpreterPath": "/opt/homebrew/bin/python3"
}

View file

@ -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

View file

@ -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"

View file

@ -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

125
ansible/findings.md Normal file
View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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:

View file

@ -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:

View file

@ -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

View file

@ -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:

View file

@ -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'

View file

@ -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:

View file

@ -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

View file

@ -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

View file

@ -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:

View file

@ -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:

View file

@ -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'

View file

@ -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'

View file

@ -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:

View file

@ -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:

View file

@ -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:

View file

@ -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'

View file

@ -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:

View file

@ -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

View file

@ -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

View file

@ -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

Binary file not shown.

View file

@ -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"

View file

@ -1,11 +0,0 @@
---
- name: restart forgejo
systemd:
name: forgejo
state: restarted
daemon_reload: true
- name: restart caddy
systemd:
name: caddy
state: reloaded

View file

@ -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

View file

@ -1,3 +0,0 @@
{{ forgejo_domain }} {
reverse_proxy localhost:{{ forgejo_http_port }}
}

View file

@ -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"]

View file

@ -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

Binary file not shown.

Binary file not shown.

Binary file not shown.