homelab/ansible/archive/playbooks/docker/swarm_preflight.yml

111 lines
4.1 KiB
YAML

---
# ansible/playbooks/docker/swarm_preflight.yml
#
# Swarm Foundation Pre-flight
# ===========================
# Addresses all four hard prerequisites before any service can be deployed to
# the swarm. Run this once after swarm_bootstrap and before swarm_stack_deploy.
#
# Prerequisites satisfied:
# 1. NFS mounts — /mnt/homelab + /mnt/media mounted on every node
# 2. proxy-net — overlay network present on the swarm (172.20.0.0/24)
# 3. Node labels — role=manager / role=worker applied to every node
# 4. /opt/stacks — deploy root created on every node (owned by lab user)
#
# Usage:
# # Dry-run (safe, no changes):
# ansible-playbook -i inventory/hosts.ini playbooks/docker/swarm_preflight.yml --check
#
# # Live run:
# ansible-playbook -i inventory/hosts.ini playbooks/docker/swarm_preflight.yml
#
# # Single-concern run:
# ansible-playbook -i inventory/hosts.ini playbooks/docker/swarm_preflight.yml --tags storage
# ansible-playbook -i inventory/hosts.ini playbooks/docker/swarm_preflight.yml --tags network
# ansible-playbook -i inventory/hosts.ini playbooks/docker/swarm_preflight.yml --tags labels
# ansible-playbook -i inventory/hosts.ini playbooks/docker/swarm_preflight.yml --tags stacks_root
#
# Verification (post-run):
# ansible swarm_hosts -i inventory/hosts.ini -m command -a "findmnt /mnt/homelab"
# ansible swarm_hosts -i inventory/hosts.ini -m stat -a "path=/opt/stacks"
# docker node ls --format '{{ "{{" }}.Hostname{{ "}}" }}\t{{ "{{" }}.Labels{{ "}}" }}'
# docker network inspect proxy-net
###############################################################################
# PLAY 1 — Storage: NFS mounts + /opt/stacks on every swarm node #
###############################################################################
- name: "Swarm pre-flight | Storage"
hosts: swarm_hosts
become: true
gather_facts: false
tags: [storage, stacks_root]
vars:
lab_user: "{{ lab_ansible_user | default('chester') }}"
roles:
- role: storage_mounts
tags: [storage]
tasks:
- name: "Create /opt/stacks deploy root"
ansible.builtin.file:
path: /opt/stacks
state: directory
owner: "{{ lab_user }}"
group: "{{ lab_user }}"
mode: "0755"
tags: [stacks_root]
###############################################################################
# PLAY 2 — Network: ensure proxy-net overlay exists (run from one manager) #
###############################################################################
- name: "Swarm pre-flight | proxy-net overlay network"
hosts: swarm_managers[0]
become: false
gather_facts: false
tags: [network]
roles:
- role: swarm_overlay_network
tags: [network]
###############################################################################
# PLAY 3 — Labels: apply role=manager / role=worker to every swarm node #
###############################################################################
- name: "Swarm pre-flight | Node labels"
hosts: swarm_managers[0]
become: false
gather_facts: false
tags: [labels]
tasks:
- name: "Apply role=manager label to manager nodes"
ansible.builtin.command: >-
docker node update --label-add role=manager {{ item }}
loop: "{{ groups['swarm_managers'] }}"
changed_when: false
# docker node update is idempotent — labels are additive and
# re-applying the same label does not change cluster state.
tags: [labels]
- name: "Apply role=worker label to worker nodes"
ansible.builtin.command: >-
docker node update --label-add role=worker {{ item }}
loop: "{{ groups['swarm_workers'] }}"
changed_when: false
tags: [labels]
- name: "Show node label summary"
ansible.builtin.shell: >-
for node in $(docker node ls --format "{{ '{{' }}.Hostname{{ '}}' }}"); do
echo "$node $(docker node inspect $node --format '{{ '{{' }}json .Spec.Labels{{ '}}' }}')";
done
register: swarm_node_summary
changed_when: false
tags: [labels]
- name: "Print node label summary"
ansible.builtin.debug:
msg: "{{ swarm_node_summary.stdout_lines }}"
tags: [labels]