---
- name: "π Read the peer state of every interface"
ansible.builtin.command: "wg show {{ mesh_name | quote }} peers"
loop: "{{ WIREGUARD_MESH_NAMES }}"
loop_control:
loop_var: mesh_name
register: wireguard_peer_state
changed_when: false
- name: "π Fail when an interface carries no peer"
ansible.builtin.fail:
msg: >-
WireGuard interface '{{ item.mesh_name }}' on {{ inventory_hostname }}
came up with no peer. The mesh in this host's inventory is incomplete.
loop: "{{ wireguard_peer_state.results }}"
loop_control:
label: "{{ item.mesh_name }}"
when: (item.stdout | trim) | length == 0
- name: "β³ Wait until every interface has a fresh handshake with the peers it awaits"
ansible.builtin.shell: "date +%s && wg show {{ awaited.key | quote }} latest-handshakes"
loop: "{{ WIREGUARD_AWAITED_KEYS | dict2items }}"
loop_control:
loop_var: awaited
label: "{{ awaited.key }}"
register: wireguard_handshakes
changed_when: false
failed_when: false
retries: 24
delay: 5
until:
- wireguard_handshakes.rc == 0
- wireguard_handshakes.stdout | mesh_handshaken(awaited.value)
- name: "π Fail hard when an interface never reached a peer it awaits"
ansible.builtin.fail:
msg: >-
WireGuard interface '{{ item.awaited.key }}' on {{ inventory_hostname }}
holds no fresh handshake with every peer it awaits: a peer never
handshaked, or its last handshake is older than the session lifetime
WireGuard accepts. No deploy can proceed over a partitioned mesh.
loop: "{{ wireguard_handshakes.results }}"
loop_control:
label: "{{ item.awaited.key }}"
when: >-
item.rc != 0
or not (item.stdout | mesh_handshaken(item.awaited.value))
- name: "π Check whether ping is available for the MTU probe"
ansible.builtin.stat:
path: "{{ WIREGUARD_PING_BINARY }}"
register: wireguard_ping
- name: "π Prove the path carries a full-size payload without fragmenting"
ansible.builtin.command: >-
{{ WIREGUARD_PING_BINARY }} -c 2 -W 2 -M do
-s {{ wireguard_overlay_mtu | int - 28 }} {{ item | quote }}
loop: "{{ WIREGUARD_EXPECTED_PEERS }}"
register: wireguard_mtu_probe
changed_when: false
failed_when: false
when: wireguard_ping.stat.exists
- name: "π Fail when the overlay MTU does not survive the tunnel"
ansible.builtin.fail:
msg: >-
A {{ wireguard_overlay_mtu | int }}-byte payload does not reach
{{ oversized | map(attribute='item') | join(', ') }} from
{{ inventory_hostname }}. Stacked VXLAN inside WireGuard needs the
overlay MTU at or below the tunnel's, or large payloads drop silently.
vars:
oversized: >-
{{ wireguard_mtu_probe.results | default([])
| rejectattr('skipped', 'defined')
| rejectattr('rc', 'equalto', 0) | list }}
when: oversized | length > 0