Ansible sier startet, men WireGuard kjører fortsatt den gamle konfigurasjonen
state: started lar en enhet som allerede kjører være i fred, så en omskrevet wg0.conf blir aldri brukt. Legg til en endringshandler, og sammenlign deretter den levende enheten med filen.
Playbook-kjøringen slutter grønt, WireGuard-enheten er aktiv, håndtrykket virker, og den nye peer-en når fortsatt ingenting. Å se en playbook melde suksess mens serveren kjører gårsdagens konfigurasjon er særlig frustrerende, fordi ingenting i utdataene er galt. Ansible gjorde nøyaktig det det ble bedt om: det sørget for at enheten var startet, og enheten var allerede startet. Å bruke en omskrevet konfigurasjonsfil er en annen oppgave, og det skjer bare hvis noe ber tjenesten lese den på nytt.
Se hva en andre kjøring faktisk rapporterer
Kjør playbooken to ganger med den endrede konfigurasjonen og sammenlign sammendraget. Den andre kjøringen bør vise enhetsoppgaven som ok, ikke changed, fordi en tjeneste som allerede kjører med vilje får være i fred. Det er idempotens som virker riktig, og det er også grunnen til at den nye filen aldri når kjernen.
Legg til en kontrollkjøring med diff-utdata for å se hvilke oppgaver som i det hele tatt ville røre noe.
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 tre tidsstemplene forteller historien før du leser én eneste logglinje. Hvis konfigurasjonsfilen er nyere enn øyeblikket enheten ble aktiv, er det kjørende grensesnittet bygget fra en eldre fil, og hvert påfølgende symptom følger av det.
Dette er ikke en feil i Ansible. Samme oppførsel vises med ethvert konfigurasjonsstyringsverktøy som skiller «sørg for at det kjører» fra «sørg for at det kjører dette». Forskjellen virker pedantisk helt til den koster deg en ettermiddag.
Startet er en tilstand, ikke en omlasting
state: started hevder en betingelse om enheten. Det lover ikke at tjenesten leser inndataene sine på nytt, og det kan ikke vite at en fil det aldri har åpnet, er endret. Ved en wg-quick-utrulling omfatter inndataene grensesnittkonfigurasjonen, adressene, rutene, DNS-oppføringene og eventuelle post-up-hooks.
Derfor kan en oppdatert fil inneholde en ny peer, en annen adresse eller en endret rutingdirektiv mens det levende grensesnittet fortsatt betjener det gamle settet. Håndtrykket lykkes fortsatt fordi nøklene og endepunktene som ble lastet, fortsatt er gyldige. Nettopp det gjør feilen vanskelig å se, og derfor jager folk DNS i en time før de sjekker et tidsstempel.
To andre modulvalg oppfattes ofte som en løsning. daemon_reload får systemd til å lese enhetsfiler på nytt, noe som er irrelevant for en WireGuard-konfigurasjonsfil. state: reloaded ber enheten kjøre omlastingshandlingen sin, og om den gjør det du trenger, avhenger helt av enheten. Ingen av dem erstatter å vite hvilke inndata den kjørende prosessen faktisk leste.
Installer filen, og varsle deretter en handler
Mønsteret som bevarer idempotensen og likevel bruker endringer, er det vanlige: oppgaven som skriver filen, varsler en handler, og handleren kjører bare når filen faktisk er endret. En andre kjøring uten redigeringer gjør ingenting, og det er det du vil.
- 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: restartedHandlere kjører på slutten av playet, etter oppgavene som varslet dem, så en oppgave senere i samme play kan fortsatt se det gamle grensesnittet. Hvis rekkefølgen er viktig, tøm handlerne eksplisitt med meta: flush_handlers før oppgaven som avhenger av den nye konfigurasjonen.
Bruk restart i stedet for reload, med mindre du har verifisert enhetens omlastingshandling. Upstream wg-quick-enheten støtter en, og den synkroniserer WireGuard-konfigurasjonen, men den kjører ikke oppsett av adresser, ruter, DNS eller hooks på nytt. En reload etter å ha lagt til et rutedirektiv ser derfor ut til å lykkes og endrer ingenting.
Sammenlign den levende enheten med filen
Kontrollen som lukker denne feilklassen, er en sammenligning mellom det kjernen har, og det filen sier. To kommandoer gir sammenlignbare utdata, og forskjellen er avviket.
sudo wg showconf wg0
sudo wg-quick strip wg0
sudo diff <(sudo wg showconf wg0) <(sudo wg-quick strip wg0)wg showconf skriver ut den levende enheten, inkludert den private nøkkelen, så behandle utdataene som en hemmelighet og ikke lim dem inn i en sak. wg-quick strip skriver ut filen uten nøklene som er spesifikke for wg-quick, og derfor er de to sammenlignbare i det hele tatt.
En forskjell i peer-listen betyr at filen aldri ble brukt. En forskjell begrenset til nøkler eller endepunkter du forventet skulle endre seg, betyr at noe brukte den delvis. Ingen forskjell betyr at konfigurasjonen er oppdatert og feilen ligger et annet sted, noe som i seg selv er et nyttig resultat.
Betal prisen for omstarten med vilje
Omstart av grensesnittet river ned tunnelen, og hvis den tunnelen bærer den administrative økten din, avslutter omstarten økten som ba om den. Sett handleren bak et endringsvindu, eller kjør playbooken fra en administrasjonsvei som ikke avhenger av at grensesnittet startes på nytt.
Prisen er grunnen til at folk griper etter reload. Det er en rimelig instinkt, og den blir riktig når du vet hvilke endringer en reload faktisk bruker. For peer- og nøkkelendringer på upstream wg-quick-enheten er det nok; for adressering, ruting og hooks er det ikke. Å avklare det én gang er billigere enn å oppdage det i et endringsvindu.
Dokumentasjonen for systemd_service-modulen forklarer forskjellen mellom started, restarted og reloaded, og den er verdt å lese én gang i stedet for å gjette fra et grønt sammendrag. Alt i denne gjennomgangen følger av den ene forskjellen.