Merge branch 'main' of ssh://gitea.purpleraft.com:2001/PurpleRaft/semaphore

This commit is contained in:
2025-09-30 07:53:13 -05:00
5 changed files with 290 additions and 0 deletions

View File

@@ -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) | int }}
- name: Split offset into minutes and seconds
set_fact:
backup_offset_minutes: "{{ backup_offset | int // 60 }}"
backup_offset_seconds: "{{ backup_offset | int % 60 }}"
- name: Deploy borgmatic config
template:
src: templates/borg/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 | int }}"
job: "sleep {{ backup_offset_seconds | int }} && {{ borgmatic_bin }} --verbosity 1"

View File

@@ -0,0 +1,79 @@
- 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"
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 }}"
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-{{ node_exporter_arch }}.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: Move Node Exporter binary into place
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:
path: "{{ 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

View File

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

View File

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

View File

@@ -0,0 +1,29 @@
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}"
# ✅ 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)
# (First sudo su) ssh-keygen -t ed25519 -f /root/.ssh/borg
storage:
# ✅ Encryption key; supply via vault/secret
encryption_passphrase: "{{ borg_encryption_passphrase | default('changeme') }}"
retention:
keep_daily: 7
keep_weekly: 4
keep_monthly: 6