- Jinja 76.1%
- Dockerfile 23.9%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| inventory | ||
| media | ||
| roles | ||
| ansible.cfg | ||
| Dockerfile | ||
| README.md | ||
| renovate.json | ||
| sample-vpn-inventory.yaml | ||
| vpn-inventory.yaml | ||
| wireguard.yaml | ||
VPN and Tunnel Creation
This tool creates encrypted tunnels using Ansible, Wireguard, Azure Key Vault. The keys and configuratons stored in Azure Key Vault will then be used by GitHub Actions when creating new ISO images for virtual and physical machines.
Quick Start: Create a New VPN
-
Add a new client block to the inventory file in the inventory directory
The new client's configuration should contain:
- A four-character
name - A two-character
country code - A
UUIDconsisting of thecountry code, 4-character abbreviated name, and a six-digit number - A
subnet addressthat is unique from any other client - The
IP addressfor the wireguard server - A
unique portnumber greater than 51800 - An
empty arrayof ips
Example:
clients: test: name: test country: de uuid: "de-test-000000" subnet: 10.2.0.0 vpnIp: "192.168.50.100" vpnPort: 51822 ips: [] - A four-character
-
Build the docker container
docker build --platform linux/amd64 -t ansible-runner . -f Dockerfile
Running Locally
cat ./inventory/inventory.yaml | yq '.clients.buildstars' > demo.yaml
echo "$(bw get item cloudymax-ssh-key |jq '.fields[1].value')" > .priavte_key
echo "$(bw get password ansible-vault-pw)" > .vault_pass
export AZURE_RESOURCE_GROUP="cloudydev-docs"
export VPN_CONFIG="demo.yaml"
export VAULT_NAME=$(az keyvault list --resource-group $AZURE_RESOURCE_GROUP --query "[*].name" --output tsv)
export AZURE_CLIENT_ID=$(bw get item admin-robot |jq -r '.fields[] |select(.name=="clientId") |.value')
export AZURE_CLIENT_SECRET=$(bw get item admin-robot |jq -r '.fields[] |select(.name=="clientSecret") |.value')
export AZURE_SUBSCRIPTION_ID=$(bw get item admin-robot |jq -r '.fields[] |select(.name=="subscriptionId") |.value')
export AZURE_TENANT_ID=$(bw get item admin-robot |jq -r '.fields[] |select(.name=="tenantId") |.value')
docker run --platform linux/amd64 -v $(pwd):/ansible \
-w /ansible ansible-runner \
ansible-playbook wireguard.yaml \
-i vpn-inventory.yaml \
-e "ansible_ssh_private_key_file=.private_key" \
-e "AZURE_CLIENT_ID=${AZURE_CLIENT_ID}" \
-e "AZURE_SECRET=${AZURE_CLIENT_SECRET}" \
-e "AZURE_SUBSCRIPTION_ID=${AZURE_SUBSCRIPTION_ID}" \
-e "AZURE_TENANT=${AZURE_TENANT_ID}" \
-e "KEY_VAULT_URI=https://$VAULT_NAME.vault.azure.net/" \
-e "ip_file=$VPN_CONFIG" \
-e "function=server-install"
export YAML_DATA=$(cat demo.yaml)
yq '.clients.buildstars = env(YAML_DATA)' ../inventory/inventory.yaml
How it works:
Creating a VPN:
- Ansible decrypts the
vpn-inventory.yamlusing theANSIBLE_VAULT_PASSWORDrepo secret - Ansible connects to the
serverdefined invpn-inventory.yamland runs thewireguard.yamlplaybook - If the environment variable
functionis set toserver-installansible will run thewg-server-install.yamltask. - Ansible will read the inventory file, and adds new internal IP address for the VPN server based on the
subnetfield. - The task generates the server's public and private wireguard keys and a wireguard config file by populating the
server_wg0.conf.j2template. - Ansible then stores the base64 encoded secrets and config in the Azure Key Vault defined by the
KEY_VAULT_URIenvironement variable - Ansible creates a systemd service for the new wireguard configuration that will start the VPN automatically after reboots
- Ansible starts the systemd service which initializes the VPN
Adding new client/peer credentials to a given VPN Server:
- Ansible decrypts the
vpn-inventory.yamlusing theANSIBLE_VAULT_PASSWORDrepo secret - Ansible connects to the
serverdefined invpn-inventory.yamland runs thewireguard.yamlplaybook - If the environment variable
functionis set tocredentialsansible will run thewg-client-creds.yamltask. - Ansible will read the inventory file, and adds a new internal IP address for the VPN client by incrementing the last octet of the last IP addess in the ips array
ips[-1] - Ansible connects to the Azure Key Vault defined by the
KEY_VAULT_URIenvironement and retreives the server's public key. - The task then generates the new client's public/private wireguard keys and a wireguard config file by populating the
client_wg0.conf.j2template. - Ansbile then stores the base64 encoded secrets and config in the Azure Key Vault
- Next Ansible connects to the
serverand writes the client's connection data to the server's wreguard config - Lastly, the wireguard service on the server is restarted with the updated config.
Tools Selections
-
Wireguard is an extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography. It aims to be faster, simpler, leaner, and more useful than IPsec, while avoiding the massive headache. It intends to be considerably more performant than OpenVPN.
-
Ansible is a general-purpose configuration-management framework built with python, yaml, and jinja2. Ansible is maintained by Red-Hat & IBM.
-
Azure Key Vault is an encrypted Secrets, Certificate, and Key vault that is part of the Azure Cloud platform. It's not completely free or open-source, but it des have a very generous free tier of usage before pricing kicks in which shouldnt be an issue until managing thousands of secrets.
This playbook and associated role will install and create/update wirguard confiurations for a server and clients. Multiple wireguard networks can be managed on the same server.
Helpful wireguard resources:
- The complete guide to setting up a multi-peer WireGuard VPN
- Wireguard.how: Network Speed Testing
- Exploring Ansible via Setting Up a WireGuard VPN
- acavella/ansible-role-wireguard



