Merge branch 'main' of ssh://gitea.purpleraft.com:2001/PurpleRaft/semaphore
This commit is contained in:
57
playbooks/borgmatic-backup.yml
Normal file
57
playbooks/borgmatic-backup.yml
Normal 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"
|
||||
79
playbooks/install-node-exporter.yml
Normal file
79
playbooks/install-node-exporter.yml
Normal 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
|
||||
66
playbooks/install_glpi-agent.yml
Normal file
66
playbooks/install_glpi-agent.yml
Normal 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
|
||||
59
playbooks/package_setup.yml
Normal file
59
playbooks/package_setup.yml
Normal 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
|
||||
|
||||
29
playbooks/templates/borg/borgmatic-config.yaml.j2
Normal file
29
playbooks/templates/borg/borgmatic-config.yaml.j2
Normal 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
|
||||
Reference in New Issue
Block a user