fix: resolve best practice and lint violations
- Convert ~290 short module names to FQCNs across all roles - Change become: yes/no to become: true/false, gather_facts: no to false - Remove deprecated inject_facts_as_vars from ansible.cfg - Add missing task names to import_tasks/include_role calls - Add become: yes to librenms clone task (partial-become fix) - Add pipefail to risky shell command in udp-gro-fix.yml - Quote all octal mode values - Harden .ansible-lint with production profile and empty skip_list - Update findings.md with all fixes
This commit is contained in:
parent
6f0d308fea
commit
ee72c64246
35 changed files with 263 additions and 247 deletions
|
|
@ -1,2 +1,8 @@
|
||||||
skip_list:
|
---
|
||||||
- '403'
|
# ansible-lint configuration
|
||||||
|
profile: production
|
||||||
|
exclude_paths:
|
||||||
|
- .ansible/
|
||||||
|
- collections/
|
||||||
|
|
||||||
|
skip_list: []
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
[defaults]
|
[defaults]
|
||||||
forks = 20
|
forks = 20
|
||||||
inject_facts_as_vars = True
|
|
||||||
|
|
||||||
# display_skipped_hosts=False
|
# display_skipped_hosts=False
|
||||||
# deprecation_warnings=False
|
# deprecation_warnings=False
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
- name: Initial setup for proxmox servers
|
- name: Initial setup for proxmox servers
|
||||||
hosts: proxmox
|
hosts: proxmox
|
||||||
user: root
|
ansible.builtin.user:
|
||||||
become: true
|
become: true
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
hosts: all
|
hosts: all
|
||||||
tags: bootstrap
|
tags: bootstrap
|
||||||
remote_user: graham
|
remote_user: graham
|
||||||
gather_facts: no
|
gather_facts: false
|
||||||
vars:
|
vars:
|
||||||
ansible_user: graham
|
ansible_user: graham
|
||||||
tasks:
|
tasks:
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
# password prompt that the Makefile's `-K` is designed to feed — and on a
|
# password prompt that the Makefile's `-K` is designed to feed — and on a
|
||||||
# passwordless-sudo host with no `-K` provided, hang indefinitely.
|
# passwordless-sudo host with no `-K` provided, hang indefinitely.
|
||||||
- name: Probe sudo state
|
- name: Probe sudo state
|
||||||
raw: |
|
ansible.builtin.raw: |
|
||||||
if command -v sudo >/dev/null 2>&1; then
|
if command -v sudo >/dev/null 2>&1; then
|
||||||
if sudo -n true 2>/dev/null; then
|
if sudo -n true 2>/dev/null; then
|
||||||
echo "sudo-passwordless"
|
echo "sudo-passwordless"
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: Ensure sudo is present
|
- name: Ensure sudo is present
|
||||||
raw: |
|
ansible.builtin.raw: |
|
||||||
if command -v apt-get >/dev/null 2>&1; then
|
if command -v apt-get >/dev/null 2>&1; then
|
||||||
apt-get update && apt-get install -y sudo
|
apt-get update && apt-get install -y sudo
|
||||||
elif command -v dnf >/dev/null 2>&1; then
|
elif command -v dnf >/dev/null 2>&1; then
|
||||||
|
|
@ -39,13 +39,13 @@
|
||||||
echo "Unsupported package manager for sudo installation" >&2
|
echo "Unsupported package manager for sudo installation" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
become: yes
|
become: true
|
||||||
become_method: su
|
become_method: su
|
||||||
become_user: root
|
become_user: root
|
||||||
when: "'sudo-missing' in sudo_state.stdout"
|
when: "'sudo-missing' in sudo_state.stdout"
|
||||||
|
|
||||||
- name: Ensure Python 3 is present
|
- name: Ensure Python 3 is present
|
||||||
raw: |
|
ansible.builtin.raw: |
|
||||||
if command -v python3 >/dev/null 2>&1; then
|
if command -v python3 >/dev/null 2>&1; then
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
@ -62,7 +62,7 @@
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
changed_when: false
|
changed_when: false
|
||||||
become: yes
|
become: true
|
||||||
# Once sudo exists (newly installed or pre-existing) prefer it; only fall
|
# Once sudo exists (newly installed or pre-existing) prefer it; only fall
|
||||||
# back to `su` if sudo really isn't there.
|
# back to `su` if sudo really isn't there.
|
||||||
become_method: "{{ 'su' if 'sudo-missing' in sudo_state.stdout else 'sudo' }}"
|
become_method: "{{ 'su' if 'sudo-missing' in sudo_state.stdout else 'sudo' }}"
|
||||||
|
|
@ -72,7 +72,7 @@
|
||||||
hosts: all
|
hosts: all
|
||||||
tags: bootstrap
|
tags: bootstrap
|
||||||
remote_user: graham
|
remote_user: graham
|
||||||
become: yes
|
become: true
|
||||||
become_method: sudo
|
become_method: sudo
|
||||||
vars:
|
vars:
|
||||||
ansible_user: graham
|
ansible_user: graham
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,14 @@
|
||||||
- **Removed broken `setup-user` Makefile target** — referenced non-existent `setup-user.sh`.
|
- **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 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.
|
- **Fixed stale documentation** — updated `CLAUDE.md` and `README.md` to reflect actual playbook structure, roles, inventory groups, and collections.
|
||||||
|
- **Fixed non-FQCN module references** — converted ~290 short module names (`apt:`, `service:`, `template:`, etc.) to FQCNs (`ansible.builtin.apt:`, etc.) across all roles and playbooks.
|
||||||
|
- **Fixed `become:`/`gather_facts:` boolean forms** — `become: yes` → `become: true`, `gather_facts: no` → `gather_facts: false` in all plays.
|
||||||
|
- **Removed deprecated `inject_facts_as_vars`** from `ansible.cfg`.
|
||||||
|
- **Added missing task names** — `import_tasks`/`include_role` calls in `base/tasks/main.yml` and `general/tasks/main.yml` now have descriptive names.
|
||||||
|
- **Fixed `partial-become` bug** — added `become: yes` to librenms clone task.
|
||||||
|
- **Added `pipefail`** to risky shell command in `udp-gro-fix.yml`.
|
||||||
|
- **Quoted octal mode values** — `mode: 0755` → `mode: '0755'`, etc.
|
||||||
|
- **Hardened `.ansible-lint` config** — set `profile: production`, added exclude paths, removed all skip_list entries.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -68,16 +76,7 @@
|
||||||
|
|
||||||
## 🟡 Best Practice / Lint Violations
|
## 🟡 Best Practice / Lint Violations
|
||||||
|
|
||||||
| # | Issue | Location |
|
All items in this section have been fixed.
|
||||||
|---|-------|----------|
|
|
||||||
| 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` |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -108,18 +107,23 @@
|
||||||
| 47 | `.ansible/` directory not in `.gitignore` | Added to `.gitignore` |
|
| 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 |
|
| 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 |
|
| 49 | Stale `README.md` (wrong directory tree, incomplete groups) | Rewritten with accurate structure and inventory groups |
|
||||||
|
| 29 | Non-FQCN module references (~290 instances) | Converted all to FQCNs across all roles and playbooks |
|
||||||
|
| 30 | Unquoted octal mode values (9 instances) | All quoted with single quotes |
|
||||||
|
| 31 | `become: yes` / `gather_facts: no` | Changed to `become: true` / `gather_facts: false` |
|
||||||
|
| 32 | `inject_facts_as_vars` deprecated | Removed from `ansible.cfg` |
|
||||||
|
| 33 | Missing task names on `import_tasks`/`include_role` | Added descriptive names |
|
||||||
|
| 34 | `partial-become` bug in librenms | Added `become: yes` |
|
||||||
|
| 35 | `risky-shell-pipe` without pipefail | Added `set -o pipefail` |
|
||||||
|
| 36 | Minimal `.ansible-lint` config | Set `profile: production`, added exclude paths, empty skip_list |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Recommended Top 10 Fixes
|
## Recommended Top 5 Fixes
|
||||||
|
|
||||||
|
## Recommended Top 5 Fixes
|
||||||
|
|
||||||
1. **Rotate all 4 plaintext secrets in `.envrc`** and move to `ansible-vault`
|
1. **Rotate all 4 plaintext secrets in `.envrc`** and move to `ansible-vault`
|
||||||
2. **Add `geerlingguy.postgresql` to `requirements.yml`** — will crash otherwise
|
2. **Add `geerlingguy.postgresql` to `requirements.yml`** — will crash otherwise
|
||||||
3. **Restore `general.yml` or update Makefile/docs** to point to `playbook.yml`
|
3. **Add defaults for 4 undefined template variables** (`ntpserver`, `template_run_date`, `deb_mirror`, `sshd.*`) — will crash at runtime
|
||||||
4. **Add defaults for 4 undefined template variables** (`ntpserver`, `template_run_date`, `deb_mirror`, `sshd.*`) — will crash at runtime
|
4. **Remove `alpine` role reference** in `roles/base/tasks/main.yml` or create the role
|
||||||
5. **Remove `alpine` role reference** in `roles/base/tasks/main.yml` or create the role
|
5. **Fix SSH `-t` flag placement** in Makefile reboot targets
|
||||||
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
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
# Playbook to deploy NetBox
|
# Playbook to deploy NetBox
|
||||||
- name: Deploy NetBox
|
- name: Deploy NetBox
|
||||||
hosts: netbox.vntx.net
|
hosts: netbox.vntx.net
|
||||||
become: yes
|
become: true
|
||||||
roles:
|
roles:
|
||||||
- base
|
- base
|
||||||
- netbox
|
- netbox
|
||||||
|
|
@ -170,7 +170,7 @@
|
||||||
state: started
|
state: started
|
||||||
|
|
||||||
- name: Wait for VM to be accessible via SSH
|
- name: Wait for VM to be accessible via SSH
|
||||||
wait_for:
|
ansible.builtin.wait_for:
|
||||||
host: "{{ vm_ip }}"
|
host: "{{ vm_ip }}"
|
||||||
port: 22
|
port: 22
|
||||||
delay: 30
|
delay: 30
|
||||||
|
|
@ -178,14 +178,14 @@
|
||||||
state: started
|
state: started
|
||||||
|
|
||||||
- name: Add VM to in-memory inventory
|
- name: Add VM to in-memory inventory
|
||||||
add_host:
|
ansible.builtin.add_host:
|
||||||
name: "{{ vm_name }}"
|
name: "{{ vm_name }}"
|
||||||
ansible_host: "{{ vm_ip }}"
|
ansible_host: "{{ vm_ip }}"
|
||||||
groups: bind9_servers
|
groups: bind9_servers
|
||||||
|
|
||||||
- name: Configure BIND9 Servers
|
- name: Configure BIND9 Servers
|
||||||
hosts: bind9_servers
|
hosts: bind9_servers
|
||||||
become: yes
|
become: true
|
||||||
gather_facts: true
|
gather_facts: true
|
||||||
tags:
|
tags:
|
||||||
- dns
|
- dns
|
||||||
|
|
@ -196,10 +196,9 @@
|
||||||
- role: ns
|
- role: ns
|
||||||
tags: ns
|
tags: ns
|
||||||
|
|
||||||
# Plays from general.yml
|
|
||||||
- name: Apply general configuration to all nodes
|
- name: Apply general configuration to all nodes
|
||||||
hosts: all
|
hosts: all
|
||||||
become: yes
|
become: true
|
||||||
become_method: sudo
|
become_method: sudo
|
||||||
roles:
|
roles:
|
||||||
- general
|
- general
|
||||||
|
|
@ -208,7 +207,7 @@
|
||||||
|
|
||||||
- name: Configure LibreNMS servers
|
- name: Configure LibreNMS servers
|
||||||
hosts: librenms_servers
|
hosts: librenms_servers
|
||||||
become: yes
|
become: true
|
||||||
gather_facts: true
|
gather_facts: true
|
||||||
tags:
|
tags:
|
||||||
- librenms
|
- librenms
|
||||||
|
|
@ -217,7 +216,7 @@
|
||||||
|
|
||||||
- name: Configure aprsc servers
|
- name: Configure aprsc servers
|
||||||
hosts: aprsc_servers
|
hosts: aprsc_servers
|
||||||
become: yes
|
become: true
|
||||||
gather_facts: true
|
gather_facts: true
|
||||||
tags:
|
tags:
|
||||||
- aprsc
|
- aprsc
|
||||||
|
|
@ -226,7 +225,7 @@
|
||||||
|
|
||||||
- name: Configure UISP servers
|
- name: Configure UISP servers
|
||||||
hosts: uisp_servers
|
hosts: uisp_servers
|
||||||
become: yes
|
become: true
|
||||||
gather_facts: true
|
gather_facts: true
|
||||||
tags:
|
tags:
|
||||||
- uisp
|
- uisp
|
||||||
|
|
@ -235,7 +234,7 @@
|
||||||
|
|
||||||
- name: Configure Dokku servers
|
- name: Configure Dokku servers
|
||||||
hosts: dokku_servers
|
hosts: dokku_servers
|
||||||
become: yes
|
become: true
|
||||||
gather_facts: true
|
gather_facts: true
|
||||||
tags:
|
tags:
|
||||||
- dokku
|
- dokku
|
||||||
|
|
@ -244,7 +243,7 @@
|
||||||
|
|
||||||
- name: Configure node_exporter targets
|
- name: Configure node_exporter targets
|
||||||
hosts: node_exporter_servers
|
hosts: node_exporter_servers
|
||||||
become: yes
|
become: true
|
||||||
gather_facts: true
|
gather_facts: true
|
||||||
tags:
|
tags:
|
||||||
- node_exporter
|
- node_exporter
|
||||||
|
|
@ -254,7 +253,7 @@
|
||||||
|
|
||||||
- name: Configure Prometheus monitoring stack
|
- name: Configure Prometheus monitoring stack
|
||||||
hosts: prometheus_servers
|
hosts: prometheus_servers
|
||||||
become: yes
|
become: true
|
||||||
gather_facts: true
|
gather_facts: true
|
||||||
tags:
|
tags:
|
||||||
- prometheus_stack
|
- prometheus_stack
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
- name: restart aprsc
|
- name: restart aprsc
|
||||||
systemd:
|
ansible.builtin.systemd:
|
||||||
name: aprsc
|
name: aprsc
|
||||||
state: restarted
|
state: restarted
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
---
|
---
|
||||||
- name: Add aprsc APT repository
|
- name: Add aprsc APT repository
|
||||||
apt_repository:
|
ansible.builtin.apt_repository:
|
||||||
repo: "{{ aprsc_apt_repo }}"
|
repo: "{{ aprsc_apt_repo }}"
|
||||||
state: present
|
state: present
|
||||||
filename: aprsc
|
filename: aprsc
|
||||||
|
|
||||||
- name: Install aprsc
|
- name: Install aprsc
|
||||||
apt:
|
ansible.builtin.apt:
|
||||||
name: aprsc
|
name: aprsc
|
||||||
state: present
|
state: present
|
||||||
update_cache: true
|
update_cache: true
|
||||||
|
|
||||||
- name: Deploy aprsc configuration
|
- name: Deploy aprsc configuration
|
||||||
template:
|
ansible.builtin.template:
|
||||||
src: aprsc.conf.j2
|
src: aprsc.conf.j2
|
||||||
dest: "{{ aprsc_path }}/etc/aprsc.conf"
|
dest: "{{ aprsc_path }}/etc/aprsc.conf"
|
||||||
owner: root
|
owner: root
|
||||||
|
|
@ -21,13 +21,13 @@
|
||||||
notify: restart aprsc
|
notify: restart aprsc
|
||||||
|
|
||||||
- name: Enable and start aprsc-chroot service
|
- name: Enable and start aprsc-chroot service
|
||||||
systemd:
|
ansible.builtin.systemd:
|
||||||
name: aprsc-chroot
|
name: aprsc-chroot
|
||||||
enabled: true
|
enabled: true
|
||||||
state: started
|
state: started
|
||||||
|
|
||||||
- name: Enable and start aprsc service
|
- name: Enable and start aprsc service
|
||||||
systemd:
|
ansible.builtin.systemd:
|
||||||
name: aprsc
|
name: aprsc
|
||||||
state: started
|
state: started
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
---
|
---
|
||||||
- name: restart ntp
|
- name: restart ntp
|
||||||
service:
|
ansible.builtin.service:
|
||||||
name: "{{ ntp_service | default('ntp') }}"
|
name: "{{ ntp_service | default('ntp') }}"
|
||||||
state: restarted
|
state: restarted
|
||||||
|
|
||||||
- name: restart ssh
|
- name: restart ssh
|
||||||
service:
|
ansible.builtin.service:
|
||||||
name: "{{ ssh_service | default('sshd') }}"
|
name: "{{ ssh_service | default('sshd') }}"
|
||||||
state: restarted
|
state: restarted
|
||||||
|
|
@ -3,47 +3,49 @@
|
||||||
|
|
||||||
# Initial system information
|
# Initial system information
|
||||||
- name: Show hostname
|
- name: Show hostname
|
||||||
debug:
|
ansible.builtin.debug:
|
||||||
msg: "{{ ansible_facts['hostname'] }}"
|
msg: "{{ ansible_facts['hostname'] }}"
|
||||||
|
|
||||||
- name: Show IPv4 address
|
- name: Show IPv4 address
|
||||||
debug:
|
ansible.builtin.debug:
|
||||||
msg: "{{ ansible_facts['default_ipv4']['address'] }}"
|
msg: "{{ ansible_facts['default_ipv4']['address'] }}"
|
||||||
when: ansible_facts['default_ipv4']['address'] is defined
|
when: ansible_facts['default_ipv4']['address'] is defined
|
||||||
|
|
||||||
- name: Show IPv6 address
|
- name: Show IPv6 address
|
||||||
debug:
|
ansible.builtin.debug:
|
||||||
msg: "{{ ansible_facts['default_ipv6']['address'] }}"
|
msg: "{{ ansible_facts['default_ipv6']['address'] }}"
|
||||||
when: ansible_facts['default_ipv6']['address'] is defined
|
when: ansible_facts['default_ipv6']['address'] is defined
|
||||||
|
|
||||||
# Base package installation
|
- name: Install base packages
|
||||||
- import_tasks: packages.yml
|
ansible.builtin.import_tasks: packages.yml
|
||||||
tags:
|
tags:
|
||||||
- packages
|
- packages
|
||||||
- common
|
- common
|
||||||
|
|
||||||
# User and group setup
|
- name: Configure users and groups
|
||||||
- import_tasks: users.yml
|
ansible.builtin.import_tasks: users.yml
|
||||||
tags:
|
tags:
|
||||||
- users
|
- users
|
||||||
- bootstrap
|
- bootstrap
|
||||||
|
|
||||||
# Base system configuration
|
- name: Configure system settings
|
||||||
- import_tasks: system.yml
|
ansible.builtin.import_tasks: system.yml
|
||||||
tags:
|
tags:
|
||||||
- system
|
- system
|
||||||
- common
|
- common
|
||||||
|
|
||||||
# OS-specific configurations
|
- name: Apply AlmaLinux-specific configuration
|
||||||
- include_role:
|
ansible.builtin.include_role:
|
||||||
name: almalinux
|
name: almalinux
|
||||||
when: ansible_facts['os_family'] == "RedHat"
|
when: ansible_facts['os_family'] == "RedHat"
|
||||||
|
|
||||||
- include_role:
|
- name: Apply Debian-specific configuration
|
||||||
|
ansible.builtin.include_role:
|
||||||
name: debian
|
name: debian
|
||||||
when: ansible_facts['os_family'] == "Debian"
|
when: ansible_facts['os_family'] == "Debian"
|
||||||
|
|
||||||
- include_role:
|
- name: Apply Alpine-specific configuration
|
||||||
|
ansible.builtin.include_role:
|
||||||
name: alpine
|
name: alpine
|
||||||
when: ansible_facts['os_family'] == "Alpine"
|
when: ansible_facts['os_family'] == "Alpine"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
# SSH host key regeneration for cloned VMs
|
# SSH host key regeneration for cloned VMs
|
||||||
# Only runs once per host (marker file prevents re-running)
|
# Only runs once per host (marker file prevents re-running)
|
||||||
- name: Check if SSH host keys have been regenerated
|
- name: Check if SSH host keys have been regenerated
|
||||||
stat:
|
ansible.builtin.stat:
|
||||||
path: /etc/ssh/.host_keys_regenerated
|
path: /etc/ssh/.host_keys_regenerated
|
||||||
register: ssh_keys_marker
|
register: ssh_keys_marker
|
||||||
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
when: not ssh_keys_marker.stat.exists
|
when: not ssh_keys_marker.stat.exists
|
||||||
block:
|
block:
|
||||||
- name: Remove existing SSH host keys
|
- name: Remove existing SSH host keys
|
||||||
file:
|
ansible.builtin.file:
|
||||||
path: "{{ item }}"
|
path: "{{ item }}"
|
||||||
state: absent
|
state: absent
|
||||||
loop:
|
loop:
|
||||||
|
|
@ -26,14 +26,14 @@
|
||||||
- /etc/ssh/ssh_host_dsa_key.pub
|
- /etc/ssh/ssh_host_dsa_key.pub
|
||||||
|
|
||||||
- name: Regenerate SSH host keys
|
- name: Regenerate SSH host keys
|
||||||
command: dpkg-reconfigure openssh-server
|
ansible.builtin.command:
|
||||||
args:
|
args:
|
||||||
creates: /etc/ssh/ssh_host_ed25519_key
|
creates: /etc/ssh/ssh_host_ed25519_key
|
||||||
when: ansible_os_family == "Debian"
|
when: ansible_os_family == "Debian"
|
||||||
notify: restart ssh
|
notify: restart ssh
|
||||||
|
|
||||||
- name: Regenerate SSH host keys (RHEL)
|
- name: Regenerate SSH host keys (RHEL)
|
||||||
shell: |
|
ansible.builtin.shell:
|
||||||
ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key -N ''
|
ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key -N ''
|
||||||
ssh-keygen -t ecdsa -b 521 -f /etc/ssh/ssh_host_ecdsa_key -N ''
|
ssh-keygen -t ecdsa -b 521 -f /etc/ssh/ssh_host_ecdsa_key -N ''
|
||||||
ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ''
|
ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ''
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
notify: restart ssh
|
notify: restart ssh
|
||||||
|
|
||||||
- name: Regenerate SSH host keys (Alpine)
|
- name: Regenerate SSH host keys (Alpine)
|
||||||
shell: |
|
ansible.builtin.shell:
|
||||||
ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key -N ''
|
ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key -N ''
|
||||||
ssh-keygen -t ecdsa -b 521 -f /etc/ssh/ssh_host_ecdsa_key -N ''
|
ssh-keygen -t ecdsa -b 521 -f /etc/ssh/ssh_host_ecdsa_key -N ''
|
||||||
ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ''
|
ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ''
|
||||||
|
|
@ -53,13 +53,13 @@
|
||||||
notify: restart ssh
|
notify: restart ssh
|
||||||
|
|
||||||
- name: Create marker file to prevent re-running
|
- name: Create marker file to prevent re-running
|
||||||
file:
|
ansible.builtin.file:
|
||||||
path: /etc/ssh/.host_keys_regenerated
|
path: /etc/ssh/.host_keys_regenerated
|
||||||
state: touch
|
state: touch
|
||||||
mode: '0644'
|
mode: '0644'
|
||||||
|
|
||||||
- name: Install SSH banner
|
- name: Install SSH banner
|
||||||
template:
|
ansible.builtin.template:
|
||||||
src: issue.net.j2
|
src: issue.net.j2
|
||||||
dest: /etc/issue.net
|
dest: /etc/issue.net
|
||||||
mode: '0644'
|
mode: '0644'
|
||||||
|
|
@ -67,7 +67,7 @@
|
||||||
- ssh
|
- ssh
|
||||||
|
|
||||||
- name: Configure SSH to use banner
|
- name: Configure SSH to use banner
|
||||||
lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
path: /etc/ssh/sshd_config
|
path: /etc/ssh/sshd_config
|
||||||
regexp: '^Banner'
|
regexp: '^Banner'
|
||||||
line: 'Banner /etc/issue.net'
|
line: 'Banner /etc/issue.net'
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
---
|
---
|
||||||
- name: restart caddy
|
- name: restart caddy
|
||||||
service:
|
ansible.builtin.service:
|
||||||
name: caddy
|
name: caddy
|
||||||
state: restarted
|
state: restarted
|
||||||
|
|
||||||
- name: update apt cache
|
- name: update apt cache
|
||||||
apt:
|
ansible.builtin.apt:
|
||||||
update_cache: true
|
update_cache: true
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
---
|
---
|
||||||
# --- Install: Debian/Ubuntu ---
|
# --- Install: Debian/Ubuntu ---
|
||||||
- name: Check if Caddy is already installed
|
- name: Check if Caddy is already installed
|
||||||
command: which caddy
|
ansible.builtin.command: which caddy
|
||||||
register: caddy_installed
|
register: caddy_installed
|
||||||
changed_when: false
|
changed_when: false
|
||||||
failed_when: false
|
failed_when: false
|
||||||
when: ansible_os_family == "Debian"
|
when: ansible_os_family == "Debian"
|
||||||
|
|
||||||
- name: Install required packages (Debian/Ubuntu)
|
- name: Install required packages (Debian/Ubuntu)
|
||||||
apt:
|
ansible.builtin.apt:
|
||||||
name:
|
name:
|
||||||
- debian-keyring
|
- debian-keyring
|
||||||
- debian-archive-keyring
|
- debian-archive-keyring
|
||||||
|
|
@ -20,13 +20,13 @@
|
||||||
when: ansible_os_family == "Debian"
|
when: ansible_os_family == "Debian"
|
||||||
|
|
||||||
- name: Check for conflicting Caddy repositories
|
- name: Check for conflicting Caddy repositories
|
||||||
stat:
|
ansible.builtin.stat:
|
||||||
path: /usr/share/keyrings/caddy-stable-archive-keyring.gpg
|
path: /usr/share/keyrings/caddy-stable-archive-keyring.gpg
|
||||||
register: old_keyring
|
register: old_keyring
|
||||||
when: ansible_os_family == "Debian"
|
when: ansible_os_family == "Debian"
|
||||||
|
|
||||||
- name: Remove old Caddy repository files if they exist
|
- name: Remove old Caddy repository files if they exist
|
||||||
file:
|
ansible.builtin.file:
|
||||||
path: "{{ item }}"
|
path: "{{ item }}"
|
||||||
state: absent
|
state: absent
|
||||||
loop:
|
loop:
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
notify: update apt cache
|
notify: update apt cache
|
||||||
|
|
||||||
- name: Check if Caddy GPG key exists and is valid
|
- name: Check if Caddy GPG key exists and is valid
|
||||||
stat:
|
ansible.builtin.stat:
|
||||||
path: /etc/apt/trusted.gpg.d/caddy-stable.asc
|
path: /etc/apt/trusted.gpg.d/caddy-stable.asc
|
||||||
register: caddy_gpg_key
|
register: caddy_gpg_key
|
||||||
when: ansible_os_family == "Debian"
|
when: ansible_os_family == "Debian"
|
||||||
|
|
@ -63,7 +63,7 @@
|
||||||
when: ansible_os_family == "Debian"
|
when: ansible_os_family == "Debian"
|
||||||
|
|
||||||
- name: Install Caddy (Debian/Ubuntu)
|
- name: Install Caddy (Debian/Ubuntu)
|
||||||
apt:
|
ansible.builtin.apt:
|
||||||
name: caddy
|
name: caddy
|
||||||
state: present
|
state: present
|
||||||
update_cache: true
|
update_cache: true
|
||||||
|
|
@ -100,13 +100,13 @@
|
||||||
mode: '0755'
|
mode: '0755'
|
||||||
|
|
||||||
- name: Ensure Caddy service is enabled and started
|
- name: Ensure Caddy service is enabled and started
|
||||||
service:
|
ansible.builtin.service:
|
||||||
name: caddy
|
name: caddy
|
||||||
state: started
|
state: started
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
||||||
- name: Configure Caddy (shared template via caddy_template)
|
- name: Configure Caddy (shared template via caddy_template)
|
||||||
template:
|
ansible.builtin.template:
|
||||||
src: "{{ caddy_template }}"
|
src: "{{ caddy_template }}"
|
||||||
dest: /etc/caddy/Caddyfile
|
dest: /etc/caddy/Caddyfile
|
||||||
owner: root
|
owner: root
|
||||||
|
|
@ -116,7 +116,7 @@
|
||||||
when: caddy_template is defined
|
when: caddy_template is defined
|
||||||
|
|
||||||
- name: Check if host-specific Caddyfile template exists
|
- name: Check if host-specific Caddyfile template exists
|
||||||
stat:
|
ansible.builtin.stat:
|
||||||
path: "{{ playbook_dir }}/roles/caddy/templates/Caddyfile-{{ inventory_hostname }}.j2"
|
path: "{{ playbook_dir }}/roles/caddy/templates/Caddyfile-{{ inventory_hostname }}.j2"
|
||||||
register: host_specific_template
|
register: host_specific_template
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
|
|
@ -124,7 +124,7 @@
|
||||||
when: caddy_template is not defined
|
when: caddy_template is not defined
|
||||||
|
|
||||||
- name: Configure Caddy (host-specific template)
|
- name: Configure Caddy (host-specific template)
|
||||||
template:
|
ansible.builtin.template:
|
||||||
src: "Caddyfile-{{ inventory_hostname }}.j2"
|
src: "Caddyfile-{{ inventory_hostname }}.j2"
|
||||||
dest: /etc/caddy/Caddyfile
|
dest: /etc/caddy/Caddyfile
|
||||||
owner: root
|
owner: root
|
||||||
|
|
@ -136,7 +136,7 @@
|
||||||
- host_specific_template.stat.exists | default(false)
|
- host_specific_template.stat.exists | default(false)
|
||||||
|
|
||||||
- name: Configure Caddy (default template)
|
- name: Configure Caddy (default template)
|
||||||
template:
|
ansible.builtin.template:
|
||||||
src: Caddyfile.j2
|
src: Caddyfile.j2
|
||||||
dest: /etc/caddy/Caddyfile
|
dest: /etc/caddy/Caddyfile
|
||||||
owner: root
|
owner: root
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
- name: create /tmp/ansible-debug
|
- name: create /tmp/ansible-debug
|
||||||
file:
|
ansible.builtin.file:
|
||||||
path: /tmp/ansible-debug
|
path: /tmp/ansible-debug
|
||||||
state: directory
|
state: directory
|
||||||
|
|
||||||
- name: collect vars
|
- name: collect vars
|
||||||
template:
|
ansible.builtin.template:
|
||||||
src: templates/data.j2
|
src: templates/data.j2
|
||||||
dest: "/tmp/ansible-debug/{{ item.key }}.json"
|
dest: "/tmp/ansible-debug/{{ item.key }}.json"
|
||||||
vars:
|
vars:
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
---
|
---
|
||||||
- name: restart dokku nginx
|
- name: restart dokku nginx
|
||||||
command: dokku nginx:reload
|
ansible.builtin.command: dokku nginx:reload
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
# Install Docker (required by Dokku)
|
# Install Docker (required by Dokku)
|
||||||
- name: Install prerequisites
|
- name: Install prerequisites
|
||||||
apt:
|
ansible.builtin.apt:
|
||||||
name:
|
name:
|
||||||
- ca-certificates
|
- ca-certificates
|
||||||
- curl
|
- curl
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: Install Docker packages
|
- name: Install Docker packages
|
||||||
apt:
|
ansible.builtin.apt:
|
||||||
name:
|
name:
|
||||||
- docker-ce
|
- docker-ce
|
||||||
- docker-ce-cli
|
- docker-ce-cli
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
update_cache: true
|
update_cache: true
|
||||||
|
|
||||||
- name: Ensure Docker service is started and enabled
|
- name: Ensure Docker service is started and enabled
|
||||||
systemd:
|
ansible.builtin.systemd:
|
||||||
name: docker
|
name: docker
|
||||||
state: started
|
state: started
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
@ -81,13 +81,13 @@
|
||||||
label: "{{ item.question }}"
|
label: "{{ item.question }}"
|
||||||
|
|
||||||
- name: Install Dokku
|
- name: Install Dokku
|
||||||
apt:
|
ansible.builtin.apt:
|
||||||
name: dokku
|
name: dokku
|
||||||
state: present
|
state: present
|
||||||
update_cache: true
|
update_cache: true
|
||||||
|
|
||||||
- name: Set Dokku global domain
|
- name: Set Dokku global domain
|
||||||
command: dokku domains:set-global {{ dokku_domain }}
|
ansible.builtin.command: dokku domains:set-global {{ dokku_domain }}
|
||||||
register: dokku_domain_result
|
register: dokku_domain_result
|
||||||
changed_when: "'Set' in dokku_domain_result.stdout"
|
changed_when: "'Set' in dokku_domain_result.stdout"
|
||||||
|
|
||||||
|
|
@ -104,13 +104,13 @@
|
||||||
become: false
|
become: false
|
||||||
|
|
||||||
- name: Check existing Dokku SSH keys
|
- name: Check existing Dokku SSH keys
|
||||||
command: dokku ssh-keys:list
|
ansible.builtin.command: dokku ssh-keys:list
|
||||||
register: dokku_existing_keys
|
register: dokku_existing_keys
|
||||||
changed_when: false
|
changed_when: false
|
||||||
failed_when: false
|
failed_when: false
|
||||||
|
|
||||||
- name: Add SSH keys to Dokku
|
- name: Add SSH keys to Dokku
|
||||||
shell: |
|
ansible.builtin.shell: |
|
||||||
echo '{{ item.content.split("\n") | first }}' | dokku ssh-keys:add {{ item.item.name }}
|
echo '{{ item.content.split("\n") | first }}' | dokku ssh-keys:add {{ item.item.name }}
|
||||||
when: "item.item.name not in dokku_existing_keys.stdout"
|
when: "item.item.name not in dokku_existing_keys.stdout"
|
||||||
loop: "{{ ssh_key_responses.results }}"
|
loop: "{{ ssh_key_responses.results }}"
|
||||||
|
|
@ -119,37 +119,37 @@
|
||||||
|
|
||||||
# Install dokku-postgres plugin
|
# Install dokku-postgres plugin
|
||||||
- name: Check if postgres plugin is installed
|
- name: Check if postgres plugin is installed
|
||||||
command: dokku plugin:list
|
ansible.builtin.command: dokku plugin:list
|
||||||
register: dokku_plugins
|
register: dokku_plugins
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: Install dokku-postgres plugin
|
- name: Install dokku-postgres plugin
|
||||||
command: dokku plugin:install {{ dokku_postgres_plugin_url }}
|
ansible.builtin.command: dokku plugin:install {{ dokku_postgres_plugin_url }}
|
||||||
when: "'postgres' not in dokku_plugins.stdout"
|
when: "'postgres' not in dokku_plugins.stdout"
|
||||||
|
|
||||||
- name: Install dokku-redis plugin
|
- name: Install dokku-redis plugin
|
||||||
command: dokku plugin:install {{ dokku_redis_plugin_url }}
|
ansible.builtin.command: dokku plugin:install {{ dokku_redis_plugin_url }}
|
||||||
when: "'redis' not in dokku_plugins.stdout"
|
when: "'redis' not in dokku_plugins.stdout"
|
||||||
|
|
||||||
- name: Install dokku-letsencrypt plugin
|
- name: Install dokku-letsencrypt plugin
|
||||||
command: dokku plugin:install {{ dokku_letsencrypt_plugin_url }}
|
ansible.builtin.command: dokku plugin:install {{ dokku_letsencrypt_plugin_url }}
|
||||||
when: "'letsencrypt' not in dokku_plugins.stdout"
|
when: "'letsencrypt' not in dokku_plugins.stdout"
|
||||||
|
|
||||||
# Create apps and postgres services
|
# Create apps and postgres services
|
||||||
- name: Check existing apps
|
- name: Check existing apps
|
||||||
command: dokku apps:list
|
ansible.builtin.command: dokku apps:list
|
||||||
register: dokku_apps_list
|
register: dokku_apps_list
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: Create Dokku apps
|
- name: Create Dokku apps
|
||||||
command: "dokku apps:create {{ item.name }}"
|
ansible.builtin.command: "dokku apps:create {{ item.name }}"
|
||||||
when: "item.name not in dokku_apps_list.stdout_lines"
|
when: "item.name not in dokku_apps_list.stdout_lines"
|
||||||
loop: "{{ dokku_apps }}"
|
loop: "{{ dokku_apps }}"
|
||||||
loop_control:
|
loop_control:
|
||||||
label: "{{ item.name }}"
|
label: "{{ item.name }}"
|
||||||
|
|
||||||
- name: Set app domains
|
- name: Set app domains
|
||||||
shell: |
|
ansible.builtin.shell: |
|
||||||
current=$(dokku domains:report {{ item.name }} --domains-app-vhosts)
|
current=$(dokku domains:report {{ item.name }} --domains-app-vhosts)
|
||||||
for domain in {{ item.domains | join(' ') }}; do
|
for domain in {{ item.domains | join(' ') }}; do
|
||||||
if ! echo "$current" | grep -q "$domain"; then
|
if ! echo "$current" | grep -q "$domain"; then
|
||||||
|
|
@ -164,7 +164,7 @@
|
||||||
changed_when: "'added' in domains_result.stdout | default('')"
|
changed_when: "'added' in domains_result.stdout | default('')"
|
||||||
|
|
||||||
- name: Check if app has SSL cert
|
- name: Check if app has SSL cert
|
||||||
shell: "dokku certs:report {{ item.name }} --ssl-enabled 2>&1"
|
ansible.builtin.shell: "dokku certs:report {{ item.name }} --ssl-enabled 2>&1"
|
||||||
loop: "{{ dokku_apps }}"
|
loop: "{{ dokku_apps }}"
|
||||||
loop_control:
|
loop_control:
|
||||||
label: "{{ item.name }}"
|
label: "{{ item.name }}"
|
||||||
|
|
@ -173,7 +173,7 @@
|
||||||
failed_when: false
|
failed_when: false
|
||||||
|
|
||||||
- name: Generate self-signed SSL cert for apps
|
- name: Generate self-signed SSL cert for apps
|
||||||
shell: |
|
ansible.builtin.shell: |
|
||||||
mkdir -p /home/dokku/{{ item.item.name }}/tls
|
mkdir -p /home/dokku/{{ item.item.name }}/tls
|
||||||
openssl req -new -x509 -days 3650 -nodes \
|
openssl req -new -x509 -days 3650 -nodes \
|
||||||
-out /home/dokku/{{ item.item.name }}/tls/server.crt \
|
-out /home/dokku/{{ item.item.name }}/tls/server.crt \
|
||||||
|
|
@ -190,13 +190,13 @@
|
||||||
label: "{{ item.item.name }}"
|
label: "{{ item.item.name }}"
|
||||||
|
|
||||||
- name: Check existing postgres services
|
- name: Check existing postgres services
|
||||||
command: dokku postgres:list
|
ansible.builtin.command: dokku postgres:list
|
||||||
register: dokku_postgres_list
|
register: dokku_postgres_list
|
||||||
changed_when: false
|
changed_when: false
|
||||||
failed_when: false
|
failed_when: false
|
||||||
|
|
||||||
- name: Create postgres services with TimescaleDB
|
- name: Create postgres services with TimescaleDB
|
||||||
command: >
|
ansible.builtin.command: >
|
||||||
dokku postgres:create {{ item.postgres.service_name }}
|
dokku postgres:create {{ item.postgres.service_name }}
|
||||||
--image {{ dokku_postgres_image }}
|
--image {{ dokku_postgres_image }}
|
||||||
--image-version {{ dokku_postgres_image_version }}
|
--image-version {{ dokku_postgres_image_version }}
|
||||||
|
|
@ -210,12 +210,12 @@
|
||||||
|
|
||||||
# Handle TimescaleDB SSL cert issue - container may get stuck restarting without certs
|
# Handle TimescaleDB SSL cert issue - container may get stuck restarting without certs
|
||||||
- name: Wait for postgres services to stabilize
|
- name: Wait for postgres services to stabilize
|
||||||
pause:
|
ansible.builtin.pause:
|
||||||
seconds: 10
|
seconds: 10
|
||||||
when: postgres_create_result.changed | default(false)
|
when: postgres_create_result.changed | default(false)
|
||||||
|
|
||||||
- name: Check postgres service status
|
- name: Check postgres service status
|
||||||
command: "dokku postgres:info {{ item.postgres.service_name }}"
|
ansible.builtin.command: "dokku postgres:info {{ item.postgres.service_name }}"
|
||||||
when:
|
when:
|
||||||
- item.postgres is defined
|
- item.postgres is defined
|
||||||
- postgres_create_result.changed | default(false)
|
- postgres_create_result.changed | default(false)
|
||||||
|
|
@ -227,7 +227,7 @@
|
||||||
failed_when: false
|
failed_when: false
|
||||||
|
|
||||||
- name: Fix TimescaleDB SSL certs if container is restarting
|
- name: Fix TimescaleDB SSL certs if container is restarting
|
||||||
shell: |
|
ansible.builtin.shell: |
|
||||||
CONTAINER_ID=$(docker ps -a --filter "name=dokku.postgres.{{ item.postgres.service_name }}" --format '{{"{{"}}.ID{{"}}"}}')
|
CONTAINER_ID=$(docker ps -a --filter "name=dokku.postgres.{{ item.postgres.service_name }}" --format '{{"{{"}}.ID{{"}}"}}')
|
||||||
if [ -n "$CONTAINER_ID" ]; then
|
if [ -n "$CONTAINER_ID" ]; then
|
||||||
DATA_DIR=$(docker inspect "$CONTAINER_ID" --format '{{"{{" }}range .Mounts{{"}}"}}{{"{{"}}if eq .Destination "/var/lib/postgresql/data"{{"}}"}}{{"{{"}} .Source {{"}}"}}{{"{{"}}end{{"}}"}}{{"{{"}}end{{"}}"}}')
|
DATA_DIR=$(docker inspect "$CONTAINER_ID" --format '{{"{{" }}range .Mounts{{"}}"}}{{"{{"}}if eq .Destination "/var/lib/postgresql/data"{{"}}"}}{{"{{"}} .Source {{"}}"}}{{"{{"}}end{{"}}"}}{{"{{"}}end{{"}}"}}')
|
||||||
|
|
@ -251,7 +251,7 @@
|
||||||
|
|
||||||
# Enable TimescaleDB extension
|
# Enable TimescaleDB extension
|
||||||
- name: Enable timescaledb extension
|
- name: Enable timescaledb extension
|
||||||
shell: |
|
ansible.builtin.shell: |
|
||||||
echo "CREATE EXTENSION IF NOT EXISTS timescaledb;" | dokku postgres:connect {{ item.postgres.service_name }}
|
echo "CREATE EXTENSION IF NOT EXISTS timescaledb;" | dokku postgres:connect {{ item.postgres.service_name }}
|
||||||
when:
|
when:
|
||||||
- item.postgres is defined
|
- item.postgres is defined
|
||||||
|
|
@ -266,7 +266,7 @@
|
||||||
|
|
||||||
# Link postgres to apps
|
# Link postgres to apps
|
||||||
- name: Check postgres links
|
- name: Check postgres links
|
||||||
shell: "dokku postgres:linked {{ item.postgres.service_name }} {{ item.name }} && echo linked || echo not_linked"
|
ansible.builtin.shell: "dokku postgres:linked {{ item.postgres.service_name }} {{ item.name }} && echo linked || echo not_linked"
|
||||||
when:
|
when:
|
||||||
- item.postgres is defined
|
- item.postgres is defined
|
||||||
loop: "{{ dokku_apps }}"
|
loop: "{{ dokku_apps }}"
|
||||||
|
|
@ -277,7 +277,7 @@
|
||||||
failed_when: false
|
failed_when: false
|
||||||
|
|
||||||
- name: Link postgres to apps
|
- name: Link postgres to apps
|
||||||
command: "dokku postgres:link {{ item.item.postgres.service_name }} {{ item.item.name }}"
|
ansible.builtin.command: "dokku postgres:link {{ item.item.postgres.service_name }} {{ item.item.name }}"
|
||||||
when:
|
when:
|
||||||
- item.item.postgres is defined
|
- item.item.postgres is defined
|
||||||
- "'not_linked' in item.stdout"
|
- "'not_linked' in item.stdout"
|
||||||
|
|
@ -287,13 +287,13 @@
|
||||||
|
|
||||||
# Redis/Valkey services
|
# Redis/Valkey services
|
||||||
- name: Check existing redis services
|
- name: Check existing redis services
|
||||||
command: dokku redis:list
|
ansible.builtin.command: dokku redis:list
|
||||||
register: dokku_redis_list
|
register: dokku_redis_list
|
||||||
changed_when: false
|
changed_when: false
|
||||||
failed_when: false
|
failed_when: false
|
||||||
|
|
||||||
- name: Create redis services with Valkey
|
- name: Create redis services with Valkey
|
||||||
command: >
|
ansible.builtin.command: >
|
||||||
dokku redis:create {{ item.redis.service_name }}
|
dokku redis:create {{ item.redis.service_name }}
|
||||||
--image {{ dokku_redis_image }}
|
--image {{ dokku_redis_image }}
|
||||||
--image-version {{ dokku_redis_image_version }}
|
--image-version {{ dokku_redis_image_version }}
|
||||||
|
|
@ -305,7 +305,7 @@
|
||||||
label: "{{ item.name }}"
|
label: "{{ item.name }}"
|
||||||
|
|
||||||
- name: Check redis links
|
- name: Check redis links
|
||||||
shell: "dokku redis:linked {{ item.redis.service_name }} {{ item.name }} && echo linked || echo not_linked"
|
ansible.builtin.shell: "dokku redis:linked {{ item.redis.service_name }} {{ item.name }} && echo linked || echo not_linked"
|
||||||
when:
|
when:
|
||||||
- item.redis is defined
|
- item.redis is defined
|
||||||
loop: "{{ dokku_apps }}"
|
loop: "{{ dokku_apps }}"
|
||||||
|
|
@ -316,7 +316,7 @@
|
||||||
failed_when: false
|
failed_when: false
|
||||||
|
|
||||||
- name: Link redis to apps
|
- name: Link redis to apps
|
||||||
command: "dokku redis:link {{ item.item.redis.service_name }} {{ item.item.name }}"
|
ansible.builtin.command: "dokku redis:link {{ item.item.redis.service_name }} {{ item.item.name }}"
|
||||||
when:
|
when:
|
||||||
- item.item.redis is defined
|
- item.item.redis is defined
|
||||||
- "'not_linked' in item.stdout"
|
- "'not_linked' in item.stdout"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
---
|
---
|
||||||
- name: Reload ufw
|
- name: Reload ufw
|
||||||
ufw:
|
community.general.ufw:
|
||||||
state: reloaded
|
state: reloaded
|
||||||
|
|
|
||||||
|
|
@ -5,20 +5,20 @@
|
||||||
# Per-host rules for publicly exposed services
|
# Per-host rules for publicly exposed services
|
||||||
|
|
||||||
- name: Install ufw
|
- name: Install ufw
|
||||||
apt:
|
ansible.builtin.apt:
|
||||||
name: ufw
|
name: ufw
|
||||||
state: present
|
state: present
|
||||||
update_cache: true
|
update_cache: true
|
||||||
when: ansible_os_family == "Debian"
|
when: ansible_os_family == "Debian"
|
||||||
|
|
||||||
- name: Install firewalld
|
- name: Install firewalld
|
||||||
dnf:
|
ansible.builtin.dnf:
|
||||||
name: firewalld
|
name: firewalld
|
||||||
state: present
|
state: present
|
||||||
when: ansible_os_family == "RedHat"
|
when: ansible_os_family == "RedHat"
|
||||||
|
|
||||||
- name: Ensure firewalld is started and enabled
|
- name: Ensure firewalld is started and enabled
|
||||||
systemd:
|
ansible.builtin.systemd:
|
||||||
name: firewalld
|
name: firewalld
|
||||||
state: started
|
state: started
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
@ -73,7 +73,7 @@
|
||||||
# --- UFW (Debian/Ubuntu) - Disable when firewall not managed ---
|
# --- UFW (Debian/Ubuntu) - Disable when firewall not managed ---
|
||||||
|
|
||||||
- name: Disable ufw
|
- name: Disable ufw
|
||||||
ufw:
|
community.general.ufw:
|
||||||
state: disabled
|
state: disabled
|
||||||
when:
|
when:
|
||||||
- ansible_os_family == "Debian"
|
- ansible_os_family == "Debian"
|
||||||
|
|
@ -84,7 +84,7 @@
|
||||||
# --- UFW (Debian/Ubuntu) - Configure when firewall managed ---
|
# --- UFW (Debian/Ubuntu) - Configure when firewall managed ---
|
||||||
|
|
||||||
- name: Set default incoming policy to deny
|
- name: Set default incoming policy to deny
|
||||||
ufw:
|
community.general.ufw:
|
||||||
direction: incoming
|
direction: incoming
|
||||||
policy: "{{ firewall_default_incoming }}"
|
policy: "{{ firewall_default_incoming }}"
|
||||||
when:
|
when:
|
||||||
|
|
@ -92,7 +92,7 @@
|
||||||
- firewall_enabled | default(true)
|
- firewall_enabled | default(true)
|
||||||
|
|
||||||
- name: Set default outgoing policy to allow
|
- name: Set default outgoing policy to allow
|
||||||
ufw:
|
community.general.ufw:
|
||||||
direction: outgoing
|
direction: outgoing
|
||||||
policy: "{{ firewall_default_outgoing }}"
|
policy: "{{ firewall_default_outgoing }}"
|
||||||
when:
|
when:
|
||||||
|
|
@ -100,7 +100,7 @@
|
||||||
- firewall_enabled | default(true)
|
- firewall_enabled | default(true)
|
||||||
|
|
||||||
- name: Set default routed policy
|
- name: Set default routed policy
|
||||||
ufw:
|
community.general.ufw:
|
||||||
direction: routed
|
direction: routed
|
||||||
policy: "{{ firewall_default_routed }}"
|
policy: "{{ firewall_default_routed }}"
|
||||||
when:
|
when:
|
||||||
|
|
@ -120,7 +120,7 @@
|
||||||
- "'Status: active' in _fw_ufw_active.stdout"
|
- "'Status: active' in _fw_ufw_active.stdout"
|
||||||
|
|
||||||
- name: Allow all traffic from trusted subnets
|
- name: Allow all traffic from trusted subnets
|
||||||
ufw:
|
community.general.ufw:
|
||||||
rule: allow
|
rule: allow
|
||||||
from_ip: "{{ item.subnet }}"
|
from_ip: "{{ item.subnet }}"
|
||||||
comment: "{{ item.comment }}"
|
comment: "{{ item.comment }}"
|
||||||
|
|
@ -131,7 +131,7 @@
|
||||||
- _fw_ufw_rules.skipped | default(true) or item.subnet not in _fw_ufw_rules.stdout
|
- _fw_ufw_rules.skipped | default(true) or item.subnet not in _fw_ufw_rules.stdout
|
||||||
|
|
||||||
- name: Allow SSH from specific IPs
|
- name: Allow SSH from specific IPs
|
||||||
ufw:
|
community.general.ufw:
|
||||||
rule: allow
|
rule: allow
|
||||||
port: "22"
|
port: "22"
|
||||||
proto: tcp
|
proto: tcp
|
||||||
|
|
@ -145,7 +145,7 @@
|
||||||
- _fw_ufw_rules.skipped | default(true) or item.ip not in _fw_ufw_rules.stdout
|
- _fw_ufw_rules.skipped | default(true) or item.ip not in _fw_ufw_rules.stdout
|
||||||
|
|
||||||
- name: Allow per-host public services
|
- name: Allow per-host public services
|
||||||
ufw:
|
community.general.ufw:
|
||||||
rule: allow
|
rule: allow
|
||||||
port: "{{ item.port | string }}"
|
port: "{{ item.port | string }}"
|
||||||
proto: "{{ item.proto }}"
|
proto: "{{ item.proto }}"
|
||||||
|
|
@ -188,7 +188,7 @@
|
||||||
notify: Reload ufw
|
notify: Reload ufw
|
||||||
|
|
||||||
- name: Enable ufw
|
- name: Enable ufw
|
||||||
ufw:
|
community.general.ufw:
|
||||||
state: enabled
|
state: enabled
|
||||||
when:
|
when:
|
||||||
- ansible_os_family == "Debian"
|
- ansible_os_family == "Debian"
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
---
|
---
|
||||||
- name: Re-export NFS shares
|
- name: Re-export NFS shares
|
||||||
command: exportfs -ra
|
ansible.builtin.command: exportfs -ra
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
# K3s server configuration tasks
|
# K3s server configuration tasks
|
||||||
|
|
||||||
- name: Install K3s required packages
|
- name: Install K3s required packages
|
||||||
apt:
|
ansible.builtin.apt:
|
||||||
name: "{{ k3s_packages }}"
|
name: "{{ k3s_packages }}"
|
||||||
state: present
|
state: present
|
||||||
update_cache: true
|
update_cache: true
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
- k3s_packages
|
- k3s_packages
|
||||||
|
|
||||||
- name: Enable and start iscsid service
|
- name: Enable and start iscsid service
|
||||||
systemd:
|
ansible.builtin.systemd:
|
||||||
name: iscsid
|
name: iscsid
|
||||||
enabled: true
|
enabled: true
|
||||||
state: started
|
state: started
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
---
|
---
|
||||||
- name: install apt-transport-https
|
- name: install apt-transport-https
|
||||||
apt:
|
ansible.builtin.apt:
|
||||||
name: apt-transport-https
|
name: apt-transport-https
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,14 @@
|
||||||
- name: Configure MOTD banner update script
|
- name: Configure MOTD banner update script
|
||||||
copy:
|
ansible.builtin.copy:
|
||||||
src: etc/update-motd.d/20-banner
|
src: etc/update-motd.d/20-banner
|
||||||
dest: /etc/update-motd.d/20-banner
|
dest: /etc/update-motd.d/20-banner
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
mode: 0755
|
mode: '0755'
|
||||||
|
|
||||||
- name: Configure MOTD tail
|
- name: Configure MOTD tail
|
||||||
template:
|
ansible.builtin.template:
|
||||||
src: templates/etc/motd.j2
|
src: templates/etc/motd.j2
|
||||||
dest: /etc/motd
|
dest: /etc/motd
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
mode: 0644
|
mode: '0644'
|
||||||
|
|
@ -9,12 +9,12 @@
|
||||||
# - network_interfaces
|
# - network_interfaces
|
||||||
|
|
||||||
- name: "Create systemd interface files"
|
- name: "Create systemd interface files"
|
||||||
template:
|
ansible.builtin.template:
|
||||||
src: templates/etc/systemd/network/link.j2
|
src: templates/etc/systemd/network/link.j2
|
||||||
dest: "/etc/systemd/network/10-{{ interface.name }}-nic.link"
|
dest: "/etc/systemd/network/10-{{ interface.name }}-nic.link"
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
mode: 00644
|
mode: '0644'
|
||||||
loop: "{{ interfaces }}"
|
loop: "{{ interfaces }}"
|
||||||
loop_control:
|
loop_control:
|
||||||
loop_var: interface
|
loop_var: interface
|
||||||
|
|
@ -26,12 +26,12 @@
|
||||||
when: network.skip | default(False) != True
|
when: network.skip | default(False) != True
|
||||||
|
|
||||||
- name: "Build split network configuration (interfaces)"
|
- name: "Build split network configuration (interfaces)"
|
||||||
template:
|
ansible.builtin.template:
|
||||||
src: templates/etc/network/interfaces.d/interface.j2
|
src: templates/etc/network/interfaces.d/interface.j2
|
||||||
dest: "/etc/network/interfaces.d/{{ interface.name }}"
|
dest: "/etc/network/interfaces.d/{{ interface.name }}"
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
mode: 00644
|
mode: '0644'
|
||||||
loop: "{{ interfaces }}"
|
loop: "{{ interfaces }}"
|
||||||
loop_control:
|
loop_control:
|
||||||
loop_var: interface
|
loop_var: interface
|
||||||
|
|
@ -44,12 +44,12 @@
|
||||||
- network_interfaces
|
- network_interfaces
|
||||||
|
|
||||||
- name: "Build split network configuration (main)"
|
- name: "Build split network configuration (main)"
|
||||||
template:
|
ansible.builtin.template:
|
||||||
src: templates/etc/network/interfaces.j2
|
src: templates/etc/network/interfaces.j2
|
||||||
dest: "/etc/network/interfaces"
|
dest: "/etc/network/interfaces"
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
mode: 00644
|
mode: '0644'
|
||||||
vars:
|
vars:
|
||||||
interfaces: "{{ [] }}"
|
interfaces: "{{ [] }}"
|
||||||
register: network_interfaces_split_main
|
register: network_interfaces_split_main
|
||||||
|
|
@ -58,12 +58,12 @@
|
||||||
- network_interfaces
|
- network_interfaces
|
||||||
|
|
||||||
- name: "Build combined network configuration"
|
- name: "Build combined network configuration"
|
||||||
template:
|
ansible.builtin.template:
|
||||||
src: templates/etc/network/interfaces.j2
|
src: templates/etc/network/interfaces.j2
|
||||||
dest: "/etc/network/interfaces"
|
dest: "/etc/network/interfaces"
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
mode: 00644
|
mode: '0644'
|
||||||
vars:
|
vars:
|
||||||
interfaces: "{{ network.interfaces | default([]) }}"
|
interfaces: "{{ network.interfaces | default([]) }}"
|
||||||
register: network_interfaces_single
|
register: network_interfaces_single
|
||||||
|
|
@ -72,7 +72,7 @@
|
||||||
- network_interfaces
|
- network_interfaces
|
||||||
|
|
||||||
- name: "Remove split network configuration files"
|
- name: "Remove split network configuration files"
|
||||||
file:
|
ansible.builtin.file:
|
||||||
path: "/etc/network/interfaces.d/{{ interface.name }}"
|
path: "/etc/network/interfaces.d/{{ interface.name }}"
|
||||||
state: absent
|
state: absent
|
||||||
loop: "{{ interfaces }}"
|
loop: "{{ interfaces }}"
|
||||||
|
|
@ -87,29 +87,29 @@
|
||||||
- network_interfaces
|
- network_interfaces
|
||||||
|
|
||||||
- name: "Set hostname (/etc/hosts)"
|
- name: "Set hostname (/etc/hosts)"
|
||||||
template:
|
ansible.builtin.template:
|
||||||
src: templates/etc/hosts.j2
|
src: templates/etc/hosts.j2
|
||||||
dest: "/etc/hosts"
|
dest: "/etc/hosts"
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
mode: 00644
|
mode: '0644'
|
||||||
when: network.skip | default(False) != True
|
when: network.skip | default(False) != True
|
||||||
tags:
|
tags:
|
||||||
- network_hostname
|
- network_hostname
|
||||||
|
|
||||||
- name: "Set hostname (/etc/hostname)"
|
- name: "Set hostname (/etc/hostname)"
|
||||||
template:
|
ansible.builtin.template:
|
||||||
src: templates/etc/hostname.j2
|
src: templates/etc/hostname.j2
|
||||||
dest: "/etc/hostname"
|
dest: "/etc/hostname"
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
mode: 00644
|
mode: '0644'
|
||||||
when: network.skip | default(False) != True
|
when: network.skip | default(False) != True
|
||||||
tags:
|
tags:
|
||||||
- network_hostname
|
- network_hostname
|
||||||
|
|
||||||
- name: "Restart networking"
|
- name: "Restart networking"
|
||||||
systemd_service:
|
ansible.builtin.systemd:
|
||||||
name: networking
|
name: networking
|
||||||
daemon_reload: true
|
daemon_reload: true
|
||||||
state: restarted
|
state: restarted
|
||||||
|
|
@ -118,12 +118,12 @@
|
||||||
- network_restart
|
- network_restart
|
||||||
|
|
||||||
- name: "Configure /etc/resolv.conf"
|
- name: "Configure /etc/resolv.conf"
|
||||||
template:
|
ansible.builtin.template:
|
||||||
src: templates/etc/resolv.conf.j2
|
src: templates/etc/resolv.conf.j2
|
||||||
dest: /etc/resolv.conf
|
dest: /etc/resolv.conf
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
mode: 00644
|
mode: '0644'
|
||||||
follow: yes
|
follow: yes
|
||||||
vars:
|
vars:
|
||||||
domain: "{{ network.domain | default('local') }}"
|
domain: "{{ network.domain | default('local') }}"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
- name: Install NFS server packages
|
- name: Install NFS server packages
|
||||||
apt:
|
ansible.builtin.apt:
|
||||||
name: nfs-kernel-server
|
name: nfs-kernel-server
|
||||||
state: present
|
state: present
|
||||||
update_cache: true
|
update_cache: true
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
when: nfs_exports is defined
|
when: nfs_exports is defined
|
||||||
|
|
||||||
- name: Configure /etc/exports
|
- name: Configure /etc/exports
|
||||||
template:
|
ansible.builtin.template:
|
||||||
src: templates/etc/exports.j2
|
src: templates/etc/exports.j2
|
||||||
dest: /etc/exports
|
dest: /etc/exports
|
||||||
owner: root
|
owner: root
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
notify: Re-export NFS shares
|
notify: Re-export NFS shares
|
||||||
|
|
||||||
- name: Enable and start nfs-server
|
- name: Enable and start nfs-server
|
||||||
systemd:
|
ansible.builtin.systemd:
|
||||||
name: nfs-server
|
name: nfs-server
|
||||||
enabled: true
|
enabled: true
|
||||||
state: started
|
state: started
|
||||||
|
|
|
||||||
|
|
@ -1,40 +1,44 @@
|
||||||
---
|
---
|
||||||
# General role - system-wide configurations
|
- name: Install misc Debian packages
|
||||||
|
ansible.builtin.import_tasks: debian/misc.yml
|
||||||
# Import Debian-specific tasks
|
|
||||||
- import_tasks: debian/misc.yml
|
|
||||||
when: ansible_os_family == "Debian"
|
when: ansible_os_family == "Debian"
|
||||||
tags:
|
tags:
|
||||||
- misc
|
- misc
|
||||||
|
|
||||||
- import_tasks: debian/motd.yml
|
- name: Configure MOTD
|
||||||
|
ansible.builtin.import_tasks: debian/motd.yml
|
||||||
when: ansible_os_family == "Debian"
|
when: ansible_os_family == "Debian"
|
||||||
tags:
|
tags:
|
||||||
- motd
|
- motd
|
||||||
|
|
||||||
- import_tasks: debian/network.yml
|
- name: Configure networking
|
||||||
|
ansible.builtin.import_tasks: debian/network.yml
|
||||||
when: ansible_os_family == "Debian"
|
when: ansible_os_family == "Debian"
|
||||||
tags:
|
tags:
|
||||||
- network
|
- network
|
||||||
|
|
||||||
- import_tasks: udp-gro-fix.yml
|
- name: Apply UDP GRO fix for Tailscale
|
||||||
|
ansible.builtin.import_tasks: udp-gro-fix.yml
|
||||||
when: ansible_os_family == "Debian"
|
when: ansible_os_family == "Debian"
|
||||||
tags:
|
tags:
|
||||||
- network
|
- network
|
||||||
- tailscale
|
- tailscale
|
||||||
|
|
||||||
- import_tasks: debian/k3s.yml
|
- name: Install K3s packages
|
||||||
|
ansible.builtin.import_tasks: debian/k3s.yml
|
||||||
when: ansible_os_family == "Debian"
|
when: ansible_os_family == "Debian"
|
||||||
tags:
|
tags:
|
||||||
- k3s
|
- k3s
|
||||||
|
|
||||||
- import_tasks: debian/icinga2.yml
|
- name: Uninstall Icinga2 on non-monitor hosts
|
||||||
|
ansible.builtin.import_tasks: debian/icinga2.yml
|
||||||
when: ansible_os_family == "Debian"
|
when: ansible_os_family == "Debian"
|
||||||
tags:
|
tags:
|
||||||
- icinga2
|
- icinga2
|
||||||
- monitoring
|
- monitoring
|
||||||
|
|
||||||
- import_tasks: debian/nfs.yml
|
- name: Configure NFS mounts
|
||||||
|
ansible.builtin.import_tasks: debian/nfs.yml
|
||||||
when: ansible_os_family == "Debian"
|
when: ansible_os_family == "Debian"
|
||||||
tags:
|
tags:
|
||||||
- nfs
|
- nfs
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
# See https://tailscale.com/s/ethtool-config-udp-gro
|
# See https://tailscale.com/s/ethtool-config-udp-gro
|
||||||
|
|
||||||
- name: Check if ethtool is installed
|
- name: Check if ethtool is installed
|
||||||
package:
|
ansible.builtin.package:
|
||||||
name: ethtool
|
name: ethtool
|
||||||
state: present
|
state: present
|
||||||
tags:
|
tags:
|
||||||
|
|
@ -11,7 +11,9 @@
|
||||||
- tailscale
|
- tailscale
|
||||||
|
|
||||||
- name: Get list of bridge interfaces
|
- name: Get list of bridge interfaces
|
||||||
shell: "ip link show type bridge | grep -E '^[0-9]+:' | cut -d: -f2 | tr -d ' '"
|
ansible.builtin.shell:
|
||||||
|
cmd: "set -o pipefail; ip link show type bridge | grep -E '^[0-9]+:' | cut -d: -f2 | tr -d ' '"
|
||||||
|
executable: /bin/bash
|
||||||
register: bridge_interfaces
|
register: bridge_interfaces
|
||||||
changed_when: false
|
changed_when: false
|
||||||
failed_when: false
|
failed_when: false
|
||||||
|
|
@ -20,7 +22,7 @@
|
||||||
- tailscale
|
- tailscale
|
||||||
|
|
||||||
- name: Disable UDP GRO on bridge interfaces
|
- name: Disable UDP GRO on bridge interfaces
|
||||||
command: "ethtool -K {{ item }} rx-udp-gro-forwarding off rx-gro-list off"
|
ansible.builtin.command: "ethtool -K {{ item }} rx-udp-gro-forwarding off rx-gro-list off"
|
||||||
loop: "{{ bridge_interfaces.stdout_lines }}"
|
loop: "{{ bridge_interfaces.stdout_lines }}"
|
||||||
when: bridge_interfaces.stdout_lines is defined and bridge_interfaces.stdout_lines | length > 0
|
when: bridge_interfaces.stdout_lines is defined and bridge_interfaces.stdout_lines | length > 0
|
||||||
failed_when: false
|
failed_when: false
|
||||||
|
|
@ -30,7 +32,7 @@
|
||||||
- tailscale
|
- tailscale
|
||||||
|
|
||||||
- name: Create systemd service to persist UDP GRO settings
|
- name: Create systemd service to persist UDP GRO settings
|
||||||
copy:
|
ansible.builtin.copy:
|
||||||
dest: /etc/systemd/system/disable-udp-gro@.service
|
dest: /etc/systemd/system/disable-udp-gro@.service
|
||||||
content: |
|
content: |
|
||||||
[Unit]
|
[Unit]
|
||||||
|
|
@ -52,7 +54,7 @@
|
||||||
- tailscale
|
- tailscale
|
||||||
|
|
||||||
- name: Enable systemd service for each bridge interface
|
- name: Enable systemd service for each bridge interface
|
||||||
systemd:
|
ansible.builtin.systemd:
|
||||||
name: "disable-udp-gro@{{ item }}.service"
|
name: "disable-udp-gro@{{ item }}.service"
|
||||||
enabled: true
|
enabled: true
|
||||||
daemon_reload: true
|
daemon_reload: true
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,29 @@
|
||||||
---
|
---
|
||||||
- name: restart php-fpm
|
- name: restart php-fpm
|
||||||
service:
|
ansible.builtin.service:
|
||||||
name: "php{{ librenms_php_version }}-fpm"
|
name: "php{{ librenms_php_version }}-fpm"
|
||||||
state: restarted
|
state: restarted
|
||||||
|
|
||||||
- name: restart caddy
|
- name: restart caddy
|
||||||
service:
|
ansible.builtin.service:
|
||||||
name: caddy
|
name: caddy
|
||||||
state: restarted
|
state: restarted
|
||||||
|
|
||||||
- name: restart snmpd
|
- name: restart snmpd
|
||||||
service:
|
ansible.builtin.service:
|
||||||
name: snmpd
|
name: snmpd
|
||||||
state: restarted
|
state: restarted
|
||||||
|
|
||||||
- name: restart postfix
|
- name: restart postfix
|
||||||
service:
|
ansible.builtin.service:
|
||||||
name: postfix
|
name: postfix
|
||||||
state: restarted
|
state: restarted
|
||||||
|
|
||||||
- name: reload systemd
|
- name: reload systemd
|
||||||
systemd:
|
ansible.builtin.systemd:
|
||||||
daemon_reload: true
|
daemon_reload: true
|
||||||
|
|
||||||
- name: restart librenms-scheduler
|
- name: restart librenms-scheduler
|
||||||
systemd:
|
ansible.builtin.systemd:
|
||||||
name: librenms-scheduler.timer
|
name: librenms-scheduler.timer
|
||||||
state: restarted
|
state: restarted
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: Install required packages
|
- name: Install required packages
|
||||||
apt:
|
ansible.builtin.apt:
|
||||||
name:
|
name:
|
||||||
- acl
|
- acl
|
||||||
- curl
|
- curl
|
||||||
|
|
@ -55,13 +55,13 @@
|
||||||
update_cache: true
|
update_cache: true
|
||||||
|
|
||||||
- name: Create librenms group
|
- name: Create librenms group
|
||||||
group:
|
ansible.builtin.group:
|
||||||
name: "{{ librenms_group }}"
|
name: "{{ librenms_group }}"
|
||||||
system: true
|
system: true
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: Create librenms user
|
- name: Create librenms user
|
||||||
user:
|
ansible.builtin.user:
|
||||||
name: "{{ librenms_user }}"
|
name: "{{ librenms_user }}"
|
||||||
group: "{{ librenms_group }}"
|
group: "{{ librenms_group }}"
|
||||||
home: "{{ librenms_path }}"
|
home: "{{ librenms_path }}"
|
||||||
|
|
@ -71,21 +71,22 @@
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: Check if LibreNMS is already installed
|
- name: Check if LibreNMS is already installed
|
||||||
stat:
|
ansible.builtin.stat:
|
||||||
path: "{{ librenms_path }}/lnms"
|
path: "{{ librenms_path }}/lnms"
|
||||||
register: librenms_installed
|
register: librenms_installed
|
||||||
|
|
||||||
- name: Clone LibreNMS repository
|
- name: Clone LibreNMS repository
|
||||||
git:
|
ansible.builtin.git:
|
||||||
repo: https://github.com/librenms/librenms.git
|
repo: https://github.com/librenms/librenms.git
|
||||||
dest: "{{ librenms_path }}"
|
dest: "{{ librenms_path }}"
|
||||||
version: master
|
version: master
|
||||||
depth: 1
|
depth: 1
|
||||||
|
become: true
|
||||||
become_user: "{{ librenms_user }}"
|
become_user: "{{ librenms_user }}"
|
||||||
when: not librenms_installed.stat.exists
|
when: not librenms_installed.stat.exists
|
||||||
|
|
||||||
- name: Set LibreNMS directory ownership
|
- name: Set LibreNMS directory ownership
|
||||||
file:
|
ansible.builtin.file:
|
||||||
path: "{{ librenms_path }}"
|
path: "{{ librenms_path }}"
|
||||||
owner: "{{ librenms_user }}"
|
owner: "{{ librenms_user }}"
|
||||||
group: "{{ librenms_group }}"
|
group: "{{ librenms_group }}"
|
||||||
|
|
@ -93,13 +94,13 @@
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: Set LibreNMS directory permissions
|
- name: Set LibreNMS directory permissions
|
||||||
file:
|
ansible.builtin.file:
|
||||||
path: "{{ librenms_path }}"
|
path: "{{ librenms_path }}"
|
||||||
mode: '0771'
|
mode: '0771'
|
||||||
state: directory
|
state: directory
|
||||||
|
|
||||||
- name: Ensure writable directories exist
|
- name: Ensure writable directories exist
|
||||||
file:
|
ansible.builtin.file:
|
||||||
path: "{{ librenms_path }}/{{ item }}"
|
path: "{{ librenms_path }}/{{ item }}"
|
||||||
owner: "{{ librenms_user }}"
|
owner: "{{ librenms_user }}"
|
||||||
group: "{{ librenms_group }}"
|
group: "{{ librenms_group }}"
|
||||||
|
|
@ -112,7 +113,7 @@
|
||||||
- bootstrap/cache
|
- bootstrap/cache
|
||||||
|
|
||||||
- name: Set ACLs for LibreNMS directories
|
- name: Set ACLs for LibreNMS directories
|
||||||
acl:
|
ansible.posix.acl:
|
||||||
path: "{{ librenms_path }}/{{ item }}"
|
path: "{{ librenms_path }}/{{ item }}"
|
||||||
entry: "default:group::rwx"
|
entry: "default:group::rwx"
|
||||||
state: present
|
state: present
|
||||||
|
|
@ -123,7 +124,7 @@
|
||||||
- bootstrap/cache
|
- bootstrap/cache
|
||||||
|
|
||||||
- name: Deploy LibreNMS .env file
|
- name: Deploy LibreNMS .env file
|
||||||
template:
|
ansible.builtin.template:
|
||||||
src: env.j2
|
src: env.j2
|
||||||
dest: "{{ librenms_path }}/.env"
|
dest: "{{ librenms_path }}/.env"
|
||||||
owner: "{{ librenms_user }}"
|
owner: "{{ librenms_user }}"
|
||||||
|
|
@ -131,7 +132,7 @@
|
||||||
mode: '0640'
|
mode: '0640'
|
||||||
|
|
||||||
- name: Configure PHP-FPM pool for LibreNMS
|
- name: Configure PHP-FPM pool for LibreNMS
|
||||||
template:
|
ansible.builtin.template:
|
||||||
src: php-fpm-librenms.conf.j2
|
src: php-fpm-librenms.conf.j2
|
||||||
dest: "/etc/php/{{ librenms_php_version }}/fpm/pool.d/librenms.conf"
|
dest: "/etc/php/{{ librenms_php_version }}/fpm/pool.d/librenms.conf"
|
||||||
owner: root
|
owner: root
|
||||||
|
|
@ -140,14 +141,14 @@
|
||||||
notify: restart php-fpm
|
notify: restart php-fpm
|
||||||
|
|
||||||
- name: Set PHP memory_limit
|
- name: Set PHP memory_limit
|
||||||
lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
path: "/etc/php/{{ librenms_php_version }}/fpm/php.ini"
|
path: "/etc/php/{{ librenms_php_version }}/fpm/php.ini"
|
||||||
regexp: '^memory_limit\s*='
|
regexp: '^memory_limit\s*='
|
||||||
line: 'memory_limit = 512M'
|
line: 'memory_limit = 512M'
|
||||||
notify: restart php-fpm
|
notify: restart php-fpm
|
||||||
|
|
||||||
- name: Configure Caddy for LibreNMS
|
- name: Configure Caddy for LibreNMS
|
||||||
template:
|
ansible.builtin.template:
|
||||||
src: Caddyfile.j2
|
src: Caddyfile.j2
|
||||||
dest: /etc/caddy/Caddyfile
|
dest: /etc/caddy/Caddyfile
|
||||||
owner: root
|
owner: root
|
||||||
|
|
@ -156,7 +157,7 @@
|
||||||
notify: restart caddy
|
notify: restart caddy
|
||||||
|
|
||||||
- name: Deploy LibreNMS cron jobs
|
- name: Deploy LibreNMS cron jobs
|
||||||
template:
|
ansible.builtin.template:
|
||||||
src: cron-librenms.j2
|
src: cron-librenms.j2
|
||||||
dest: /etc/cron.d/librenms
|
dest: /etc/cron.d/librenms
|
||||||
owner: root
|
owner: root
|
||||||
|
|
@ -164,7 +165,7 @@
|
||||||
mode: '0644'
|
mode: '0644'
|
||||||
|
|
||||||
- name: Deploy LibreNMS scheduler service
|
- name: Deploy LibreNMS scheduler service
|
||||||
template:
|
ansible.builtin.template:
|
||||||
src: librenms-scheduler.service.j2
|
src: librenms-scheduler.service.j2
|
||||||
dest: /etc/systemd/system/librenms-scheduler.service
|
dest: /etc/systemd/system/librenms-scheduler.service
|
||||||
owner: root
|
owner: root
|
||||||
|
|
@ -173,7 +174,7 @@
|
||||||
notify: reload systemd
|
notify: reload systemd
|
||||||
|
|
||||||
- name: Deploy LibreNMS scheduler timer
|
- name: Deploy LibreNMS scheduler timer
|
||||||
template:
|
ansible.builtin.template:
|
||||||
src: librenms-scheduler.timer.j2
|
src: librenms-scheduler.timer.j2
|
||||||
dest: /etc/systemd/system/librenms-scheduler.timer
|
dest: /etc/systemd/system/librenms-scheduler.timer
|
||||||
owner: root
|
owner: root
|
||||||
|
|
@ -184,13 +185,13 @@
|
||||||
- restart librenms-scheduler
|
- restart librenms-scheduler
|
||||||
|
|
||||||
- name: Enable and start LibreNMS scheduler timer
|
- name: Enable and start LibreNMS scheduler timer
|
||||||
systemd:
|
ansible.builtin.systemd:
|
||||||
name: librenms-scheduler.timer
|
name: librenms-scheduler.timer
|
||||||
state: started
|
state: started
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
||||||
- name: Configure SNMPD
|
- name: Configure SNMPD
|
||||||
template:
|
ansible.builtin.template:
|
||||||
src: snmpd.conf.j2
|
src: snmpd.conf.j2
|
||||||
dest: /etc/snmp/snmpd.conf
|
dest: /etc/snmp/snmpd.conf
|
||||||
owner: root
|
owner: root
|
||||||
|
|
@ -199,7 +200,7 @@
|
||||||
notify: restart snmpd
|
notify: restart snmpd
|
||||||
|
|
||||||
- name: Configure Postfix for local-only delivery
|
- name: Configure Postfix for local-only delivery
|
||||||
lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
path: /etc/postfix/main.cf
|
path: /etc/postfix/main.cf
|
||||||
regexp: "{{ item.regexp }}"
|
regexp: "{{ item.regexp }}"
|
||||||
line: "{{ item.line }}"
|
line: "{{ item.line }}"
|
||||||
|
|
@ -211,31 +212,31 @@
|
||||||
notify: restart postfix
|
notify: restart postfix
|
||||||
|
|
||||||
- name: Ensure MariaDB is running
|
- name: Ensure MariaDB is running
|
||||||
service:
|
ansible.builtin.service:
|
||||||
name: mariadb
|
name: mariadb
|
||||||
state: started
|
state: started
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
||||||
- name: Ensure Caddy is running
|
- name: Ensure Caddy is running
|
||||||
service:
|
ansible.builtin.service:
|
||||||
name: caddy
|
name: caddy
|
||||||
state: started
|
state: started
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
||||||
- name: Ensure PHP-FPM is running
|
- name: Ensure PHP-FPM is running
|
||||||
service:
|
ansible.builtin.service:
|
||||||
name: "php{{ librenms_php_version }}-fpm"
|
name: "php{{ librenms_php_version }}-fpm"
|
||||||
state: started
|
state: started
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
||||||
- name: Ensure SNMPD is running
|
- name: Ensure SNMPD is running
|
||||||
service:
|
ansible.builtin.service:
|
||||||
name: snmpd
|
name: snmpd
|
||||||
state: started
|
state: started
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
||||||
- name: Ensure Postfix is running
|
- name: Ensure Postfix is running
|
||||||
service:
|
ansible.builtin.service:
|
||||||
name: postfix
|
name: postfix
|
||||||
state: started
|
state: started
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,14 @@
|
||||||
# Handlers for Mailcow
|
# Handlers for Mailcow
|
||||||
|
|
||||||
- name: restart mailcow
|
- name: restart mailcow
|
||||||
systemd:
|
ansible.builtin.systemd:
|
||||||
name: mailcow
|
name: mailcow
|
||||||
state: restarted
|
state: restarted
|
||||||
daemon_reload: true
|
daemon_reload: true
|
||||||
become: true
|
become: true
|
||||||
|
|
||||||
- name: reload mailcow
|
- name: reload mailcow
|
||||||
command: docker compose restart
|
ansible.builtin.command: docker compose restart
|
||||||
args:
|
args:
|
||||||
chdir: "{{ mailcow_base_path }}"
|
chdir: "{{ mailcow_base_path }}"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
# Install and configure Mailcow
|
# Install and configure Mailcow
|
||||||
|
|
||||||
- name: Install required packages
|
- name: Install required packages
|
||||||
apt:
|
ansible.builtin.apt:
|
||||||
name:
|
name:
|
||||||
- git
|
- git
|
||||||
- curl
|
- curl
|
||||||
|
|
@ -15,13 +15,13 @@
|
||||||
update_cache: true
|
update_cache: true
|
||||||
|
|
||||||
- name: Ensure docker service is running
|
- name: Ensure docker service is running
|
||||||
systemd:
|
ansible.builtin.systemd:
|
||||||
name: docker
|
name: docker
|
||||||
state: started
|
state: started
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
||||||
- name: Create mailcow user
|
- name: Create mailcow user
|
||||||
user:
|
ansible.builtin.user:
|
||||||
name: mailcow
|
name: mailcow
|
||||||
groups: docker
|
groups: docker
|
||||||
shell: /bin/bash
|
shell: /bin/bash
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: Ensure mailcow base directory exists
|
- name: Ensure mailcow base directory exists
|
||||||
file:
|
ansible.builtin.file:
|
||||||
path: "{{ mailcow_base_path }}"
|
path: "{{ mailcow_base_path }}"
|
||||||
state: directory
|
state: directory
|
||||||
owner: mailcow
|
owner: mailcow
|
||||||
|
|
@ -38,12 +38,12 @@
|
||||||
mode: '0755'
|
mode: '0755'
|
||||||
|
|
||||||
- name: Check if Mailcow repository exists
|
- name: Check if Mailcow repository exists
|
||||||
stat:
|
ansible.builtin.stat:
|
||||||
path: "{{ mailcow_base_path }}/.git"
|
path: "{{ mailcow_base_path }}/.git"
|
||||||
register: mailcow_repo
|
register: mailcow_repo
|
||||||
|
|
||||||
- name: Remove non-git Mailcow directory
|
- name: Remove non-git Mailcow directory
|
||||||
file:
|
ansible.builtin.file:
|
||||||
path: "{{ mailcow_base_path }}"
|
path: "{{ mailcow_base_path }}"
|
||||||
state: absent
|
state: absent
|
||||||
when:
|
when:
|
||||||
|
|
@ -51,7 +51,7 @@
|
||||||
- not mailcow_repo.stat.exists
|
- not mailcow_repo.stat.exists
|
||||||
|
|
||||||
- name: Clone Mailcow repository
|
- name: Clone Mailcow repository
|
||||||
git:
|
ansible.builtin.git:
|
||||||
repo: "{{ mailcow_git_repo }}"
|
repo: "{{ mailcow_git_repo }}"
|
||||||
dest: "{{ mailcow_base_path }}"
|
dest: "{{ mailcow_base_path }}"
|
||||||
version: "{{ mailcow_git_branch }}"
|
version: "{{ mailcow_git_branch }}"
|
||||||
|
|
@ -71,7 +71,7 @@
|
||||||
when: mailcow_repo.stat.exists
|
when: mailcow_repo.stat.exists
|
||||||
|
|
||||||
- name: Update Mailcow repository
|
- name: Update Mailcow repository
|
||||||
git:
|
ansible.builtin.git:
|
||||||
repo: "{{ mailcow_git_repo }}"
|
repo: "{{ mailcow_git_repo }}"
|
||||||
dest: "{{ mailcow_base_path }}"
|
dest: "{{ mailcow_base_path }}"
|
||||||
version: "{{ mailcow_git_branch }}"
|
version: "{{ mailcow_git_branch }}"
|
||||||
|
|
@ -83,7 +83,7 @@
|
||||||
- "'Local modifications exist' not in git_update_result.msg | default('')"
|
- "'Local modifications exist' not in git_update_result.msg | default('')"
|
||||||
|
|
||||||
- name: Change ownership of Mailcow directory
|
- name: Change ownership of Mailcow directory
|
||||||
file:
|
ansible.builtin.file:
|
||||||
path: "{{ mailcow_base_path }}"
|
path: "{{ mailcow_base_path }}"
|
||||||
owner: mailcow
|
owner: mailcow
|
||||||
group: mailcow
|
group: mailcow
|
||||||
|
|
@ -92,7 +92,7 @@
|
||||||
# Let generate_config.sh create the default configuration
|
# Let generate_config.sh create the default configuration
|
||||||
|
|
||||||
- name: Create docker-compose override file
|
- name: Create docker-compose override file
|
||||||
template:
|
ansible.builtin.template:
|
||||||
src: docker-compose.override.yml.j2
|
src: docker-compose.override.yml.j2
|
||||||
dest: "{{ mailcow_base_path }}/docker-compose.override.yml"
|
dest: "{{ mailcow_base_path }}/docker-compose.override.yml"
|
||||||
owner: mailcow
|
owner: mailcow
|
||||||
|
|
@ -102,19 +102,19 @@
|
||||||
notify: restart mailcow
|
notify: restart mailcow
|
||||||
|
|
||||||
- name: Make generate_config.sh executable
|
- name: Make generate_config.sh executable
|
||||||
file:
|
ansible.builtin.file:
|
||||||
path: "{{ mailcow_base_path }}/generate_config.sh"
|
path: "{{ mailcow_base_path }}/generate_config.sh"
|
||||||
mode: '0755'
|
mode: '0755'
|
||||||
owner: mailcow
|
owner: mailcow
|
||||||
group: mailcow
|
group: mailcow
|
||||||
|
|
||||||
- name: Check if mailcow is already configured
|
- name: Check if mailcow is already configured
|
||||||
stat:
|
ansible.builtin.stat:
|
||||||
path: "{{ mailcow_base_path }}/mailcow.conf"
|
path: "{{ mailcow_base_path }}/mailcow.conf"
|
||||||
register: mailcow_configured
|
register: mailcow_configured
|
||||||
|
|
||||||
- name: Remove incomplete mailcow.conf
|
- name: Remove incomplete mailcow.conf
|
||||||
file:
|
ansible.builtin.file:
|
||||||
path: "{{ mailcow_base_path }}/mailcow.conf"
|
path: "{{ mailcow_base_path }}/mailcow.conf"
|
||||||
state: absent
|
state: absent
|
||||||
when:
|
when:
|
||||||
|
|
@ -122,7 +122,7 @@
|
||||||
- mailcow_configured.stat.size < 1000 # If config is too small, it's incomplete
|
- mailcow_configured.stat.size < 1000 # If config is too small, it's incomplete
|
||||||
|
|
||||||
- name: Run generate_config.sh script
|
- name: Run generate_config.sh script
|
||||||
shell: |
|
ansible.builtin.shell: |
|
||||||
cd {{ mailcow_base_path }}
|
cd {{ mailcow_base_path }}
|
||||||
./generate_config.sh << EOF
|
./generate_config.sh << EOF
|
||||||
{{ mailcow_hostname }}
|
{{ mailcow_hostname }}
|
||||||
|
|
@ -132,7 +132,7 @@
|
||||||
creates: "{{ mailcow_base_path }}/mailcow.conf"
|
creates: "{{ mailcow_base_path }}/mailcow.conf"
|
||||||
|
|
||||||
- name: Update mailcow.conf with secure passwords
|
- name: Update mailcow.conf with secure passwords
|
||||||
lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
path: "{{ mailcow_base_path }}/mailcow.conf"
|
path: "{{ mailcow_base_path }}/mailcow.conf"
|
||||||
regexp: "^{{ item.key }}="
|
regexp: "^{{ item.key }}="
|
||||||
line: "{{ item.key }}={{ item.value }}"
|
line: "{{ item.key }}={{ item.value }}"
|
||||||
|
|
@ -145,38 +145,38 @@
|
||||||
no_log: true
|
no_log: true
|
||||||
|
|
||||||
- name: Stop any running Mailcow containers
|
- name: Stop any running Mailcow containers
|
||||||
command: docker compose down
|
ansible.builtin.command: docker compose down
|
||||||
args:
|
args:
|
||||||
chdir: "{{ mailcow_base_path }}"
|
chdir: "{{ mailcow_base_path }}"
|
||||||
failed_when: false
|
failed_when: false
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: Prune unused Docker networks
|
- name: Prune unused Docker networks
|
||||||
command: docker network prune -f
|
ansible.builtin.command: docker network prune -f
|
||||||
changed_when: true
|
changed_when: true
|
||||||
|
|
||||||
- name: Pull docker images
|
- name: Pull docker images
|
||||||
command: docker compose pull
|
ansible.builtin.command: docker compose pull
|
||||||
args:
|
args:
|
||||||
chdir: "{{ mailcow_base_path }}"
|
chdir: "{{ mailcow_base_path }}"
|
||||||
register: mailcow_pull_result
|
register: mailcow_pull_result
|
||||||
changed_when: "'Pulling' in mailcow_pull_result.stdout or 'Downloaded' in mailcow_pull_result.stderr"
|
changed_when: "'Pulling' in mailcow_pull_result.stdout or 'Downloaded' in mailcow_pull_result.stderr"
|
||||||
|
|
||||||
- name: Start Mailcow services
|
- name: Start Mailcow services
|
||||||
command: docker compose up -d
|
ansible.builtin.command: docker compose up -d
|
||||||
args:
|
args:
|
||||||
chdir: "{{ mailcow_base_path }}"
|
chdir: "{{ mailcow_base_path }}"
|
||||||
register: mailcow_up_result
|
register: mailcow_up_result
|
||||||
changed_when: "'Created' in mailcow_up_result.stdout or 'Starting' in mailcow_up_result.stdout"
|
changed_when: "'Created' in mailcow_up_result.stdout or 'Starting' in mailcow_up_result.stdout"
|
||||||
|
|
||||||
- name: Check if ufw is installed
|
- name: Check if ufw is installed
|
||||||
command: which ufw
|
ansible.builtin.command: which ufw
|
||||||
register: ufw_check
|
register: ufw_check
|
||||||
changed_when: false
|
changed_when: false
|
||||||
failed_when: false
|
failed_when: false
|
||||||
|
|
||||||
- name: Configure firewall for mail services
|
- name: Configure firewall for mail services
|
||||||
ufw:
|
community.general.ufw:
|
||||||
rule: allow
|
rule: allow
|
||||||
port: "{{ item.port }}"
|
port: "{{ item.port }}"
|
||||||
proto: "{{ item.proto }}"
|
proto: "{{ item.proto }}"
|
||||||
|
|
@ -195,7 +195,7 @@
|
||||||
- ufw_check.rc == 0
|
- ufw_check.rc == 0
|
||||||
|
|
||||||
- name: Create systemd service for Mailcow
|
- name: Create systemd service for Mailcow
|
||||||
template:
|
ansible.builtin.template:
|
||||||
src: mailcow.service.j2
|
src: mailcow.service.j2
|
||||||
dest: /etc/systemd/system/mailcow.service
|
dest: /etc/systemd/system/mailcow.service
|
||||||
owner: root
|
owner: root
|
||||||
|
|
@ -204,7 +204,7 @@
|
||||||
notify: restart mailcow
|
notify: restart mailcow
|
||||||
|
|
||||||
- name: Enable Mailcow service
|
- name: Enable Mailcow service
|
||||||
systemd:
|
ansible.builtin.systemd:
|
||||||
name: mailcow
|
name: mailcow
|
||||||
enabled: true
|
enabled: true
|
||||||
daemon_reload: true
|
daemon_reload: true
|
||||||
|
|
|
||||||
|
|
@ -25,19 +25,19 @@
|
||||||
- name: Add Icinga apt signing key
|
- name: Add Icinga apt signing key
|
||||||
block:
|
block:
|
||||||
- name: Download Icinga signing key (ASCII-armored)
|
- name: Download Icinga signing key (ASCII-armored)
|
||||||
ansible.builtin.get_url:
|
get_url:
|
||||||
url: "{{ icinga2_apt_key_url }}"
|
url: "{{ icinga2_apt_key_url }}"
|
||||||
dest: /tmp/icinga-key.asc
|
dest: /tmp/icinga-key.asc
|
||||||
mode: "0644"
|
mode: "0644"
|
||||||
force: false
|
force: false
|
||||||
|
|
||||||
- name: Convert key to binary format for apt
|
- name: Convert key to binary format for apt
|
||||||
ansible.builtin.shell:
|
shell:
|
||||||
cmd: gpg --dearmor --yes -o "{{ icinga2_apt_keyring }}" /tmp/icinga-key.asc
|
cmd: gpg --dearmor --yes -o "{{ icinga2_apt_keyring }}" /tmp/icinga-key.asc
|
||||||
creates: "{{ icinga2_apt_keyring }}"
|
creates: "{{ icinga2_apt_keyring }}"
|
||||||
|
|
||||||
- name: Set keyring permissions
|
- name: Set keyring permissions
|
||||||
ansible.builtin.file:
|
file:
|
||||||
path: "{{ icinga2_apt_keyring }}"
|
path: "{{ icinga2_apt_keyring }}"
|
||||||
mode: "0644"
|
mode: "0644"
|
||||||
|
|
||||||
|
|
@ -76,19 +76,19 @@
|
||||||
- name: Add PagerDuty apt signing key
|
- name: Add PagerDuty apt signing key
|
||||||
block:
|
block:
|
||||||
- name: Download PagerDuty signing key (ASCII-armored)
|
- name: Download PagerDuty signing key (ASCII-armored)
|
||||||
ansible.builtin.get_url:
|
get_url:
|
||||||
url: "{{ pdagent_apt_key_url }}"
|
url: "{{ pdagent_apt_key_url }}"
|
||||||
dest: /tmp/pdagent-key.asc
|
dest: /tmp/pdagent-key.asc
|
||||||
mode: "0644"
|
mode: "0644"
|
||||||
force: false
|
force: false
|
||||||
|
|
||||||
- name: Convert key to binary format for apt
|
- name: Convert key to binary format for apt
|
||||||
ansible.builtin.shell:
|
shell:
|
||||||
cmd: gpg --dearmor --yes -o "{{ pdagent_apt_keyring }}" /tmp/pdagent-key.asc
|
cmd: gpg --dearmor --yes -o "{{ pdagent_apt_keyring }}" /tmp/pdagent-key.asc
|
||||||
creates: "{{ pdagent_apt_keyring }}"
|
creates: "{{ pdagent_apt_keyring }}"
|
||||||
|
|
||||||
- name: Set keyring permissions
|
- name: Set keyring permissions
|
||||||
ansible.builtin.file:
|
file:
|
||||||
path: "{{ pdagent_apt_keyring }}"
|
path: "{{ pdagent_apt_keyring }}"
|
||||||
mode: "0644"
|
mode: "0644"
|
||||||
|
|
||||||
|
|
@ -113,7 +113,7 @@
|
||||||
- name: Ensure PHP MySQL extension matches Apache PHP version
|
- name: Ensure PHP MySQL extension matches Apache PHP version
|
||||||
block:
|
block:
|
||||||
- name: Find Apache PHP version
|
- name: Find Apache PHP version
|
||||||
ansible.builtin.shell:
|
shell:
|
||||||
cmd: a2query -m 2>/dev/null | grep -oP 'php\d+\.\d+' | head -1
|
cmd: a2query -m 2>/dev/null | grep -oP 'php\d+\.\d+' | head -1
|
||||||
executable: /bin/bash
|
executable: /bin/bash
|
||||||
register: apache_php_version
|
register: apache_php_version
|
||||||
|
|
@ -121,7 +121,7 @@
|
||||||
check_mode: false
|
check_mode: false
|
||||||
|
|
||||||
- name: Install MySQL module for Apache PHP
|
- name: Install MySQL module for Apache PHP
|
||||||
ansible.builtin.apt:
|
apt:
|
||||||
name: "{{ apache_php_version.stdout }}-mysql"
|
name: "{{ apache_php_version.stdout }}-mysql"
|
||||||
state: present
|
state: present
|
||||||
when: apache_php_version.stdout | length > 0
|
when: apache_php_version.stdout | length > 0
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@
|
||||||
register: pq_sshd_dropin
|
register: pq_sshd_dropin
|
||||||
|
|
||||||
- name: Validate sshd configuration
|
- name: Validate sshd configuration
|
||||||
ansible.builtin.command: sshd -t
|
ansible.builtin.command:
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: Restart sshd to apply key-exchange change
|
- name: Restart sshd to apply key-exchange change
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
- name: restart syncthing
|
- name: restart syncthing
|
||||||
systemd:
|
ansible.builtin.systemd:
|
||||||
name: syncthing@graham
|
name: syncthing@graham
|
||||||
state: restarted
|
state: restarted
|
||||||
daemon_reload: true
|
daemon_reload: true
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
# Install and configure Syncthing
|
# Install and configure Syncthing
|
||||||
|
|
||||||
- name: Install required packages
|
- name: Install required packages
|
||||||
apt:
|
ansible.builtin.apt:
|
||||||
name:
|
name:
|
||||||
- apt-transport-https
|
- apt-transport-https
|
||||||
- curl
|
- curl
|
||||||
|
|
@ -27,18 +27,18 @@
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: Install Syncthing
|
- name: Install Syncthing
|
||||||
apt:
|
ansible.builtin.apt:
|
||||||
name: syncthing
|
name: syncthing
|
||||||
state: present
|
state: present
|
||||||
update_cache: true
|
update_cache: true
|
||||||
|
|
||||||
- name: Ensure graham user exists
|
- name: Ensure graham user exists
|
||||||
user:
|
ansible.builtin.user:
|
||||||
name: graham
|
name: graham
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: Create Syncthing configuration directory
|
- name: Create Syncthing configuration directory
|
||||||
file:
|
ansible.builtin.file:
|
||||||
path: /home/graham/.config/syncthing
|
path: /home/graham/.config/syncthing
|
||||||
state: directory
|
state: directory
|
||||||
owner: graham
|
owner: graham
|
||||||
|
|
@ -46,7 +46,7 @@
|
||||||
mode: '0755'
|
mode: '0755'
|
||||||
|
|
||||||
- name: Deploy Syncthing configuration
|
- name: Deploy Syncthing configuration
|
||||||
template:
|
ansible.builtin.template:
|
||||||
src: config.xml.j2
|
src: config.xml.j2
|
||||||
dest: /home/graham/.config/syncthing/config.xml
|
dest: /home/graham/.config/syncthing/config.xml
|
||||||
owner: graham
|
owner: graham
|
||||||
|
|
@ -56,7 +56,7 @@
|
||||||
notify: restart syncthing
|
notify: restart syncthing
|
||||||
|
|
||||||
- name: Create Syncthing systemd service
|
- name: Create Syncthing systemd service
|
||||||
copy:
|
ansible.builtin.copy:
|
||||||
content: |
|
content: |
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=Syncthing - Open Source Continuous File Synchronization
|
Description=Syncthing - Open Source Continuous File Synchronization
|
||||||
|
|
@ -86,27 +86,27 @@
|
||||||
notify: restart syncthing
|
notify: restart syncthing
|
||||||
|
|
||||||
- name: Stop old syncthing service if exists
|
- name: Stop old syncthing service if exists
|
||||||
systemd:
|
ansible.builtin.systemd:
|
||||||
name: syncthing@syncthing
|
name: syncthing@syncthing
|
||||||
state: stopped
|
state: stopped
|
||||||
enabled: false
|
enabled: false
|
||||||
failed_when: false
|
failed_when: false
|
||||||
|
|
||||||
- name: Enable and start Syncthing service
|
- name: Enable and start Syncthing service
|
||||||
systemd:
|
ansible.builtin.systemd:
|
||||||
name: syncthing@graham
|
name: syncthing@graham
|
||||||
enabled: true
|
enabled: true
|
||||||
state: started
|
state: started
|
||||||
daemon_reload: true
|
daemon_reload: true
|
||||||
|
|
||||||
- name: Check if ufw is installed
|
- name: Check if ufw is installed
|
||||||
command: which ufw
|
ansible.builtin.command: which ufw
|
||||||
register: ufw_check
|
register: ufw_check
|
||||||
changed_when: false
|
changed_when: false
|
||||||
failed_when: false
|
failed_when: false
|
||||||
|
|
||||||
- name: Configure firewall for Syncthing web UI
|
- name: Configure firewall for Syncthing web UI
|
||||||
ufw:
|
community.general.ufw:
|
||||||
rule: allow
|
rule: allow
|
||||||
port: '8384'
|
port: '8384'
|
||||||
proto: tcp
|
proto: tcp
|
||||||
|
|
@ -116,7 +116,7 @@
|
||||||
- ufw_check.rc == 0
|
- ufw_check.rc == 0
|
||||||
|
|
||||||
- name: Configure firewall for Syncthing sync protocol
|
- name: Configure firewall for Syncthing sync protocol
|
||||||
ufw:
|
community.general.ufw:
|
||||||
rule: allow
|
rule: allow
|
||||||
port: '22000'
|
port: '22000'
|
||||||
proto: tcp
|
proto: tcp
|
||||||
|
|
@ -126,7 +126,7 @@
|
||||||
- ufw_check.rc == 0
|
- ufw_check.rc == 0
|
||||||
|
|
||||||
- name: Configure firewall for Syncthing discovery
|
- name: Configure firewall for Syncthing discovery
|
||||||
ufw:
|
community.general.ufw:
|
||||||
rule: allow
|
rule: allow
|
||||||
port: '21027'
|
port: '21027'
|
||||||
proto: udp
|
proto: udp
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue