Skip to content

Commit

Permalink
Netplan support (#210)
Browse files Browse the repository at this point in the history
* netplan: add tasks for managing netplan

* netplan: add handlers for managing netplan

* netplan: add default variables

* netplan: add template

* netplan: proper var name, more conditions, linting

* netplan: rename netplan template file

* netplan: simplify logic

* netplan: update docs

* netplan: molecule tests

* netplan: avoid syncconf check if using netplan

* netplan: implement changes from commit fa7b0db

* netplan: final changes
  • Loading branch information
kbcz1989 authored Nov 6, 2024
1 parent fa7b0db commit 955e64b
Show file tree
Hide file tree
Showing 10 changed files with 337 additions and 10 deletions.
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,14 @@ These variables can be changed in `group_vars/` e.g.:

```yaml
# Directory to store WireGuard configuration on the remote hosts
wireguard_remote_directory: "/etc/wireguard" # On Linux
# wireguard_remote_directory: "/opt/local/etc/wireguard" # On MacOS
wireguard_remote_directory: >-
{%- if wireguard_ubuntu_use_netplan -%}
/etc/netplan
{%- elif ansible_os_family == 'Darwin' -%}
/opt/local/etc/wireguard
{%- else -%}
/etc/wireguard
{%- endif %}
# The default port WireGuard will listen if not specified otherwise.
wireguard_port: "51820"
Expand Down Expand Up @@ -197,6 +203,9 @@ wireguard_service_state: "started"
# If you have a more dynamic routing setup then setting this to "true" might be
# the safest way to go. Also if you want to avoid the possibility creating some
# hard to detect side effects this option should be considered.
# If using netplan to configure WireGuard interfaces this option should be set
# to "true" if netplan configuration should be applied, otherwise it will
# just be generated.
wireguard_interface_restart: false
# Normally the role automatically creates a private key the very first time
Expand Down Expand Up @@ -233,6 +242,9 @@ wireguard_ubuntu_update_cache: "{{ wireguard_update_cache }}"
# Set package cache valid time
wireguard_ubuntu_cache_valid_time: "3600"
# Set to "true" if netplan should be used to configure WireGuard interfaces
wireguard_ubuntu_use_netplan: false
#######################################
# Settings only relevant for CentOS 7
#######################################
Expand Down
18 changes: 17 additions & 1 deletion defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@
#######################################

# Directory to store WireGuard configuration on the remote hosts
wireguard_remote_directory: "{{ '/etc/wireguard' if not ansible_os_family == 'Darwin' else '/opt/local/etc/wireguard' }}"
wireguard_remote_directory: >-
{%- if wireguard_ubuntu_use_netplan -%}
/etc/netplan
{%- elif ansible_os_family == 'Darwin' -%}
/opt/local/etc/wireguard
{%- else -%}
/etc/wireguard
{%- endif %}
# The default port WireGuard will listen if not specified otherwise.
wireguard_port: "51820"
Expand All @@ -18,6 +25,12 @@ wireguard_interface: "wg0"
# The default owner of the wg.conf file
wireguard_conf_owner: root

# By default a WireGuard configuration file in "wireguard_remote_directory"
# directory will be created that is called like the value of "wireguard_interface"
# plus ".conf". If "wireguard_ubuntu_use_netplan" is set to "true" this should
# be changed to "70-{{ wireguard_interface }}.yaml" e.g.
wireguard_conf_filename: "{{ wireguard_interface }}.conf"

# The default group of the wg.conf file
wireguard_conf_group: "{{ 'root' if not ansible_os_family == 'Darwin' else 'wheel' }}"

Expand Down Expand Up @@ -93,6 +106,9 @@ wireguard_ubuntu_update_cache: "{{ wireguard_update_cache }}"
# Set package cache valid time
wireguard_ubuntu_cache_valid_time: "3600"

# Set to "true" if you want to use netplan to configure WireGuard.
wireguard_ubuntu_use_netplan: false

#######################################
# Settings only relevant for CentOS 7
#######################################
Expand Down
29 changes: 29 additions & 0 deletions handlers/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,32 @@
- not ansible_os_family == 'Darwin'
- wireguard_service_enabled == "yes"
listen: "reconfigure wireguard"

- name: Generating Netplan Configuration
ansible.builtin.command: netplan generate
listen: reconfigure netplan
notify: netplan apply config
changed_when: true
become: true
when:
- wireguard_ubuntu_use_netplan

- name: Applying Netplan Configuration
ansible.builtin.command: netplan apply
listen: netplan apply config
notify: restart systemd-networkd
changed_when: true
become: true
when:
- wireguard_ubuntu_use_netplan
- wireguard_interface_restart

- name: Restart systemd-networkd
ansible.builtin.systemd:
name: systemd-networkd
state: restarted
listen: restart systemd-networkd
become: true
when:
- wireguard_ubuntu_use_netplan
- wireguard_interface_restart
13 changes: 13 additions & 0 deletions molecule/netplan/converge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
# Copyright (C) 2020-2023 Robert Wimmer
# SPDX-License-Identifier: GPL-3.0-or-later

- name: Setup WireGuard
hosts: all
remote_user: vagrant
become: true
gather_facts: true
tasks:
- name: Include WireGuard role
ansible.builtin.include_role:
name: githubixx.ansible_role_wireguard
90 changes: 90 additions & 0 deletions molecule/netplan/molecule.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
---
# Copyright (C) 2020-2023 Robert Wimmer
# Copyright (C) 2020 Pierre Ozoux
# SPDX-License-Identifier: GPL-3.0-or-later

dependency:
name: galaxy

driver:
name: vagrant
provider:
name: libvirt
type: libvirt

platforms:
- name: test-wg-ubuntu2004
box: alvistack/ubuntu-20.04
memory: 1536
cpus: 2
interfaces:
- auto_config: true
network_name: private_network
type: static
ip: 172.16.10.10
groups:
- vpn
- ubuntu
- name: test-wg-ubuntu2204
box: alvistack/ubuntu-22.04
memory: 1536
cpus: 2
interfaces:
- auto_config: true
network_name: private_network
type: static
ip: 172.16.10.20
groups:
- vpn
- ubuntu
- name: test-wg-ubuntu2404
box: alvistack/ubuntu-24.04
memory: 1536
cpus: 2
interfaces:
- auto_config: true
network_name: private_network
type: static
ip: 172.16.10.30
groups:
- vpn
- ubuntu

provisioner:
name: ansible
connection_options:
ansible_ssh_user: vagrant
ansible_become: true
log: true
lint:
name: ansible-lint
inventory:
host_vars:
test-wg-ubuntu2004:
wireguard_address: "10.10.10.10/24"
wireguard_port: 51820
wireguard_persistent_keepalive: "30"
wireguard_endpoint: "172.16.10.10"
test-wg-ubuntu2204:
wireguard_address: "10.10.10.20/24"
wireguard_port: 51820
wireguard_persistent_keepalive: "30"
wireguard_endpoint: "172.16.10.20"
wireguard_conf_backup: true
test-wg-ubuntu2404:
wireguard_address: "10.10.10.30/24"
wireguard_port: 51820
wireguard_persistent_keepalive: "30"
wireguard_endpoint: "172.16.10.30"
wireguard_ubuntu_use_netplan: true
wireguard_conf_filename: "70-wg0.yaml"
wireguard_interface_restart: true

scenario:
name: netplan
test_sequence:
- prepare
- converge

verifier:
name: ansible
14 changes: 14 additions & 0 deletions molecule/netplan/prepare.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
# Copyright (C) 2024 Robert Wimmer
# SPDX-License-Identifier: GPL-3.0-or-later

- name: Prepare Ubuntu hosts
hosts: ubuntu
remote_user: vagrant
become: true
gather_facts: true
tasks:
- name: Update APT package cache
ansible.builtin.apt:
update_cache: true
cache_valid_time: 3600
33 changes: 33 additions & 0 deletions molecule/netplan/verify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
# Copyright (C) 2023 Robert Wimmer
# SPDX-License-Identifier: GPL-3.0-or-later

- name: Verify setup
hosts: all
vars:
hosts_count: "{{ groups['vpn'] | length }}"
tasks:
- name: Count WireGuard interfaces
ansible.builtin.shell: |
set -o errexit
set -o pipefail
set -o nounset
wg | grep "peer: " | wc -l
exit 0
args:
executable: "/bin/bash"
register: wireguard__interfaces_count
changed_when: false

- name: Print WireGuard interface count
ansible.builtin.debug:
var: wireguard__interfaces_count.stdout

- name: Print hosts count in vpn group
ansible.builtin.debug:
var: hosts_count

- name: There should be as much WireGuard interfaces as hosts in vpn group minus one
ansible.builtin.assert:
that:
- "hosts_count|int -1 == wireguard__interfaces_count.stdout|int"
23 changes: 16 additions & 7 deletions tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
- name: Make sure wg syncconf option is available
when:
- not wireguard_interface_restart
- not wireguard_ubuntu_use_netplan
tags:
- wg-config
block:
Expand Down Expand Up @@ -87,7 +88,7 @@

- name: Register if config/private key already exists on target host
ansible.builtin.stat:
path: "{{ wireguard_remote_directory }}/{{ wireguard_interface }}.conf"
path: "{{ wireguard_remote_directory }}/{{ wireguard_conf_filename }}"
register: wireguard__register_config_file
tags:
- wg-generate-keys
Expand All @@ -103,6 +104,7 @@
register: wireguard__register_private_key
changed_when: false
no_log: '{{ ansible_verbosity < 3 }}'
check_mode: false
tags:
- wg-generate-keys

Expand All @@ -120,15 +122,19 @@
block:
- name: Read WireGuard config file
ansible.builtin.slurp:
src: "{{ wireguard_remote_directory }}/{{ wireguard_interface }}.conf"
src: "{{ wireguard_remote_directory }}/{{ wireguard_conf_filename }}"
register: wireguard__register_config
no_log: '{{ ansible_verbosity < 3 }}'
tags:
- wg-config

- name: Set private key fact
ansible.builtin.set_fact:
wireguard_private_key: "{{ wireguard__register_config['content'] | b64decode | regex_findall('PrivateKey = (.*)') | first }}"
wireguard_private_key: >-
{{ wireguard__register_config['content'] | b64decode |
regex_findall(wireguard_ubuntu_use_netplan |
ternary('key:\s*(.*)$', 'PrivateKey\s*=\s*(.*)$'), multiline=True) |
first }}
no_log: '{{ ansible_verbosity < 3 }}'
tags:
- wg-config
Expand Down Expand Up @@ -157,11 +163,12 @@
mode: 0700
tags:
- wg-config
when: not wireguard_ubuntu_use_netplan

- name: Generate WireGuard configuration file
ansible.builtin.template:
src: etc/wireguard/wg.conf.j2
dest: "{{ wireguard_remote_directory }}/{{ wireguard_interface }}.conf"
src: "etc/{{ 'wireguard/wg.conf.j2' if not wireguard_ubuntu_use_netplan else 'netplan/wg.yaml.j2' }}"
dest: "{{ wireguard_remote_directory }}/{{ wireguard_conf_filename }}"
owner: "{{ wireguard_conf_owner }}"
group: "{{ wireguard_conf_group }}"
mode: "{{ wireguard_conf_mode }}"
Expand All @@ -170,7 +177,7 @@
tags:
- wg-config
notify:
- reconfigure wireguard
- "reconfigure {{ 'wireguard' if not wireguard_ubuntu_use_netplan else 'netplan' }}"

- name: Ensure legacy reload-module-on-update is absent
ansible.builtin.file:
Expand All @@ -184,4 +191,6 @@
name: "wg-quick@{{ wireguard_interface }}"
state: "{{ wireguard_service_state }}"
enabled: "{{ wireguard_service_enabled }}"
when: not ansible_os_family == 'Darwin'
when:
- not ansible_os_family == 'Darwin'
- not wireguard_ubuntu_use_netplan
9 changes: 9 additions & 0 deletions tasks/setup-ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@
# Copyright (C) 2018-2023 Robert Wimmer
# SPDX-License-Identifier: GPL-3.0-or-later

- name: Check if Netplan is supported
ansible.builtin.assert:
that:
- ansible_distribution == "Ubuntu"
- ansible_distribution_version is version('17.10', '>=')
fail_msg: "Netplan is only supported on Ubuntu 17.10 and later versions"
success_msg: "Netplan is supported on this system"
when: wireguard_ubuntu_use_netplan

- name: (Ubuntu) Update APT package cache
ansible.builtin.apt:
update_cache: "{{ wireguard_ubuntu_update_cache }}"
Expand Down
Loading

0 comments on commit 955e64b

Please sign in to comment.