Add playbooks/setup_awx_https.yml that deploys a host-level nginx
reverse proxy in front of the AWX LoadBalancer service, terminating
TLS on 443 and proxying to the existing HTTP service on 80.
Why a reverse proxy and not in-pod TLS: the AWX Operator only wires
nginx for HTTPS on the OpenShift Route passthrough code path
(ingress_type: route + route_tls_termination_mechanism: passthrough),
which requires the Route CRD and fails on k3s. The cluster has no
ingress controller either. A host nginx proxy is the lowest-risk
option and is trivially swappable when the internal CA / an ingress
controller + cert-manager arrive.
The self-signed cert (CN=tsys-awx.knel.net) carries SANs for the
FQDN, short hostname, and both LAN and Tailscale IPs. Re-run the
playbook to rotate the cert once the internal CA is rolled out.
Also update scripts/awx_create_job_templates.py to use https by
default and add AWX_VERIFY_TLS / AWX_CA_BUNDLE env vars so it works
with the self-signed cert now and verifies properly once the internal
CA bundle is distributed.
🤖 Generated with [Crush](https://github.com/charmassociates/crush)
Assisted-by: GLM-5 via Crush <crush@charm.land>
Add an explicit, top-of-file policy forbidding any secret, password,
token, API key, or SSH key from being committed to the repository in
any form (source, comments, examples, docs, commit messages).
Covers: environment-variable/vault sourcing, placeholder usage in
examples, pre-commit self-check, and the mandatory history-purge
procedure (git filter-repo --replace-text + force-push + credential
rotation) if a secret is ever introduced.
🤖 Generated with [Crush](https://github.com/charmassociates/crush)
Assisted-by: GLM-5 via Crush <crush@charm.land>
The AWX admin password was hardcoded in scripts/awx_create_job_templates.py.
Read credentials from environment variables instead (AWX_USER,
AWX_PASSWORD, AWX_URL) and fail loudly when AWX_PASSWORD is unset.
No credentials are stored in this repository.
🤖 Generated with [Crush](https://github.com/charmassociates/crush)
Assisted-by: GLM-5 via Crush <crush@charm.land>
Add .venv/ to .gitignore so the locally-bootstrapped Ansible tooling
(ansible-core, ansible-lint, yamllint) used for pre-push validation is
never accidentally committed.
🤖 Generated with [Crush](https://github.com/charmassociates/crush)
Assisted-by: GLM-5 via Crush <crush@charm.land>
Add scripts/awx_create_job_templates.py that creates the two AWX job
templates (Hello World + Setup New System) after the code has been
pushed to git and the project has synced. Run this once after cloning
the repo on a new AWX instance.
🤖 Generated with [Crush](https://github.com/charmassociates/crush)
Assisted-by: GLM-5 via Crush <crush@charm.land>
Port Modules/Security/secharden-audit-agents.sh.
Deploys hardened configurations for:
- auditd (log rotation, disk space actions, email alerts)
- systemd-journald (persistent storage)
- logrotate (weekly rotation, 4 weeks retention)
This role is disabled by default (run_security_audit: false) matching
the legacy script which was commented out of the run order.
🤖 Generated with [Crush](https://github.com/charmassociates/crush)
Assisted-by: GLM-5 via Crush <crush@charm.land>
Port Modules/Security/secharden-2fa.sh.
Configures TOTP two-factor authentication via Google Authenticator for:
- SSH (publickey + keyboard-interactive)
- Cockpit web interface (PAM with Google Authenticator)
- Webmin (if installed, TOTP provider enabled)
Includes:
- Backup of existing SSH, PAM, and Cockpit configs before changes
- PAM sshd and cockpit config deployment
- Per-user enrollment scaffolding (setup script + instructions for
root and localuser)
- SSH service validation before restart
🤖 Generated with [Crush](https://github.com/charmassociates/crush)
Assisted-by: GLM-5 via Crush <crush@charm.land>
Port Modules/Security/secharden-wazuh.sh.
Installs the Wazuh agent from the official apt repository with the
configured manager address. The agent package is held to prevent
uncontrolled upgrades. Skipped entirely on the Wazuh server host
(tsys-nsm) via the wazuh_server inventory group.
🤖 Generated with [Crush](https://github.com/charmassociates/crush)
Assisted-by: GLM-5 via Crush <crush@charm.land>
Port Modules/Security/secharden-ssh.sh.
Deploys:
- Authorized keys for root, localuser, subodev (conditional on existence)
- Hardened /etc/ssh/sshd_config (skipped on dev workstations)
- ssh-audit hardening drop-in for algorithm restrictions (skipped on
Ubuntu where it breaks openssh-server)
- Lockdown of sshd_config.d directory permissions
SSH service is validated (sshd -t) before restart.
🤖 Generated with [Crush](https://github.com/charmassociates/crush)
Assisted-by: GLM-5 via Crush <crush@charm.land>
Port Modules/OAM/oam-librenms.sh.
Deploys the check_mk agent and systemd socket for LibreNMS monitoring,
along with the local plugins: distro, dmi, dpkg, ntp-client,
os-updates, postfixdetailed, and postfix-queues.
🤖 Generated with [Crush](https://github.com/charmassociates/crush)
Assisted-by: GLM-5 via Crush <crush@charm.land>
Port global-systemServiceConfigurationFiles() and
global-postPackageConfiguration().
Manages:
- Global zsh config (/etc/zshrc)
- Mail aliases and postfix relay (local-only, smarthost to Cloudron)
- Static DNS resolv.conf (replaces systemd-resolved symlinks)
- rsyslog forwarding to LibreNMS (skipped on LibreNMS server itself)
- DHCP client config (skipped on DHCP servers pfv-netinfra-01/02)
- SNMP daemon config selected by host class (Pi/physical/Proxmox/VM)
- NTP client config (skipped on NTP server hosts)
- LLDP network discovery
- Cockpit disallowed-users
- Default user shells (zsh, conditional on user existence)
- Process accounting (accton)
- CPU governor on physical/Proxmox hosts (performance)
- tuned profile on VM guests (virtual-guest)
Infrastructure configs use Jinja2 templates parameterized by variables
in group_vars/all.yml.
🤖 Generated with [Crush](https://github.com/charmassociates/crush)
Assisted-by: GLM-5 via Crush <crush@charm.land>
Port PreflightCheck.sh and pi-detect.sh to the preflight role.
Detects at runtime:
- Physical Dell host (dmidecode, NOT Proxmox, NOT Pi)
- Proxmox VE host (dpkg-query proxmox-ve)
- Virtual guest (virt-what: hyperv/kvm)
- KVM guest specifically
- Raspberry Pi (device-tree model file)
- Distro: Debian, Ubuntu, Kali
- User existence: localuser, subodev
Derives from inventory groups:
- NTP server, DHCP server, DNS server
- LibreNMS server, Wazuh server
- Dev workstation
All facts are cacheable so downstream roles can branch on them without
re-running detection commands.
🤖 Generated with [Crush](https://github.com/charmassociates/crush)
Assisted-by: GLM-5 via Crush <crush@charm.land>
Add two playbooks:
- hello_world.yml: AWX smoke test that asserts Debian-family OS and
reports facts. Use this as the first Job Template to confirm AWX
can reach hosts, become root, and gather facts.
- setup_new_system.yml: Full host provisioning playbook that mirrors
the function call order of SetupNewSystem.sh. Each role is gated by
a run_* feature toggle so the same template can do partial runs.
🤖 Generated with [Crush](https://github.com/charmassociates/crush)
Assisted-by: GLM-5 via Crush <crush@charm.land>
Make explicit that agents must commit and push automatically after every
logical unit of work — never wait to be asked.
🤖 Generated with [Crush](https://github.com/charmassociates/crush)
Assisted-by: GLM-5 via Crush <crush@charm.land>
Add agent guidelines for AI assistants working on this repository:
- Document atomic commit requirements
- Specify conventional commit format with examples
- Require verbose, formatted commit messages
- Emphasize immediate commit/push behavior
🤖 Generated with [Crush](https://github.com/charmassociates/crush)
Assisted-by: GLM-5 via Crush <crush@charm.land>