Files
automation/cluster-experiments/docker-swarm/create-cluster.yml
2026-04-11 09:51:19 +02:00

99 lines
3.9 KiB
YAML

- name: Initialize Docker Swarm on the first manager
hosts: manager[0]
become: true
tasks:
- name: Check if node is already a manager
command: docker node inspect self --format '{{ "{{ .ManagerStatus }}" }}'
register: manager_status
ignore_errors: true
changed_when: false
- name: Initialize Docker Swarm if not already a manager
command: docker swarm init --advertise-addr {{ ansible_default_ipv4.address }}
register: swarm_init
when: manager_status.rc != 0
failed_when: swarm_init.rc != 0 and "'This node is already part of a swarm' not in swarm_init.stderr"
changed_when: "'Swarm initialized' in swarm_init.stdout"
- name: Get manager join-token
command: docker swarm join-token manager -q
register: manager_join_token
- name: Get worker join-token
command: docker swarm join-token worker -q
register: worker_join_token
- name: Set fact with join details
set_fact:
swarm_leader_ip: "{{ ansible_default_ipv4.address }}"
swarm_manager_token: "{{ manager_join_token.stdout }}"
swarm_worker_token: "{{ worker_join_token.stdout }}"
- name: Propagate join info globally
add_host:
name: "swarm_info_host"
swarm_leader_ip: "{{ swarm_leader_ip }}"
swarm_manager_token: "{{ swarm_manager_token }}"
swarm_worker_token: "{{ swarm_worker_token }}"
changed_when: false
- name: Join additional managers to Swarm
hosts: swarm_managers:!manager[0]
become: true
vars:
swarm_info: "{{ hostvars['swarm_info_host'] }}"
tasks:
- name: Check if already in a swarm
command: docker info --format '{{ "{{ .Swarm.LocalNodeState }}" }}'
register: manager2_swarm_status
ignore_errors: true
changed_when: false
- name: Join as manager (if not already part of a swarm)
command: >
docker swarm join --token {{ swarm_info['swarm_manager_token'] }}
{{ swarm_info['swarm_leader_ip'] }}:2377
when: manager2_swarm_status.stdout != "active"
- name: Join swarm_workers to Swarm
hosts: swarm_workers
become: true
vars:
swarm_info: "{{ hostvars['swarm_info_host'] }}"
tasks:
- name: Check if node is already part of a swarm
command: docker info --format '{{ "{{ .Swarm.LocalNodeState }}" }}'
register: swarm_worker_status
ignore_errors: true
changed_when: false
- name: Join as worker (if not already part of a swarm)
command: >
docker swarm join --token {{ swarm_info['swarm_worker_token'] }}
{{ swarm_info['swarm_leader_ip'] }}:2377
when: swarm_worker_status.stdout != "active"
- name: Verify all nodes are present in the swarm
hosts: manager[0]
become: true
tasks:
- name: Get list of all nodes and their roles in the swarm
command: docker node ls --format '{{ "{{ .Hostname }}|{{ .ManagerStatus }}" }}'
register: swarm_nodes
- name: Parse manager and worker counts
set_fact:
manager_count: "{{ swarm_nodes.stdout_lines | select('search', 'Leader|Reachable') | list | length }}"
worker_count: "{{ swarm_nodes.stdout_lines | select('search', '^((?!Leader|Reachable).)*$') | list | length }}"
- name: Show parsed node roles
debug:
msg:
- "Managers found: {{ manager_count }} (expected: {{ groups['swarm_managers'] | length }})"
- "Workers found: {{ worker_count }} (expected: {{ groups['swarm_workers'] | length }})"
- name: Fail if manager or worker counts do not match inventory
fail:
msg: |
Swarm node count mismatch!
Managers found: {{ manager_count }} (expected: {{ groups['swarm_managers'] | length }})
Workers found: {{ worker_count }} (expected: {{ groups['swarm_workers'] | length }})
All nodes: {{ swarm_nodes.stdout_lines }}
when: (manager_count | int) != (groups['swarm_managers'] | length) or (worker_count | int) != (groups['swarm_workers'] | length)