From 4e04c508db697e97ff2fdf02349a20aba492b780 Mon Sep 17 00:00:00 2001 From: transcaffeine Date: Fri, 9 Jan 2026 23:22:46 +0100 Subject: [PATCH] feat(wg_quick): add ansible role and playbook --- playbooks/wg_quick.yml | 7 +++++ roles/wg_quick/defaults/main/connection.yml | 20 ++++++++++++++ roles/wg_quick/defaults/main/main.yml | 7 +++++ roles/wg_quick/tasks/configure-interface.yml | 19 +++++++++++++ roles/wg_quick/tasks/main.yml | 20 ++++++++++++++ roles/wg_quick/templates/wg-quick.conf.j2 | 29 ++++++++++++++++++++ 6 files changed, 102 insertions(+) create mode 100644 playbooks/wg_quick.yml create mode 100644 roles/wg_quick/defaults/main/connection.yml create mode 100644 roles/wg_quick/defaults/main/main.yml create mode 100644 roles/wg_quick/tasks/configure-interface.yml create mode 100644 roles/wg_quick/tasks/main.yml create mode 100644 roles/wg_quick/templates/wg-quick.conf.j2 diff --git a/playbooks/wg_quick.yml b/playbooks/wg_quick.yml new file mode 100644 index 0000000..1c872a6 --- /dev/null +++ b/playbooks/wg_quick.yml @@ -0,0 +1,7 @@ +--- +- name: Configure wireguard interfaces with wg_quick + hosts: "{{ wg_quick_hosts | default(wg_quick) }}" + become: "{{ wg_quick_become | default(false) }}" + gather_facts: "{{ wg_quick_gather_facts | default(false) }}" + roles: + - role: finallycoffee.base.wg_quick diff --git a/roles/wg_quick/defaults/main/connection.yml b/roles/wg_quick/defaults/main/connection.yml new file mode 100644 index 0000000..0c0fcc1 --- /dev/null +++ b/roles/wg_quick/defaults/main/connection.yml @@ -0,0 +1,20 @@ +--- +wg_quick_interface_name: ~ +wg_quick_interface_address: ~ +wg_quick_interface_listen_port: ~ +wg_quick_interface_private_key: ~ +wg_quick_interface_private_key_file: ~ +wg_quick_interface_peer_endpoint: ~ +wg_quick_interface_peer_public_key: ~ +wg_quick_interface_peer_allowed_ips: ~ + +wg_quick_interfaces: + - name: "{{ wg_quck_interface_name }}" + address: "{{ wg_quick_interface_address }}" + listen_port: "{{ wg_quick_interface_listen_port }}" + private_key: "{{ wg_quick_interface_private_key }}" + private_key_file: "{{ wg_quick_interface_private_key_file }}" + peers: + - endpoint: "{{ wg_quick_interface_peer_endpoint }}" + public_key: "{{ wg_quick_interface_peer_public_key }}" + allowed_ips: "{{ wg_quick_interface_peer_allowed_ips }}" diff --git a/roles/wg_quick/defaults/main/main.yml b/roles/wg_quick/defaults/main/main.yml new file mode 100644 index 0000000..111d659 --- /dev/null +++ b/roles/wg_quick/defaults/main/main.yml @@ -0,0 +1,7 @@ +--- +wg_quick_state: "present" +wg_quick_package_name: "wireguard-tools" +wg_quick_system_packages: + - "{{ wg_quick_package_name }}" + +wg_quick_configuration_dir: "/etc/wireguard" diff --git a/roles/wg_quick/tasks/configure-interface.yml b/roles/wg_quick/tasks/configure-interface.yml new file mode 100644 index 0000000..6092188 --- /dev/null +++ b/roles/wg_quick/tasks/configure-interface.yml @@ -0,0 +1,19 @@ +--- +- name: Ensure wg-quick configuration for interface '{{ wg_quick_iface.name }}' is up to date + ansible.builtin.template: + src: "wg-quick.conf.j2" + dest: "{{ wg_quick_configuration_dir }}/{{ wg_quick_iface.name }}.conf" + when: wg_quick_iface.state | default(wg_quick_state) == 'present' + +- name: Ensure systemd service is enabled + ansible.builtin.systemd_service: + name: "wg-quick@{{ wg_quick_iface.name }}.service" + enabled: true + when: wg_quick_iface.state | default(wg_quick_state) == 'present' + +- name: Ensure systemd service is {{ wg_quick_iface.state | default(wg_quick_state) }} + ansible.builtin.systemd_service: + name: "wg-quick@{{ wg_quick_iface.name }}.service" + state: >-2 + {{ (wg_quick_iface.state | default(wg_quick_state) == 'present') + | ternary('started', 'absent') }} diff --git a/roles/wg_quick/tasks/main.yml b/roles/wg_quick/tasks/main.yml new file mode 100644 index 0000000..51faad8 --- /dev/null +++ b/roles/wg_quick/tasks/main.yml @@ -0,0 +1,20 @@ +--- +- name: Ensure system packages are available + ansible.builtin.package: + name: "{{ wg_quick_system_packages }}" + state: "present" + when: wg_quick_state == 'present' + +- name: Ensure configuration folder is present + ansible.builtin.file: + name: "{{ wg_quick_configuration_dir }}" + state: "directory" + when: wg_quick_state == 'present' + +- name: Ensure connections are in the configured state + ansible.builtin.include_tasks: + file: "configure-interface.yml" + loop: "{{ wg_quick_interfaces }}" + loop_control: + loop_var: "wg_quick_iface" + label: "{{ wg_quick_iface.name }}" diff --git a/roles/wg_quick/templates/wg-quick.conf.j2 b/roles/wg_quick/templates/wg-quick.conf.j2 new file mode 100644 index 0000000..ef3dd85 --- /dev/null +++ b/roles/wg_quick/templates/wg-quick.conf.j2 @@ -0,0 +1,29 @@ +[Interface] +Address = {{ wg_quick_iface.address | join(', ') }} +ListenPort = {{ wg_quick_iface.listen_port }} + +{% if wg_quick_iface.private_key %} +PrivateKey = {{ wg_quick_iface.private_key }} +{% elif wg_quick_iface.private_key_file %} +PrivateKeyFile = {{ wg_quick_iface.private_key_file }} +{% endif %} +{% if wg_quick_iface.table is defined %} +Table = {{ wg_quick_iface.table | ternary('On', 'Off') }} +{% endif %} +{% if wg_quick_iface.post_up %} +PostUp = /bin/bash -c "{{ wg_quick_iface.post_up | join('; ') }}" +{% endif %} +{% if wg_quick_iface.pre_down %} +PreDown = /bin/bash -c "{{ wg_quick_iface.pre_down | join('; ') }}" +{% endif %} + + +{% for _peer in wg_quick_iface.peers %} +[Peer] +Endpoint = {{ _peer.endpoint }} +PublicKey = {{ _peer.public_key }} +AllowedIPs = {{ _peer.allowed_ips | join(', ') }} +{% if _peer.persistent_keepalive %} +PersistentKeepalive = {{ _peer.persistent_keepalive }} +{% endif %} +{% endfor %}