From 14f6348bf4d95dbbd8b24aa45d2b56b8b159eab8 Mon Sep 17 00:00:00 2001 From: Maddox Date: Fri, 23 Jan 2026 14:36:08 +0000 Subject: [PATCH] Initial cluster configuration --- ansible.cfg | 18 ++++++++++ inventory/group_vars/all.yml | 12 +++++++ inventory/hosts.yml | 65 ++++++++++++++++++++++++++++++++++++ playbooks/check-status.yml | 26 +++++++++++++++ playbooks/deploy-utils.yml | 28 ++++++++++++++++ playbooks/docker-prune.yml | 19 +++++++++++ playbooks/restart-utils.yml | 27 +++++++++++++++ playbooks/update-all.yml | 38 +++++++++++++++++++++ 8 files changed, 233 insertions(+) create mode 100644 ansible.cfg create mode 100644 inventory/group_vars/all.yml create mode 100644 inventory/hosts.yml create mode 100644 playbooks/check-status.yml create mode 100644 playbooks/deploy-utils.yml create mode 100644 playbooks/docker-prune.yml create mode 100644 playbooks/restart-utils.yml create mode 100644 playbooks/update-all.yml diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 0000000..f534737 --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,18 @@ +[defaults] +inventory = inventory/hosts.yml +remote_user = root +host_key_checking = False +retry_files_enabled = False +gathering = smart +fact_caching = jsonfile +fact_caching_connection = /tmp/ansible_facts +fact_caching_timeout = 86400 +stdout_callback = yaml +forks = 10 + +[privilege_escalation] +become = False + +[ssh_connection] +pipelining = True +ssh_args = -o ControlMaster=auto -o ControlPersist=60s diff --git a/inventory/group_vars/all.yml b/inventory/group_vars/all.yml new file mode 100644 index 0000000..7faec0c --- /dev/null +++ b/inventory/group_vars/all.yml @@ -0,0 +1,12 @@ +--- +ansible_python_interpreter: /usr/bin/python3 +timezone: America/New_York +nas_ip: 192.168.1.251 +nas_media_share: /volume1/Media +nas_downloads_share: /volume1/Downloads +nas_docker_share: /volume1/docker +ntfy_server: https://ntfy.3ddbrewery.com +ntfy_autoheal_topic: autoheal-proxmox +ntfy_watchtower_topic: watchtower-proxmox +docker_compose_version: "3.8" +docker_data_dir: /home/docker/appdata diff --git a/inventory/hosts.yml b/inventory/hosts.yml new file mode 100644 index 0000000..a7bf1bb --- /dev/null +++ b/inventory/hosts.yml @@ -0,0 +1,65 @@ +all: + children: + proxmox_nodes: + hosts: + pve2: + ansible_host: 192.168.1.3 + ansible_user: root + pve-dell: + ansible_host: 192.168.1.4 + ansible_user: root + vms: + hosts: + replicant: + ansible_host: 192.168.1.80 + ansible_user: maddox + ansible_become: yes + docker_appdata: /home/maddox/docker/appdata + databases: + ansible_host: 192.168.1.81 + ansible_user: root + immich: + ansible_host: 192.168.1.82 + ansible_user: root + lxcs: + hosts: + media-transcode: + ansible_host: 192.168.1.120 + ansible_user: root + network-services: + ansible_host: 192.168.1.121 + ansible_user: root + download-stack: + ansible_host: 192.168.1.122 + ansible_user: root + docker666: + ansible_host: 192.168.1.123 + ansible_user: root + docker_appdata: /root/docker/appdata + tailscale-home: + ansible_host: 192.168.1.124 + ansible_user: root + infrastructure: + hosts: + dns-lxc: + ansible_host: 192.168.1.125 + ansible_user: root + legacy: + hosts: + nas: + ansible_host: 192.168.1.251 + ansible_user: maddox + ansible_port: 44822 + alien: + ansible_host: 192.168.1.252 + ansible_user: maddox + docker_hosts: + children: + vms: + lxcs: + all_managed: + children: + proxmox_nodes: + vms: + lxcs: + infrastructure: diff --git a/playbooks/check-status.yml b/playbooks/check-status.yml new file mode 100644 index 0000000..713cc11 --- /dev/null +++ b/playbooks/check-status.yml @@ -0,0 +1,26 @@ +--- +- name: Check cluster status + hosts: all_managed + become: yes + gather_facts: yes + + tasks: + - name: Get disk usage + shell: df -h / | tail -1 | awk '{print $5}' + register: disk_usage + changed_when: false + + - name: Get memory usage + shell: free -m | awk '/^Mem:/ {printf "%.0f%%", $3/$2 * 100}' + register: memory_usage + changed_when: false + + - name: Get container count + shell: docker ps -q 2>/dev/null | wc -l + register: container_count + changed_when: false + failed_when: false + + - name: Display status + debug: + msg: "{{ inventory_hostname }}: Disk={{ disk_usage.stdout }} Mem={{ memory_usage.stdout }} Containers={{ container_count.stdout | default('N/A') }}" diff --git a/playbooks/deploy-utils.yml b/playbooks/deploy-utils.yml new file mode 100644 index 0000000..b99ddbf --- /dev/null +++ b/playbooks/deploy-utils.yml @@ -0,0 +1,28 @@ +--- +- name: Deploy standardized utils stack + hosts: docker_hosts + become: yes + gather_facts: yes + vars: + utils_path: /home/docker/appdata/utils + host_ip: "{{ ansible_default_ipv4.address }}" + host_name: "{{ inventory_hostname }}" + + tasks: + - name: Create utils directory + file: + path: "{{ utils_path }}" + state: directory + mode: '0755' + + - name: Create .env file + copy: + dest: "{{ utils_path }}/.env" + content: | + HOST_IP={{ host_ip }} + HOST_NAME={{ host_name }} + mode: '0600' + + - name: Display completion + debug: + msg: "Utils directory created at {{ utils_path }} for {{ inventory_hostname }}" diff --git a/playbooks/docker-prune.yml b/playbooks/docker-prune.yml new file mode 100644 index 0000000..060db87 --- /dev/null +++ b/playbooks/docker-prune.yml @@ -0,0 +1,19 @@ +--- +- name: Docker cleanup on all hosts + hosts: docker_hosts + become: yes + gather_facts: no + + tasks: + - name: Prune with docker CLI + shell: | + docker image prune -f + docker network prune -f + docker builder prune -f + register: prune_result + changed_when: "'Total reclaimed space' in prune_result.stdout" + + - name: Show prune output + debug: + var: prune_result.stdout_lines + when: prune_result.stdout_lines | length > 0 diff --git a/playbooks/restart-utils.yml b/playbooks/restart-utils.yml new file mode 100644 index 0000000..5d50306 --- /dev/null +++ b/playbooks/restart-utils.yml @@ -0,0 +1,27 @@ +--- +- name: Restart utils stack on Docker hosts + hosts: docker_hosts + become: yes + gather_facts: no + + tasks: + - name: Set utils path + set_fact: + utils_path: "{{ docker_appdata | default('/home/docker/appdata') }}/utils" + + - name: Check if utils compose file exists + stat: + path: "{{ utils_path }}/docker-compose.yml" + register: compose_file + + - name: Restart utils stack + shell: docker compose pull && docker compose up -d --force-recreate + args: + chdir: "{{ utils_path }}" + when: compose_file.stat.exists + register: restart_result + + - name: Skip if no utils stack + debug: + msg: "{{ inventory_hostname }}: No utils stack found at {{ utils_path }}" + when: not compose_file.stat.exists diff --git a/playbooks/update-all.yml b/playbooks/update-all.yml new file mode 100644 index 0000000..6db15b3 --- /dev/null +++ b/playbooks/update-all.yml @@ -0,0 +1,38 @@ +--- +- name: Update all Docker hosts + hosts: docker_hosts + become: yes + gather_facts: yes + vars: + reboot: false + + tasks: + - name: Update apt cache + apt: + update_cache: yes + cache_valid_time: 3600 + + - name: Upgrade all packages + apt: + upgrade: dist + autoremove: yes + autoclean: yes + register: upgrade_result + + - name: Check if reboot is required + stat: + path: /var/run/reboot-required + register: reboot_required + + - name: Notify if reboot needed + debug: + msg: "{{ inventory_hostname }} requires a reboot" + when: reboot_required.stat.exists + + - name: Reboot if required and allowed + reboot: + msg: "Ansible triggered reboot after updates" + reboot_timeout: 300 + when: + - reboot_required.stat.exists + - reboot | bool