--- - name: Provision WireGuard VPN for new client hosts: vpn_servers become: yes vars: client_dir: /etc/wireguard/clients wg_interface: wg0 server_dir: /etc/wireguard server_ip: 10.8.0.1/24 server_port: 51820 server_endpoint: "{{ ansible_host | default(inventory_hostname) }}" tasks: - name: Debug invoice ID debug: msg: "Processing invoice ID: {{ invoice_id }}" # Server Setup Tasks - name: Check if server keys exist stat: path: "{{ server_dir }}/{{ wg_interface }}.conf" register: server_config - name: Generate server private key if not exists shell: wg genkey register: server_private_key when: not server_config.stat.exists - name: Save server private key copy: content: "{{ server_private_key.stdout }}" dest: "{{ server_dir }}/private.key" mode: '0600' when: not server_config.stat.exists - name: Generate server public key shell: "cat {{ server_dir }}/private.key | wg pubkey" register: server_public_key when: not server_config.stat.exists - name: Save server public key copy: content: "{{ server_public_key.stdout }}" dest: "{{ server_dir }}/public.key" mode: '0644' when: not server_config.stat.exists - name: Update vault with server details block: - name: Read server public key shell: "cat {{ server_dir }}/public.key" register: pubkey_content changed_when: false - name: Save server details to vault copy: content: | wireguard_server_public_key: "{{ pubkey_content.stdout }}" wireguard_server_endpoint: "{{ ansible_host }}" dest: "{{ playbook_dir }}/../group_vars/vpn_servers/vault.yml" mode: '0600' when: not server_config.stat.exists - name: Create initial server config template: src: templates/server.conf.j2 dest: "{{ server_dir }}/{{ wg_interface }}.conf" mode: '0600' when: not server_config.stat.exists # Client Setup Tasks - name: Ensure client directory exists file: path: "{{ client_dir }}/{{ invoice_id }}" state: directory mode: '0700' - name: Generate client private key shell: wg genkey register: client_private_key no_log: true - name: Save client private key copy: content: "{{ client_private_key.stdout }}" dest: "{{ client_dir }}/{{ invoice_id }}/private.key" mode: '0600' no_log: true - name: Generate client public key shell: "echo '{{ client_private_key.stdout }}' | wg pubkey" register: client_public_key - name: Save client public key copy: content: "{{ client_public_key.stdout }}" dest: "{{ client_dir }}/{{ invoice_id }}/public.key" mode: '0644' - name: Read server public key shell: "cat {{ server_dir }}/public.key" register: server_public_key_read changed_when: false - name: Get next available IP shell: | last_ip=$(grep -h '^Address' {{ client_dir }}/*/wg0.conf 2>/dev/null | tail -n1 | grep -oE '[0-9]+$' || echo 1) echo $((last_ip + 1)) register: next_ip - name: Generate client config template: src: templates/client.conf.j2 dest: "{{ client_dir }}/{{ invoice_id }}/wg0.conf" mode: '0600' vars: client_ip: "10.8.0.{{ next_ip.stdout }}" server_pubkey: "{{ server_public_key_read.stdout }}" - name: Add client to server config blockinfile: path: "{{ server_dir }}/{{ wg_interface }}.conf" marker: "# {mark} ANSIBLE MANAGED BLOCK FOR {{ invoice_id }}" block: | [Peer] PublicKey = {{ client_public_key.stdout }} AllowedIPs = 10.8.0.{{ next_ip.stdout }}/32 notify: restart wireguard handlers: - name: restart wireguard service: name: wg-quick@{{ wg_interface }} state: restarted