From 6ccd60b4a347de4dbb5add868f30d94ea1835d6d Mon Sep 17 00:00:00 2001 From: Ryan Hamilton Date: Tue, 22 Jul 2025 01:25:37 +0000 Subject: [PATCH 01/13] Add playbooks/install-node-exporter.yml --- playbooks/install-node-exporter.yml | 68 +++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 playbooks/install-node-exporter.yml diff --git a/playbooks/install-node-exporter.yml b/playbooks/install-node-exporter.yml new file mode 100644 index 0000000..357d340 --- /dev/null +++ b/playbooks/install-node-exporter.yml @@ -0,0 +1,68 @@ +- name: Install Node Exporter from binary + hosts: all + become: true + + vars: + node_exporter_version: "1.9.1" + node_exporter_user: "node_exporter" + node_exporter_listen: "0.0.0.0:9100" + node_exporter_bin_dir: "/usr/local/bin" + node_exporter_service_path: "/etc/systemd/system/node_exporter.service" + + tasks: + - name: Ensure node_exporter user exists + user: + name: "{{ node_exporter_user }}" + shell: /usr/sbin/nologin + system: true + create_home: false + + - name: Download Node Exporter archive + get_url: + url: "https://github.com/prometheus/node_exporter/releases/download/v{{ node_exporter_version }}/node_exporter-{{ node_exporter_version }}.linux-amd64.tar.gz" + dest: "/tmp/node_exporter.tar.gz" + mode: "0644" + + - name: Extract Node Exporter binary + unarchive: + src: "/tmp/node_exporter.tar.gz" + dest: "/tmp/" + remote_src: true + + - name: Install binary + copy: + src: "/tmp/node_exporter-{{ node_exporter_version }}.linux-amd64/node_exporter" + dest: "{{ node_exporter_bin_dir }}/node_exporter" + mode: "0755" + owner: root + group: root + + - name: Create systemd service + copy: + dest: "{{ node_exporter_service_path }}" + content: | + [Unit] + Description=Prometheus Node Exporter + After=network.target + + [Service] + User={{ node_exporter_user }} + ExecStart={{ node_exporter_bin_dir }}/node_exporter --web.listen-address={{ node_exporter_listen }} + Restart=always + + [Install] + WantedBy=multi-user.target + notify: Restart node_exporter + + - name: Enable and start node_exporter + systemd: + name: node_exporter + enabled: true + state: started + daemon_reload: true + + handlers: + - name: Restart node_exporter + systemd: + name: node_exporter + state: restarted From 406970bea35cba0a0fa64af749fa7137cc8d7c37 Mon Sep 17 00:00:00 2001 From: Ryan Hamilton Date: Tue, 22 Jul 2025 01:28:28 +0000 Subject: [PATCH 02/13] Update playbooks/install-node-exporter.yml --- playbooks/install-node-exporter.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/playbooks/install-node-exporter.yml b/playbooks/install-node-exporter.yml index 357d340..7f093b0 100644 --- a/playbooks/install-node-exporter.yml +++ b/playbooks/install-node-exporter.yml @@ -29,10 +29,12 @@ dest: "/tmp/" remote_src: true - - name: Install binary - copy: - src: "/tmp/node_exporter-{{ node_exporter_version }}.linux-amd64/node_exporter" - dest: "{{ node_exporter_bin_dir }}/node_exporter" + - name: Move Node Exporter binary into place + command: mv /tmp/node_exporter-{{ node_exporter_version }}.linux-amd64/node_exporter {{ node_exporter_bin_dir }}/node_exporter + + - name: Set binary permissions + file: + path: "{{ node_exporter_bin_dir }}/node_exporter" mode: "0755" owner: root group: root From c99eb0bdbb008c98223dcbe83f1b5160754ebb06 Mon Sep 17 00:00:00 2001 From: Ryan Hamilton Date: Wed, 30 Jul 2025 05:44:16 +0000 Subject: [PATCH 03/13] Add playbooks/borgmatic-backup.yml --- playbooks/borgmatic-backup.yml | 57 ++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 playbooks/borgmatic-backup.yml diff --git a/playbooks/borgmatic-backup.yml b/playbooks/borgmatic-backup.yml new file mode 100644 index 0000000..5848ffa --- /dev/null +++ b/playbooks/borgmatic-backup.yml @@ -0,0 +1,57 @@ +--- +- name: Configure Borgmatic backup with deterministic offset + hosts: all + become: true + + vars: + borgmatic_bin: /usr/local/bin/borgmatic + backup_hour: 2 # Base hour to run backups + backup_window: 1800 # 30 min window (in seconds) + borgmatic_config_dir: /etc/borgmatic + + tasks: + - name: Ensure Borg and dependencies are present + package: + name: + - borgbackup + - python3-pip + state: present + + - name: Ensure borgmatic is installed via pip + pip: + name: borgmatic + executable: pip3 + + - name: Create borgmatic config directory + file: + path: "{{ borgmatic_config_dir }}" + state: directory + owner: root + group: root + mode: '0755' + + - name: Generate deterministic backup offset + set_fact: + backup_offset: >- + {{ (inventory_hostname | hash('md5') | int(base=16)) % backup_window }} + + - name: Split offset into minutes and seconds + set_fact: + backup_offset_minutes: "{{ backup_offset // 60 }}" + backup_offset_seconds: "{{ backup_offset % 60 }}" + + - name: Deploy borgmatic config + template: + src: borgmatic-config.yaml.j2 + dest: "{{ borgmatic_config_dir }}/config.yaml" + owner: root + group: root + mode: '0600' + + - name: Create cron job for borgmatic with offset + cron: + name: "Nightly borgmatic backup" + user: root + hour: "{{ backup_hour }}" + minute: "{{ backup_offset_minutes }}" + job: "sleep {{ backup_offset_seconds }} && {{ borgmatic_bin }} --verbosity 1" From 0f8796759d2129fc24d1d028143125c62e63820f Mon Sep 17 00:00:00 2001 From: Ryan Hamilton Date: Wed, 30 Jul 2025 05:45:30 +0000 Subject: [PATCH 04/13] Add playbooks/templates/borg/borgmatic-config.yaml.j2 --- .../templates/borg/borgmatic-config.yaml.j2 | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 playbooks/templates/borg/borgmatic-config.yaml.j2 diff --git a/playbooks/templates/borg/borgmatic-config.yaml.j2 b/playbooks/templates/borg/borgmatic-config.yaml.j2 new file mode 100644 index 0000000..247b65a --- /dev/null +++ b/playbooks/templates/borg/borgmatic-config.yaml.j2 @@ -0,0 +1,24 @@ +location: + source_directories: + # ✅ Always back up system configuration + - /etc + + # Uncomment these if you want Docker data/configs + # - /srv/docker + # - /opt/docker + + # ✅ Borg repository destination (injected as a variable) + repositories: + - {{ borg_repo_url }} + + # ✅ Include hostname in archive names for multi-host dedupe + archive_name_format: "{hostname}-{now:%Y-%m-%dT%H:%M:%S}" + +storage: + # ✅ Encryption key; supply via vault/secret + encryption_passphrase: "{{ borg_encryption_passphrase | default('changeme') }}" + +retention: + keep_daily: 7 + keep_weekly: 4 + keep_monthly: 6 From b0b4814ee7d450a9a0cd68cf0128462f3410d478 Mon Sep 17 00:00:00 2001 From: Ryan Hamilton Date: Wed, 30 Jul 2025 05:46:31 +0000 Subject: [PATCH 05/13] Update playbooks/borgmatic-backup.yml --- playbooks/borgmatic-backup.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playbooks/borgmatic-backup.yml b/playbooks/borgmatic-backup.yml index 5848ffa..6fc5134 100644 --- a/playbooks/borgmatic-backup.yml +++ b/playbooks/borgmatic-backup.yml @@ -42,7 +42,7 @@ - name: Deploy borgmatic config template: - src: borgmatic-config.yaml.j2 + src: templates/borg/borgmatic-config.yaml.j2 dest: "{{ borgmatic_config_dir }}/config.yaml" owner: root group: root From 0a51a33ec2a503ffceaf7eb32ca46a00888a112b Mon Sep 17 00:00:00 2001 From: Ryan Hamilton Date: Wed, 30 Jul 2025 17:18:46 +0000 Subject: [PATCH 06/13] Update playbooks/templates/borg/borgmatic-config.yaml.j2 --- playbooks/templates/borg/borgmatic-config.yaml.j2 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/playbooks/templates/borg/borgmatic-config.yaml.j2 b/playbooks/templates/borg/borgmatic-config.yaml.j2 index 247b65a..9beff46 100644 --- a/playbooks/templates/borg/borgmatic-config.yaml.j2 +++ b/playbooks/templates/borg/borgmatic-config.yaml.j2 @@ -14,6 +14,9 @@ location: # ✅ Include hostname in archive names for multi-host dedupe archive_name_format: "{hostname}-{now:%Y-%m-%dT%H:%M:%S}" + # ✅ Use a dedicated SSH key for Borg backups + ssh_command: "ssh -i /root/.ssh/borg" + storage: # ✅ Encryption key; supply via vault/secret encryption_passphrase: "{{ borg_encryption_passphrase | default('changeme') }}" From bf1234fefb3f229fa390d0c0cfc74582a77450b4 Mon Sep 17 00:00:00 2001 From: Ryan Hamilton Date: Wed, 30 Jul 2025 17:20:15 +0000 Subject: [PATCH 07/13] Update playbooks/templates/borg/borgmatic-config.yaml.j2 --- playbooks/templates/borg/borgmatic-config.yaml.j2 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/playbooks/templates/borg/borgmatic-config.yaml.j2 b/playbooks/templates/borg/borgmatic-config.yaml.j2 index 9beff46..4acfcf9 100644 --- a/playbooks/templates/borg/borgmatic-config.yaml.j2 +++ b/playbooks/templates/borg/borgmatic-config.yaml.j2 @@ -16,6 +16,8 @@ location: # ✅ Use a dedicated SSH key for Borg backups ssh_command: "ssh -i /root/.ssh/borg" + # To use this key each client needs the following command run: (and the public key added to the repo server) + # sudo ssh-keygen -t ed25519 -f /root/.ssh/borg storage: # ✅ Encryption key; supply via vault/secret From 1e0abc31479b25c5e6a53e78baafb81edbc15727 Mon Sep 17 00:00:00 2001 From: Ryan Hamilton Date: Wed, 30 Jul 2025 17:20:33 +0000 Subject: [PATCH 08/13] Update playbooks/templates/borg/borgmatic-config.yaml.j2 --- playbooks/templates/borg/borgmatic-config.yaml.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playbooks/templates/borg/borgmatic-config.yaml.j2 b/playbooks/templates/borg/borgmatic-config.yaml.j2 index 4acfcf9..d38e124 100644 --- a/playbooks/templates/borg/borgmatic-config.yaml.j2 +++ b/playbooks/templates/borg/borgmatic-config.yaml.j2 @@ -17,7 +17,7 @@ location: # ✅ Use a dedicated SSH key for Borg backups ssh_command: "ssh -i /root/.ssh/borg" # To use this key each client needs the following command run: (and the public key added to the repo server) - # sudo ssh-keygen -t ed25519 -f /root/.ssh/borg + # (First sudo su) ssh-keygen -t ed25519 -f /root/.ssh/borg storage: # ✅ Encryption key; supply via vault/secret From c55cf916060b54b96c850df23deafa4c764e884e Mon Sep 17 00:00:00 2001 From: Ryan Hamilton Date: Wed, 30 Jul 2025 17:51:04 +0000 Subject: [PATCH 09/13] Update playbooks/borgmatic-backup.yml --- playbooks/borgmatic-backup.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playbooks/borgmatic-backup.yml b/playbooks/borgmatic-backup.yml index 6fc5134..9943904 100644 --- a/playbooks/borgmatic-backup.yml +++ b/playbooks/borgmatic-backup.yml @@ -33,7 +33,7 @@ - name: Generate deterministic backup offset set_fact: backup_offset: >- - {{ (inventory_hostname | hash('md5') | int(base=16)) % backup_window }} + {{ ((inventory_hostname | hash('md5') | int(base=16)) % backup_window) | int }} - name: Split offset into minutes and seconds set_fact: From 4321807f1cad9e19c69aec5935b6bbec9e194105 Mon Sep 17 00:00:00 2001 From: Ryan Hamilton Date: Wed, 30 Jul 2025 17:54:09 +0000 Subject: [PATCH 10/13] Update playbooks/borgmatic-backup.yml --- playbooks/borgmatic-backup.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/playbooks/borgmatic-backup.yml b/playbooks/borgmatic-backup.yml index 9943904..ada992f 100644 --- a/playbooks/borgmatic-backup.yml +++ b/playbooks/borgmatic-backup.yml @@ -37,8 +37,8 @@ - name: Split offset into minutes and seconds set_fact: - backup_offset_minutes: "{{ backup_offset // 60 }}" - backup_offset_seconds: "{{ backup_offset % 60 }}" + backup_offset_minutes: "{{ backup_offset | int // 60 }}" + backup_offset_seconds: "{{ backup_offset | int % 60 }}" - name: Deploy borgmatic config template: @@ -53,5 +53,5 @@ name: "Nightly borgmatic backup" user: root hour: "{{ backup_hour }}" - minute: "{{ backup_offset_minutes }}" - job: "sleep {{ backup_offset_seconds }} && {{ borgmatic_bin }} --verbosity 1" + minute: "{{ backup_offset_minutes | int }}" + job: "sleep {{ backup_offset_seconds | int }} && {{ borgmatic_bin }} --verbosity 1" From 5af671e790001f5a09bde8dd3e3169c58a24f027 Mon Sep 17 00:00:00 2001 From: Ryan Hamilton Date: Thu, 31 Jul 2025 05:54:11 +0000 Subject: [PATCH 11/13] Update playbooks/install-node-exporter.yml --- playbooks/install-node-exporter.yml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/playbooks/install-node-exporter.yml b/playbooks/install-node-exporter.yml index 7f093b0..af0d7dd 100644 --- a/playbooks/install-node-exporter.yml +++ b/playbooks/install-node-exporter.yml @@ -8,8 +8,17 @@ node_exporter_listen: "0.0.0.0:9100" node_exporter_bin_dir: "/usr/local/bin" node_exporter_service_path: "/etc/systemd/system/node_exporter.service" + node_exporter_arch_map: + x86_64: "amd64" + aarch64: "arm64" + armv7l: "armv7" + node_exporter_arch: "{{ node_exporter_arch_map[ansible_architecture] | default('amd64') }}" tasks: + - name: Debug detected architecture + debug: + msg: "Detected architecture: {{ ansible_architecture }} -> using {{ node_exporter_arch }} build" + - name: Ensure node_exporter user exists user: name: "{{ node_exporter_user }}" @@ -19,7 +28,7 @@ - name: Download Node Exporter archive get_url: - url: "https://github.com/prometheus/node_exporter/releases/download/v{{ node_exporter_version }}/node_exporter-{{ node_exporter_version }}.linux-amd64.tar.gz" + url: "https://github.com/prometheus/node_exporter/releases/download/v{{ node_exporter_version }}/node_exporter-{{ node_exporter_version }}.linux-{{ node_exporter_arch }}.tar.gz" dest: "/tmp/node_exporter.tar.gz" mode: "0644" @@ -30,7 +39,7 @@ remote_src: true - name: Move Node Exporter binary into place - command: mv /tmp/node_exporter-{{ node_exporter_version }}.linux-amd64/node_exporter {{ node_exporter_bin_dir }}/node_exporter + command: mv /tmp/node_exporter-{{ node_exporter_version }}.linux-{{ node_exporter_arch }}/node_exporter {{ node_exporter_bin_dir }}/node_exporter - name: Set binary permissions file: From 9e32a232cdf5f33b2a2eaf69f76c5f13619b137b Mon Sep 17 00:00:00 2001 From: Ryan Hamilton Date: Sun, 10 Aug 2025 20:59:11 -0500 Subject: [PATCH 12/13] Add playbook for installing and configuring GLPI Agent --- playbooks/install_glpi-agent.yml | 66 ++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 playbooks/install_glpi-agent.yml diff --git a/playbooks/install_glpi-agent.yml b/playbooks/install_glpi-agent.yml new file mode 100644 index 0000000..8cfcb06 --- /dev/null +++ b/playbooks/install_glpi-agent.yml @@ -0,0 +1,66 @@ +--- +- name: Install and configure GLPI Agent (Perl installer) + hosts: all + become: true + + vars: + glpi_agent_version: "1.15" + glpi_agent_installer_url: "https://github.com/glpi-project/glpi-agent/releases/download/{{ glpi_agent_version }}/glpi-agent-{{ glpi_agent_version }}-linux-installer.pl" + glpi_server_url: "https://glpi.ryans.tools/" # see notes below + glpi_agent_tag: "PurpleRaft" + glpi_httpd_trust: "10.0.0.0/8,192.168.0.0/16,100.64.0.0/10" # GLPI server or management subnets + + tasks: + - name: Ensure prerequisites (perl, curl, lsb-release) + package: + name: + - perl + - curl + - lsb-release + state: present + + - name: Download GLPI Agent Perl installer + get_url: + url: "{{ glpi_agent_installer_url }}" + dest: /usr/local/src/glpi-agent-installer.pl + mode: "0755" + + - name: Run the GLPI Agent installer (idempotent-ish) + command: perl /usr/local/src/glpi-agent-installer.pl + args: + creates: /usr/bin/glpi-agent + + - name: Ensure conf.d directory exists + file: + path: /etc/glpi-agent/conf.d + state: directory + mode: "0755" + + - name: Configure GLPI Agent (server/tag/trust) + copy: + dest: /etc/glpi-agent/conf.d/atlas.cfg + mode: "0644" + content: | + # Managed by Ansible + server = {{ glpi_server_url }} + tag = {{ glpi_agent_tag }} + httpd-trust = {{ glpi_httpd_trust }} + # Optional: uncomment to reduce load after first full inventory + # full-inventory-postpone = 14 + notify: restart glpi-agent + + - name: Enable and start agent service + service: + name: glpi-agent + enabled: true + state: started + + - name: Do a first inventory now (one-shot) + command: glpi-agent --server {{ glpi_server_url }} --force + changed_when: false + + handlers: + - name: restart glpi-agent + service: + name: glpi-agent + state: restarted From 95d24b2306be8659230dff1f9d0f7972dca87d17 Mon Sep 17 00:00:00 2001 From: Ryan Hamilton Date: Sat, 30 Aug 2025 04:36:58 +0000 Subject: [PATCH 13/13] Add playbooks/package_setup.yml --- playbooks/package_setup.yml | 59 +++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 playbooks/package_setup.yml diff --git a/playbooks/package_setup.yml b/playbooks/package_setup.yml new file mode 100644 index 0000000..d8c3c02 --- /dev/null +++ b/playbooks/package_setup.yml @@ -0,0 +1,59 @@ +--- +- name: Baseline essentials for Docker hosts + hosts: all + become: true + + vars: + # --- Feature toggles (override in Semaphore extra vars) --- + enable_install_base: true # core tools everywhere + enable_install_extras: true # QoL/debug tools + enable_remove_packages: true # remove legacy/bloat + + # --- Packages --- + base_packages: + - curl # HTTP CLI + - git # pull repos + - jq # parse JSON (docker inspect, APIs) + - ca-certificates # TLS roots for HTTPS + - iproute2 # modern net tools (ip, ss, etc.) + - acl # file ACL support (setfacl/getfacl) + + extra_packages: + - fzf # fuzzy finder (your new favorite) + - dnsutils # dig/nslookup + - htop # nicer top + - unzip # handle .zip archives + - bat # prettier cat + - tree # directory view + - bash-completion # tab completion goodness + + absent_packages: + - net-tools # ifconfig/netstat (prefer iproute2) + - snapd # don't want snaps + - apport # crash reporter + + tasks: + - name: Install base packages + apt: + name: "{{ base_packages }}" + state: present + update_cache: yes + when: enable_install_base + + - name: Install extra packages + apt: + name: "{{ extra_packages }}" + state: present + when: + - enable_install_extras + - extra_packages | length > 0 + + - name: Remove unwanted packages + apt: + name: "{{ absent_packages }}" + state: absent + purge: yes + when: + - enable_remove_packages + - absent_packages | length > 0 +