Ansible meldt gestart, maar WireGuard draait nog met de oude configuratie
state: started laat een al draaiende unit met rust, dus een herschreven wg0.conf wordt nooit toegepast. Voeg een change-handler toe en vergelijk daarna het live apparaat met het bestand.
De playbook-run eindigt groen, de WireGuard-unit is actief, de handshake werkt, en de nieuwe peer bereikt nog steeds niets. Een playbook succes zien melden terwijl de server met de configuratie van gisteren draait, is bijzonder frustrerend, want er is niets mis met de uitvoer. Ansible deed precies wat er gevraagd was: het zorgde dat de unit gestart was, en de unit was al gestart. Een herschreven configuratiebestand toepassen is een andere taak, en dat gebeurt alleen als iets de dienst vraagt het opnieuw te lezen.
Kijk wat een tweede run werkelijk meldt
Draai de playbook twee keer met de gewijzigde configuratie en vergelijk de samenvatting. De tweede run hoort de unittaak als ok te tonen, niet als changed, omdat een al draaiende dienst met opzet met rust wordt gelaten. Dat is idempotentie die correct werkt, en het is ook de reden dat het nieuwe bestand nooit de kernel bereikt.
Voeg een controle-run met diff-uitvoer toe om te zien welke taken eigenlijk iets zouden aanraken.
ansible-playbook -i inventory site.yml --check --diff
systemctl show wg-quick@wg0 -p ActiveEnterTimestamp -p NRestarts
stat -c '%y %n' /etc/wireguard/wg0.confDe drie tijdstempels vertellen het verhaal voordat je één logregel leest. Als het configuratiebestand nieuwer is dan het moment waarop de unit actief werd, is de draaiende interface uit een ouder bestand gebouwd, en elk volgend symptoom komt daaruit voort.
Dit is geen defect in Ansible. Hetzelfde gedrag verschijnt bij elke configuratiebeheertool die «zorg dat het draait» scheidt van «zorg dat het dit draait». Het verschil lijkt pedant tot het je een middag kost.
Gestart is een toestand, geen herladen
state: started beweert een voorwaarde over de unit. Het belooft niet dat de dienst zijn invoer opnieuw leest, en het kan niet weten dat een bestand dat het nooit opende is gewijzigd. Bij een wg-quick-implementatie omvat de invoer de interfaceconfiguratie, de adressen, de routes, de DNS-regels en eventuele post-up-hooks.
Daarom kan een bijgewerkt bestand een nieuwe peer, een ander adres of een gewijzigde routeringsinstructie bevatten terwijl de live interface de oude set blijft bedienen. De handshake slaagt nog omdat de geladen sleutels en eindpunten nog geldig zijn. Dat maakt de fout juist moeilijk zichtbaar, en daarom jagen mensen een uur op DNS voordat ze een tijdstempel controleren.
Twee andere module-opties worden vaak voor een oplossing aangezien. daemon_reload laat systemd unitbestanden opnieuw lezen, wat irrelevant is voor een WireGuard-configuratiebestand. state: reloaded vraagt de unit zijn herlaadactie uit te voeren, en of die doet wat je nodig hebt, hangt volledig van de unit af. Geen van beide vervangt weten welke invoer het draaiende proces werkelijk heeft gelezen.
Installeer het bestand en informeer dan een handler
Het patroon dat idempotentie behoudt en toch wijzigingen toepast, is het gebruikelijke: de taak die het bestand schrijft, informeert een handler, en de handler draait alleen als het bestand werkelijk is gewijzigd. Een tweede run zonder bewerkingen doet niets, en dat is wat je wilt.
- name: write the interface configuration
ansible.builtin.template:
src: wg0.conf.j2
dest: /etc/wireguard/wg0.conf
owner: root
mode: "0600"
notify: apply wg0
- name: ensure the interface unit is enabled
ansible.builtin.systemd_service:
name: wg-quick@wg0
enabled: true
state: started
- name: apply wg0
listen: apply wg0
ansible.builtin.systemd_service:
name: wg-quick@wg0
state: restartedHandlers draaien aan het einde van de play, na de taken die hen informeerden, dus een taak later in dezelfde play kan nog de oude interface zien. Als de volgorde belangrijk is, leeg de handlers dan expliciet met meta: flush_handlers voordat de taak draait die van de nieuwe configuratie afhangt.
Gebruik restart in plaats van reload, tenzij je de herlaadactie van de unit hebt gecontroleerd. De upstream wg-quick-unit ondersteunt er een en synchroniseert de WireGuard-configuratie, maar voert de configuratie van adressen, routes, DNS en hooks niet opnieuw uit. Een reload na het toevoegen van een route-instructie lijkt dus te slagen en verandert niets.
Vergelijk het live apparaat met het bestand
De controle die deze foutklasse sluit, is een vergelijking tussen wat de kernel vasthoudt en wat het bestand zegt. Twee opdrachten geven vergelijkbare uitvoer, en het verschil is de afwijking.
sudo wg showconf wg0
sudo wg-quick strip wg0
sudo diff <(sudo wg showconf wg0) <(sudo wg-quick strip wg0)wg showconf drukt het live apparaat af, inclusief de privésleutel, dus behandel die uitvoer als geheim en plak hem niet in een ticket. wg-quick strip drukt het bestand af zonder de wg-quick-specifieke sleutels, en daarom zijn de twee eigenlijk vergelijkbaar.
Een verschil in de peer-lijst betekent dat het bestand nooit is toegepast. Een verschil dat beperkt blijft tot sleutels of eindpunten waarvan je verwachtte dat ze zouden veranderen, betekent dat iets het gedeeltelijk heeft toegepast. Geen verschil betekent dat de configuratie actueel is en de fout elders zit, wat op zichzelf een nuttig resultaat is.
Betaal de kosten van de herstart bewust
Een herstart van de interface breekt de tunnel af, en als die tunnel je beheersessie draagt, beëindigt de herstart de sessie die erom vroeg. Zet de handler achter een wijzigingsvenster, of draai de playbook vanaf een beheerpad dat niet afhangt van het herstarten van de interface.
De kosten zijn de reden dat mensen naar reload grijpen. Het is een redelijke instinct, en het wordt correct zodra je weet welke wijzigingen een reload werkelijk toepast. Voor peer- en sleutelwijzigingen op de upstream wg-quick-unit is het genoeg; voor adressering, routering en hooks niet. Dat één keer uitzoeken is goedkoper dan het ontdekken tijdens een wijzigingsvenster.
De documentatie van de systemd_service-module legt het verschil uit tussen started, restarted en reloaded, en het is de moeite waard die één keer te lezen in plaats van het uit een groene samenvatting af te leiden. Alles in deze uitleg volgt uit dat ene verschil.