Ansible di que se iniciou, pero WireGuard segue coa configuración antiga
state: started deixa intacta unha unidade que xa funciona, así que un wg0.conf reescrito nunca se aplica. Engade un handler de cambio e despois compara o dispositivo vivo co ficheiro.
A execución do playbook remata en verde, a unidade de WireGuard está activa, o handshake funciona e o novo peer segue sen chegar a nada. Ver un playbook informar de éxito mentres o servidor corre a configuración de onte é especialmente frustrante, porque nada da saída está mal. Ansible fixo exactamente o que se lle pediu: asegurou que a unidade estivese iniciada, e xa o estaba. Aplicar un ficheiro de configuración reescrito é outra tarefa, e só ocorre se algo lle di ao servizo que o volva ler.
Mira que informa realmente unha segunda execución
Executa o playbook dúas veces coa configuración cambiada no seu sitio e compara o resumo. A segunda execución debería mostrar a tarefa da unidade como ok, non como changed, porque un servizo que xa funciona déixase tranquilo por deseño. Iso é a idempotencia funcionando ben, e tamén a razón pola que o ficheiro novo nunca chega ao kernel.
Engade unha execución de comprobación con saída diff para ver que tarefas tocarían algo.
ansible-playbook -i inventory site.yml --check --diff
systemctl show wg-quick@wg0 -p ActiveEnterTimestamp -p NRestarts
stat -c '%y %n' /etc/wireguard/wg0.confAs tres marcas de tempo contan a historia antes de ler unha soa liña de rexistro. Se o ficheiro de configuración é máis novo que o momento en que a unidade se activou, a interface en execución construíuse cun ficheiro anterior, e cada síntoma posterior deriva diso.
Non é un defecto de Ansible. O mesmo comportamento aparece con calquera ferramenta de xestión de configuración que separa «asegúrate de que funciona» de «asegúrate de que funciona con isto». A distinción parece pedante ata que che custa unha tarde.
Iniciado é un estado, non unha recarga
state: started afirma unha condición sobre a unidade. Non promete que o servizo volva ler as súas entradas, e non pode saber que un ficheiro que nunca abriu cambiou. Nun despregamento wg-quick as entradas inclúen a configuración da interface, os enderezos, as rutas, as entradas DNS e calquera hook post-up.
Por iso un ficheiro actualizado pode conter un peer novo, outro enderezo ou unha directiva de encamiñamento cambiada mentres a interface viva segue servindo o conxunto antigo. O handshake aínda ten éxito porque as claves e os extremos cargados seguen sendo válidos. Iso é xusto o que fai difícil ver o fallo, e por que a xente persegue o DNS durante unha hora antes de comprobar unha marca de tempo.
Outras dúas opcións do módulo confúndense a miúdo cunha solución. daemon_reload fai que systemd volva ler os ficheiros de unidade, algo irrelevante para un ficheiro de configuración de WireGuard. state: reloaded pide á unidade que execute a súa acción de recarga, e se iso fai o que necesitas depende por completo da unidade. Ningunha substitúe a saber que entradas leu realmente o proceso en execución.
Instala o ficheiro e despois notifica un handler
O patrón que mantén a idempotencia e aplica os cambios é o habitual: a tarefa que escribe o ficheiro notifica un handler, e o handler só se executa cando o ficheiro cambiou de verdade. Unha segunda execución sen edicións non fai nada, e iso é o que queres.
- 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: restartedOs handlers execútanse ao final da obra, despois das tarefas que os notificaron, así que unha tarefa posterior da mesma obra aínda pode ver a interface antiga. Se a orde importa, baleira os handlers explicitamente con meta: flush_handlers antes da tarefa que depende da configuración nova.
Usa restart en lugar de reload salvo que verificases a acción de recarga da unidade. A unidade wg-quick de orixe si admite unha, e sincroniza a configuración de WireGuard, pero non volve executar a configuración de enderezos, rutas, DNS nin hooks. Por iso un reload tras engadir unha directiva de ruta parece ter éxito e non cambia nada.
Compara o dispositivo vivo co ficheiro
A comprobación que pecha esta clase de fallos é unha comparación entre o que ten o kernel e o que di o ficheiro. Dous comandos producen unha saída comparable, e a diferenza é a desviación.
sudo wg showconf wg0
sudo wg-quick strip wg0
sudo diff <(sudo wg showconf wg0) <(sudo wg-quick strip wg0)wg showconf imprime o dispositivo vivo, incluída a clave privada, así que trata esa saída como un segredo e non a pegues nun ticket. wg-quick strip imprime o ficheiro sen as claves exclusivas de wg-quick, e por iso as dúas saídas son comparables.
Unha diferenza na lista de peers significa que o ficheiro nunca se aplicou. Unha diferenza limitada a claves ou extremos que esperabas cambiar significa que algo o aplicou en parte. Ningunha diferenza significa que a configuración está ao día e o fallo está noutro sitio, o que xa é un resultado útil.
Paga o custo do reinicio a propósito
Reiniciar a interface tira o túnel, e se ese túnel leva a túa sesión administrativa, o reinicio remata a sesión que o pediu. Pon o handler detrás dunha ventá de cambio, ou executa o playbook desde unha ruta de xestión que non dependa de reiniciar a interface.
O custo é a razón pola que a xente recorre ao reload. É un instinto razoable, e vólvese correcto cando sabes que cambios aplica de verdade un reload. Para cambios de peer e de claves na unidade wg-quick de orixe abonda; para enderezo, encamiñamento e hooks non. Aclaralo unha vez sae máis barato que descubrilo durante unha ventá de cambio.
A documentación do módulo systemd_service explica a diferenza entre started, restarted e reloaded, e merece unha lectura en lugar de deducila dun resumo verde. Todo neste percorrido sae desa única distinción.