Fabiola  Auma

Fabiola Auma

1667684220

Ansible Role Wireguard: Ansible Role for installing WireGuard VPN

ansible-role-wireguard

This Ansible role is used in my blog series Kubernetes the not so hard way with Ansible but can be used standalone of course. The latest release is available via Ansible Galaxy. I use WireGuard and this Ansible role to setup a fully meshed VPN between all nodes of my little Kubernetes cluster.

In general WireGuard is a network tunnel (VPN) for IPv4 and IPv6 that uses UDP. If you need more information about WireGuard you can find a good introduction here: Installing WireGuard, the Modern VPN.

Linux

This role should work with:

  • Ubuntu 18.04 (Bionic Beaver)
  • Ubuntu 20.04 (Focal Fossa)
  • Ubuntu 22.04 (Jammy Jellyfish)
  • Archlinux
  • Debian 10 (Buster)
  • Debian 11 (Bullseye)
  • Fedora 34 (or later)
  • CentOS 7
  • AlmaLinux
  • Rocky Linux
  • openSUSE Leap 15.3

Molecule tests are available (see further down below). It should also work with Raspbian Buster but for this one there is no test available. MacOS (see below) should also work partitially but is only best effort.

MacOS

While this playbook configures, enables and starts a systemd service on Linux in a such a way that no additional action is needed, on MacOS it installs the required packages and it just generates the correct wg0.conf file that is then placed in the specified wireguard_remote_directory (/opt/local/etc/wireguard by default). In order to run the VPN, then, you need to:

sudo wg-quick up wg0

and to deactivate it

sudo wg-quick down wg0

or you can install the official app and import the wg0.conf file.

Versions

I tag every release and try to stay with semantic versioning. If you want to use the role I recommend to checkout the latest tag. The master branch is basically development while the tags mark stable releases. But in general I try to keep master in good shape too.

Requirements

By default port 51820 (protocol UDP) should be accessible from the outside. But you can adjust the port by changing the variable wireguard_port. Also IP forwarding needs to be enabled e.g. via echo 1 > /proc/sys/net/ipv4/ip_forward. I decided not to implement this task in this Ansible role. IMHO that should be handled elsewhere. You can use my ansible-role-harden-linux e.g. Besides changing sysctl entries (which you need to enable IP forwarding) it also manages firewall settings among other things. Nevertheless the PreUp, PreDown, PostUp and PostDown hooks may be a good place to do some network related stuff before a WireGuard interface comes up or goes down.

Changelog

see CHANGELOG.md

Role Variables

These variables can be changed in group_vars/ e.g.:

# 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

# The default port WireGuard will listen if not specified otherwise.
wireguard_port: "51820"

# The default interface name that WireGuard should use if not specified otherwise.
wireguard_interface: "wg0"

# The default owner of the wg.conf file
wireguard_conf_owner: root

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

# The default mode of the wg.conf file
wireguard_conf_mode: 0600

# The default state of the wireguard service
wireguard_service_enabled: "yes"
wireguard_service_state: "started"

# By default "wg syncconf" is used to apply WireGuard interface settings if
# they've changed. Older WireGuard tools doesn't provide this option. In that
# case as a fallback the WireGuard interface will be restarted. This causes a
# short interruption of network connections.
#
# So even if "false" is the default, the role figures out if the "syncconf"
# option of the "wg" utility is available and if not falls back to "true"
# (which means interface will be restarted as this is the only possible option
# in this case).
#
# Possible options:
# - false (default)
# - true
#
# Both options have their pros and cons. The default "false" option (do not
# restart interface)
# - does not need to restart the WireGuard interface to apply changes
# - does not cause a short VPN connection interruption when changes are applied
# - might cause network routes are not properly reloaded
#
# Setting the option value to "true" will
# - restart the WireGuard interface as the name suggests in case of changes
# - cause a short VPN connection interruption when changes are applied
# - make sure that network routes are properly reloaded
#
# So it depends a little bit on your setup which option works best. If you
# don't have an overly complicated routing that changes very often or at all
# using "false" here is most properly good enough for you. E.g. if you just
# want to connect a few servers via VPN and it normally stays this way.
#
# 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.
wireguard_interface_restart: false

# Normally the role automatically creates a private key the very first time
# if there isn't already a WireGuard configuration. But this option allows
# to provide your own WireGuard private key if really needed. As this is of
# course a very sensitive value you might consider a tool like Ansible Vault
# to store it encrypted.
# wireguard_private_key:

There are also a few Linux distribution specific settings:

#######################################
# Settings only relevant for Ubuntu
#######################################

# Set to "false" if package cache should not be updated
wireguard_ubuntu_update_cache: "true"

# Set package cache valid time
wireguard_ubuntu_cache_valid_time: "3600"

#######################################
# Settings only relevant for CentOS 7
#######################################

# Set wireguard_centos7_installation_method to "kernel-plus"
# to use the kernel-plus kernel, which includes a built-in,
# signed WireGuard module.
# UTILIZING KERNEL-PLUS WILL PERFORM A SYSTEM REBOOT DURING SETUP!!
#
# The default of "standard" will use the standard kernel and
# the ELRepo module for WireGuard.
wireguard_centos7_installation_method: "standard"

# The default seconds to wait for machine to reboot and respond
wireguard_centos7_kernel_plus_reboot_timeout: "600"

#########################################
# Settings only relevant for RockyLinux 8
#########################################

# Set wireguard_rockylinux8_installation_method to "dkms"
# to build WireGuard module from source, with wireguard-dkms.
# This is required if you use a custom kernel and/or your arch
# is not x86_64.
#
# The default of "standard" will install the kernel module
# with kmod-wireguard from ELRepo.
wireguard_rockylinux8_installation_method: "standard"

The following variable is mandatory and needs to be configured for every host in host_vars/ e.g.:

wireguard_address: "10.8.0.101/24"

Of course all IP's should be in the same subnet like /24 we see in the example above. If wireguard_allowed_ips is not set then the default value is the value from wireguard_address without the CIDR but instead with /32 which is basically a host route (have a look templates/wg.conf.j2). Let's see this example and let's assume you don't set wireguard_allowed_ips explicitly:

[Interface]
Address = 10.8.0.2/24
PrivateKey = ....
ListenPort = 51820

[Peer]
PublicKey = ....
AllowedIPs = 10.8.0.101/32
Endpoint = controller01.p.domain.tld:51820

This is part of the WireGuard config from my workstation. It has the VPN IP 10.8.0.2 and we've a /24 subnet in which all my WireGuard hosts are located. Also you can see we've a peer here that has the endpoint controller01.p.domain.tld:51820. When wireguard_allowed_ips is not explicitly set the Ansible template will add an AllowedIPs entry with the IP of that host plus /32. In WireGuard this basically specifies the routing. The config above says: On my workstation with the IP 10.8.0.2 I want send all traffic to 10.8.0.101/32 to the endpoint controller01.p.domain.tld:51820. Now let's assume we set wireguard_allowed_ips: "0.0.0.0/0". Then the resulting config looks like this.

[Interface]
Address = 10.8.0.2/24
PrivateKey = ....
ListenPort = 51820

[Peer]
PublicKey = ....
AllowedIPs = 0.0.0.0/0
Endpoint = controller01.p.domain.tld:51820

Now this is basically the same as above BUT now the config says: I want to route EVERY traffic originating from my workstation to the endpoint controller01.p.domain.tld:51820. If that endpoint can handle the traffic is of course another thing and it's up to you how you configure the endpoint routing ;-)

You can specify further optional settings (they don't have a default and won't be set if not specified besides wireguard_allowed_ips as already mentioned) also per host in host_vars/ (or in your Ansible hosts file if you like). The values for the following variables are just examples and no defaults (for more information and examples see wg-quick.8):

wireguard_allowed_ips: ""
wireguard_endpoint: "host1.domain.tld"
wireguard_persistent_keepalive: "30"
wireguard_dns: "1.1.1.1"
wireguard_fwmark: "1234"
wireguard_mtu: "1492"
wireguard_table: "5000"
wireguard_preup:
  - ...
wireguard_predown:
  - ...
wireguard_postup:
  - ...
wireguard_postdown:
  - ...
wireguard_save_config: "true"
wireguard_unmanaged_peers:
  client.example.com:
    public_key: 5zsSBeZZ8P9pQaaJvY9RbELQulcwC5VBXaZ93egzOlI=
    # preshared_key: ... e.g. from ansible-vault?
    allowed_ips: 10.0.0.3/32
    endpoint: client.example.com:51820
    persistent_keepalive: 0

wireguard_(preup|predown|postup|postdown) are specified as lists. Here are two examples:

wireguard_postup:
  - iptables -t nat -A POSTROUTING -o ens12 -j MASQUERADE
  - iptables -A FORWARD -i %i -j ACCEPT
  - iptables -A FORWARD -o %i -j ACCEPT
wireguard_preup:
  - echo 1 > /proc/sys/net/ipv4/ip_forward
  - ufw allow 51820/udp

The commands are executed in order as described in wg-quick.8.

wireguard_address is required as already mentioned. It's the IP of the interface name defined with wireguard_interface variable (wg0 by default). Every host needs a unique VPN IP of course. If you don't set wireguard_endpoint the playbook will use the hostname defined in the vpn hosts group (the Ansible inventory hostname). If you set wireguard_endpoint to "" (empty string) that peer won't have a endpoint. That means that this host can only access hosts that have a wireguard_endpoint. That's useful for clients that don't expose any services to the VPN and only want to access services on other hosts. So if you only define one host with wireguard_endpoint set and all other hosts have wireguard_endpoint set to "" (empty string) that basically means you've only clients besides one which in that case is the WireGuard server. The third possibility is to set wireguard_endpoint to some hostname. E.g. if you have different hostnames for the private and public DNS of that host and need different DNS entries for that case setting wireguard_endpoint becomes handy. Take for example the IP above: wireguard_address: "10.8.0.101". That's a private IP and I've created a DNS entry for that private IP like host01.i.domain.tld (i for internal in that case). For the public IP I've created a DNS entry like host01.p.domain.tld (p for public). The wireguard_endpoint needs to be a interface that the other members in the vpn group can connect to. So in that case I would set wireguard_endpoint to host01.p.domain.tld because WireGuard normally needs to be able to connect to the public IP of the other host(s).

Here is a litte example for what I use the playbook: I use WireGuard to setup a fully meshed VPN (every host can directly connect to every other host) and run my Kubernetes (K8s) cluster at Hetzner Cloud (but you should be able to use any hoster you want). So the important components like the K8s controller and worker nodes (which includes the pods) only communicate via encrypted WireGuard VPN. Also (as already mentioned) I've two clients. Both have kubectl installed and are able to talk to the internal Kubernetes API server by using WireGuard VPN. One of the two clients also exposes a WireGuard endpoint because the Postfix mailserver in the cloud and my internal Postfix needs to be able to talk to each other. I guess that's maybe a not so common use case for WireGuard :D But it shows what's possible. So let me explain the setup which might help you to use this Ansible role.

First, here is a part of my Ansible hosts file:

[vpn]
controller0[1:3].i.domain.tld
worker0[1:2].i.domain.tld
server.at.home.i.domain.tld
workstation.i.domain.tld

[k8s_controller]
controller0[1:3].i.domain.tld

[k8s_worker]
worker0[1:2].i.domain.tld

As you can see I've three groups here: vpn (all hosts on that will get WireGuard installed), k8s_controller (the Kubernetes controller nodes) and k8s_worker (the Kubernetes worker nodes). The i in the domainname is for internal. All the i.domain.tld DNS entries have a A record that points to the WireGuard IP that we define shortly for every host e.g.: controller01.i.domain.tld. IN A 10.8.0.101. The reason for that is that all Kubernetes components only binds and listen on the WireGuard interface in my setup. And since I need this internal IPs for all my Kubernetes components I specify the internal DNS entries in my Ansible hosts file. That way I can use the Ansible inventory hostnames and variables very easy in the playbooks and templates.

For the Kubernetes controller nodes I've defined the following host variables:

Ansible host file: host_vars/controller01.i.domain.tld

---
wireguard_address: "10.8.0.101/24"
wireguard_endpoint: "controller01.p.domain.tld"
ansible_host: "controller01.p.domain.tld"
ansible_python_interpreter: /usr/bin/python3

Ansible host file: host_vars/controller02.i.domain.tld:

---
wireguard_address: "10.8.0.102/24"
wireguard_endpoint: "controller02.p.domain.tld"
ansible_host: "controller02.p.domain.tld"
ansible_python_interpreter: /usr/bin/python3

Ansible host file: host_vars/controller03.i.domain.tld:

---
wireguard_address: "10.8.0.103/24"
wireguard_endpoint: "controller03.p.domain.tld"
ansible_host: "controller03.p.domain.tld"
ansible_python_interpreter: /usr/bin/python3

I've specified ansible_python_interpreter here for every node as the controller nodes use Ubuntu 18.04 which has Python 3 installed by default. ansible_host is set to the public DNS of that host. Ansible will use this hostname to connect to the host via SSH. I use the same value also for wireguard_endpoint because of the same reason. The WireGuard peers needs to connect to the other peers via a public IP (well at least via a IP that the WireGuard hosts can connect to - that could be of course also a internal IP if it works for you). The wireguard_address needs to be unique of course for every host.

For the Kubernetes worker I've defined the following variables:

Ansible host file: host_vars/worker01.i.domain.tld

---
wireguard_address: "10.8.0.111/24"
wireguard_endpoint: "worker01.p.domain.tld"
wireguard_persistent_keepalive: "30"
ansible_host: "worker01.p.domain.tld"
ansible_python_interpreter: /usr/bin/python3

Ansible host file: host_vars/worker02.i.domain.tld:

---
wireguard_address: "10.8.0.112/24"
wireguard_endpoint: "worker02.p.domain.tld"
wireguard_persistent_keepalive: "30"
ansible_host: "worker02.p.domain.tld"
ansible_python_interpreter: /usr/bin/python3

As you can see the variables are basically the same as the controller nodes have with one exception: wireguard_persistent_keepalive: "30". My worker nodes (at Hetzner Cloud) and my internal server (my server at home) are connected because I've running Postfix at my cloud nodes and the external Postfix server forwards the received mails to my internal server (and vice versa). I needed the keepalive setting because from time to time the cloud instances and the internal server lost connection and this setting solved the problem. The reason for this is of course because my internal server is behind NAT and the firewall/router must keep the NAT/firewall mapping valid (NAT and Firewall Traversal Persistence).

For my internal server at home (connected via DSL router to the internet) we've this configuration:

---
wireguard_address: "10.8.0.1/24"
wireguard_endpoint: "server.at.home.p.domain.tld"
wireguard_persistent_keepalive: "30"
ansible_host: 192.168.2.254
ansible_port: 22

By default the SSH daemon is listening on a different port than 22 on all of my public nodes but internally I use 22 and that's the reason to set ansible_port: 22 here. Also ansible_host is of course a internal IP for that host. The wireguard_endpoint value is a dynamic DNS entry. Since my IP at home isn't static I need to run a script every minute at my home server that checks if the IP has changed and if so adjusts my DNS record. I use OVH's DynHost feature to accomplish this but you can use and DynDNS provider you want of course. Also I forward incoming traffic on port 51820/UDP to my internal server to allow incoming WireGuard traffic. The wireguard_address needs to be of course part of our WireGuard subnet.

And finally for my workstation (on which I run all ansible-playbook commands):

wireguard_address: "10.8.0.2/24"
wireguard_endpoint: ""
ansible_connection: local
ansible_become: false

As you can see wireguard_endpoint: "" is a empty string here. That means the Ansible role won't set an endpoint for my workstation. Since there is no need for the other hosts to connect to my workstation it doesn't makes sense to have a endpoint defined. So in this case I can access all hosts defined in the Ansible group vpn from my workstation but not the other way round. So the resulting WireGuard config for my workstation looks like this:

[Interface]
Address = 10.8.0.2/24
PrivateKey = ....
ListenPort = 51820

[Peer]
PublicKey = ....
AllowedIPs = 10.8.0.101/32
Endpoint = controller01.p.domain.tld:51820

[Peer]
PublicKey = ....
AllowedIPs = 10.8.0.102/32
Endpoint = controller02.p.domain.tld:51820

[Peer]
PublicKey = ....
AllowedIPs = 10.8.0.103/32
Endpoint = controller03.p.domain.tld:51820

[Peer]
PublicKey = ....
AllowedIPs = 10.8.0.111/32
PersistentKeepalive = 30
Endpoint = worker01.p.domain.tld:51820

[Peer]
PublicKey = ....
AllowedIPs = 10.8.0.112/32
PersistentKeepalive = 30
Endpoint = worker02.p.domain.tld:51820

[Peer]
PublicKey = ....
AllowedIPs = 10.8.0.1/32
PersistentKeepalive = 30
Endpoint = server.at.home.p.domain.tld:51820

The other WireGuard config files (wg0.conf by default) looks similar but of course [Interface] includes the config of that specific host and the [Peer] entries lists the config of the other hosts.

Example Playbooks

- hosts: vpn
  roles:
    - githubixx.ansible_role_wireguard
  hosts: vpn
  roles:
    -
      role: githubixx.ansible_role_wireguard
      tags: role-wireguard

Example inventory using two different WireGuard interfaces on host "multi"

This is a complex example using yaml inventory format:

vpn1:
  hosts:
    multi:
      wireguard_address: 10.9.0.1/32
      wireguard_allowed_ips: "10.9.0.1/32, 192.168.2.0/24"
      wireguard_endpoint: multi.example.com
    nated:
      wireguard_address: 10.9.0.2/32
      wireguard_allowed_ips: "10.9.0.2/32, 192.168.3.0/24"
      wireguard_persistent_keepalive: 15
      wireguard_endpoint: nated.example.com
      wireguard_postup:
        - iptables -t nat -A POSTROUTING -o ens12 -j MASQUERADE
        - iptables -A FORWARD -i %i -j ACCEPT
        - iptables -A FORWARD -o %i -j ACCEPT
      wireguard_postdown:
        - iptables -t nat -D POSTROUTING -o ens12 -j MASQUERADE
        - iptables -D FORWARD -i %i -j ACCEPT
        - iptables -D FORWARD -o %i -j ACCEPT

vpn2:
  hosts:
    # Use a different name, and define ansible_host, to avoid mixing of vars without
    # needing to prefix vars with interface name.
    multi-wg1:
      ansible_host: multi
      wireguard_interface: wg1
      # when using several interface on one host, we must use different ports
      wireguard_port: 51821
      wireguard_address: 10.9.1.1/32
      wireguard_endpoint: multi.example.com
    another:
      wireguard_address: 10.9.1.2/32
      wireguard_endpoint: another.example.com

Sample playbooks for example above:

- hosts: vpn1
  roles:
    - githubixx.ansible_role_wireguard
- hosts: vpn2
  roles:
    - githubixx.ansible_role_wireguard

Testing

This role has a small test setup that is created using Molecule, libvirt (vagrant-libvirt) and QEMU/KVM. Please see my blog post Testing Ansible roles with Molecule, libvirt (vagrant-libvirt) and QEMU/KVM how to setup. The test configuration is here.

Afterwards molecule can be executed:

molecule converge -s kvm

This will setup quite a few virtual machines (VM) with different supported Linux operating systems. To run a few tests:

molecule verify -s kvm

To clean up run

molecule destroy -s kvm

There is also a small Molecule setup that mimics a central WireGuard server with a few clients:

molecule converge -s kvm-single-server

License

GNU General Public License v3.0 or later

Author Information

http://www.tauceti.blog


Download Details:

Author: githubixx
Source Code: https://github.com/githubixx/ansible-role-wireguard

#ansible #wireguard 

What is GEEK

Buddha Community

Ansible Role Wireguard: Ansible Role for installing WireGuard VPN
Fabiola  Auma

Fabiola Auma

1667684220

Ansible Role Wireguard: Ansible Role for installing WireGuard VPN

ansible-role-wireguard

This Ansible role is used in my blog series Kubernetes the not so hard way with Ansible but can be used standalone of course. The latest release is available via Ansible Galaxy. I use WireGuard and this Ansible role to setup a fully meshed VPN between all nodes of my little Kubernetes cluster.

In general WireGuard is a network tunnel (VPN) for IPv4 and IPv6 that uses UDP. If you need more information about WireGuard you can find a good introduction here: Installing WireGuard, the Modern VPN.

Linux

This role should work with:

  • Ubuntu 18.04 (Bionic Beaver)
  • Ubuntu 20.04 (Focal Fossa)
  • Ubuntu 22.04 (Jammy Jellyfish)
  • Archlinux
  • Debian 10 (Buster)
  • Debian 11 (Bullseye)
  • Fedora 34 (or later)
  • CentOS 7
  • AlmaLinux
  • Rocky Linux
  • openSUSE Leap 15.3

Molecule tests are available (see further down below). It should also work with Raspbian Buster but for this one there is no test available. MacOS (see below) should also work partitially but is only best effort.

MacOS

While this playbook configures, enables and starts a systemd service on Linux in a such a way that no additional action is needed, on MacOS it installs the required packages and it just generates the correct wg0.conf file that is then placed in the specified wireguard_remote_directory (/opt/local/etc/wireguard by default). In order to run the VPN, then, you need to:

sudo wg-quick up wg0

and to deactivate it

sudo wg-quick down wg0

or you can install the official app and import the wg0.conf file.

Versions

I tag every release and try to stay with semantic versioning. If you want to use the role I recommend to checkout the latest tag. The master branch is basically development while the tags mark stable releases. But in general I try to keep master in good shape too.

Requirements

By default port 51820 (protocol UDP) should be accessible from the outside. But you can adjust the port by changing the variable wireguard_port. Also IP forwarding needs to be enabled e.g. via echo 1 > /proc/sys/net/ipv4/ip_forward. I decided not to implement this task in this Ansible role. IMHO that should be handled elsewhere. You can use my ansible-role-harden-linux e.g. Besides changing sysctl entries (which you need to enable IP forwarding) it also manages firewall settings among other things. Nevertheless the PreUp, PreDown, PostUp and PostDown hooks may be a good place to do some network related stuff before a WireGuard interface comes up or goes down.

Changelog

see CHANGELOG.md

Role Variables

These variables can be changed in group_vars/ e.g.:

# 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

# The default port WireGuard will listen if not specified otherwise.
wireguard_port: "51820"

# The default interface name that WireGuard should use if not specified otherwise.
wireguard_interface: "wg0"

# The default owner of the wg.conf file
wireguard_conf_owner: root

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

# The default mode of the wg.conf file
wireguard_conf_mode: 0600

# The default state of the wireguard service
wireguard_service_enabled: "yes"
wireguard_service_state: "started"

# By default "wg syncconf" is used to apply WireGuard interface settings if
# they've changed. Older WireGuard tools doesn't provide this option. In that
# case as a fallback the WireGuard interface will be restarted. This causes a
# short interruption of network connections.
#
# So even if "false" is the default, the role figures out if the "syncconf"
# option of the "wg" utility is available and if not falls back to "true"
# (which means interface will be restarted as this is the only possible option
# in this case).
#
# Possible options:
# - false (default)
# - true
#
# Both options have their pros and cons. The default "false" option (do not
# restart interface)
# - does not need to restart the WireGuard interface to apply changes
# - does not cause a short VPN connection interruption when changes are applied
# - might cause network routes are not properly reloaded
#
# Setting the option value to "true" will
# - restart the WireGuard interface as the name suggests in case of changes
# - cause a short VPN connection interruption when changes are applied
# - make sure that network routes are properly reloaded
#
# So it depends a little bit on your setup which option works best. If you
# don't have an overly complicated routing that changes very often or at all
# using "false" here is most properly good enough for you. E.g. if you just
# want to connect a few servers via VPN and it normally stays this way.
#
# 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.
wireguard_interface_restart: false

# Normally the role automatically creates a private key the very first time
# if there isn't already a WireGuard configuration. But this option allows
# to provide your own WireGuard private key if really needed. As this is of
# course a very sensitive value you might consider a tool like Ansible Vault
# to store it encrypted.
# wireguard_private_key:

There are also a few Linux distribution specific settings:

#######################################
# Settings only relevant for Ubuntu
#######################################

# Set to "false" if package cache should not be updated
wireguard_ubuntu_update_cache: "true"

# Set package cache valid time
wireguard_ubuntu_cache_valid_time: "3600"

#######################################
# Settings only relevant for CentOS 7
#######################################

# Set wireguard_centos7_installation_method to "kernel-plus"
# to use the kernel-plus kernel, which includes a built-in,
# signed WireGuard module.
# UTILIZING KERNEL-PLUS WILL PERFORM A SYSTEM REBOOT DURING SETUP!!
#
# The default of "standard" will use the standard kernel and
# the ELRepo module for WireGuard.
wireguard_centos7_installation_method: "standard"

# The default seconds to wait for machine to reboot and respond
wireguard_centos7_kernel_plus_reboot_timeout: "600"

#########################################
# Settings only relevant for RockyLinux 8
#########################################

# Set wireguard_rockylinux8_installation_method to "dkms"
# to build WireGuard module from source, with wireguard-dkms.
# This is required if you use a custom kernel and/or your arch
# is not x86_64.
#
# The default of "standard" will install the kernel module
# with kmod-wireguard from ELRepo.
wireguard_rockylinux8_installation_method: "standard"

The following variable is mandatory and needs to be configured for every host in host_vars/ e.g.:

wireguard_address: "10.8.0.101/24"

Of course all IP's should be in the same subnet like /24 we see in the example above. If wireguard_allowed_ips is not set then the default value is the value from wireguard_address without the CIDR but instead with /32 which is basically a host route (have a look templates/wg.conf.j2). Let's see this example and let's assume you don't set wireguard_allowed_ips explicitly:

[Interface]
Address = 10.8.0.2/24
PrivateKey = ....
ListenPort = 51820

[Peer]
PublicKey = ....
AllowedIPs = 10.8.0.101/32
Endpoint = controller01.p.domain.tld:51820

This is part of the WireGuard config from my workstation. It has the VPN IP 10.8.0.2 and we've a /24 subnet in which all my WireGuard hosts are located. Also you can see we've a peer here that has the endpoint controller01.p.domain.tld:51820. When wireguard_allowed_ips is not explicitly set the Ansible template will add an AllowedIPs entry with the IP of that host plus /32. In WireGuard this basically specifies the routing. The config above says: On my workstation with the IP 10.8.0.2 I want send all traffic to 10.8.0.101/32 to the endpoint controller01.p.domain.tld:51820. Now let's assume we set wireguard_allowed_ips: "0.0.0.0/0". Then the resulting config looks like this.

[Interface]
Address = 10.8.0.2/24
PrivateKey = ....
ListenPort = 51820

[Peer]
PublicKey = ....
AllowedIPs = 0.0.0.0/0
Endpoint = controller01.p.domain.tld:51820

Now this is basically the same as above BUT now the config says: I want to route EVERY traffic originating from my workstation to the endpoint controller01.p.domain.tld:51820. If that endpoint can handle the traffic is of course another thing and it's up to you how you configure the endpoint routing ;-)

You can specify further optional settings (they don't have a default and won't be set if not specified besides wireguard_allowed_ips as already mentioned) also per host in host_vars/ (or in your Ansible hosts file if you like). The values for the following variables are just examples and no defaults (for more information and examples see wg-quick.8):

wireguard_allowed_ips: ""
wireguard_endpoint: "host1.domain.tld"
wireguard_persistent_keepalive: "30"
wireguard_dns: "1.1.1.1"
wireguard_fwmark: "1234"
wireguard_mtu: "1492"
wireguard_table: "5000"
wireguard_preup:
  - ...
wireguard_predown:
  - ...
wireguard_postup:
  - ...
wireguard_postdown:
  - ...
wireguard_save_config: "true"
wireguard_unmanaged_peers:
  client.example.com:
    public_key: 5zsSBeZZ8P9pQaaJvY9RbELQulcwC5VBXaZ93egzOlI=
    # preshared_key: ... e.g. from ansible-vault?
    allowed_ips: 10.0.0.3/32
    endpoint: client.example.com:51820
    persistent_keepalive: 0

wireguard_(preup|predown|postup|postdown) are specified as lists. Here are two examples:

wireguard_postup:
  - iptables -t nat -A POSTROUTING -o ens12 -j MASQUERADE
  - iptables -A FORWARD -i %i -j ACCEPT
  - iptables -A FORWARD -o %i -j ACCEPT
wireguard_preup:
  - echo 1 > /proc/sys/net/ipv4/ip_forward
  - ufw allow 51820/udp

The commands are executed in order as described in wg-quick.8.

wireguard_address is required as already mentioned. It's the IP of the interface name defined with wireguard_interface variable (wg0 by default). Every host needs a unique VPN IP of course. If you don't set wireguard_endpoint the playbook will use the hostname defined in the vpn hosts group (the Ansible inventory hostname). If you set wireguard_endpoint to "" (empty string) that peer won't have a endpoint. That means that this host can only access hosts that have a wireguard_endpoint. That's useful for clients that don't expose any services to the VPN and only want to access services on other hosts. So if you only define one host with wireguard_endpoint set and all other hosts have wireguard_endpoint set to "" (empty string) that basically means you've only clients besides one which in that case is the WireGuard server. The third possibility is to set wireguard_endpoint to some hostname. E.g. if you have different hostnames for the private and public DNS of that host and need different DNS entries for that case setting wireguard_endpoint becomes handy. Take for example the IP above: wireguard_address: "10.8.0.101". That's a private IP and I've created a DNS entry for that private IP like host01.i.domain.tld (i for internal in that case). For the public IP I've created a DNS entry like host01.p.domain.tld (p for public). The wireguard_endpoint needs to be a interface that the other members in the vpn group can connect to. So in that case I would set wireguard_endpoint to host01.p.domain.tld because WireGuard normally needs to be able to connect to the public IP of the other host(s).

Here is a litte example for what I use the playbook: I use WireGuard to setup a fully meshed VPN (every host can directly connect to every other host) and run my Kubernetes (K8s) cluster at Hetzner Cloud (but you should be able to use any hoster you want). So the important components like the K8s controller and worker nodes (which includes the pods) only communicate via encrypted WireGuard VPN. Also (as already mentioned) I've two clients. Both have kubectl installed and are able to talk to the internal Kubernetes API server by using WireGuard VPN. One of the two clients also exposes a WireGuard endpoint because the Postfix mailserver in the cloud and my internal Postfix needs to be able to talk to each other. I guess that's maybe a not so common use case for WireGuard :D But it shows what's possible. So let me explain the setup which might help you to use this Ansible role.

First, here is a part of my Ansible hosts file:

[vpn]
controller0[1:3].i.domain.tld
worker0[1:2].i.domain.tld
server.at.home.i.domain.tld
workstation.i.domain.tld

[k8s_controller]
controller0[1:3].i.domain.tld

[k8s_worker]
worker0[1:2].i.domain.tld

As you can see I've three groups here: vpn (all hosts on that will get WireGuard installed), k8s_controller (the Kubernetes controller nodes) and k8s_worker (the Kubernetes worker nodes). The i in the domainname is for internal. All the i.domain.tld DNS entries have a A record that points to the WireGuard IP that we define shortly for every host e.g.: controller01.i.domain.tld. IN A 10.8.0.101. The reason for that is that all Kubernetes components only binds and listen on the WireGuard interface in my setup. And since I need this internal IPs for all my Kubernetes components I specify the internal DNS entries in my Ansible hosts file. That way I can use the Ansible inventory hostnames and variables very easy in the playbooks and templates.

For the Kubernetes controller nodes I've defined the following host variables:

Ansible host file: host_vars/controller01.i.domain.tld

---
wireguard_address: "10.8.0.101/24"
wireguard_endpoint: "controller01.p.domain.tld"
ansible_host: "controller01.p.domain.tld"
ansible_python_interpreter: /usr/bin/python3

Ansible host file: host_vars/controller02.i.domain.tld:

---
wireguard_address: "10.8.0.102/24"
wireguard_endpoint: "controller02.p.domain.tld"
ansible_host: "controller02.p.domain.tld"
ansible_python_interpreter: /usr/bin/python3

Ansible host file: host_vars/controller03.i.domain.tld:

---
wireguard_address: "10.8.0.103/24"
wireguard_endpoint: "controller03.p.domain.tld"
ansible_host: "controller03.p.domain.tld"
ansible_python_interpreter: /usr/bin/python3

I've specified ansible_python_interpreter here for every node as the controller nodes use Ubuntu 18.04 which has Python 3 installed by default. ansible_host is set to the public DNS of that host. Ansible will use this hostname to connect to the host via SSH. I use the same value also for wireguard_endpoint because of the same reason. The WireGuard peers needs to connect to the other peers via a public IP (well at least via a IP that the WireGuard hosts can connect to - that could be of course also a internal IP if it works for you). The wireguard_address needs to be unique of course for every host.

For the Kubernetes worker I've defined the following variables:

Ansible host file: host_vars/worker01.i.domain.tld

---
wireguard_address: "10.8.0.111/24"
wireguard_endpoint: "worker01.p.domain.tld"
wireguard_persistent_keepalive: "30"
ansible_host: "worker01.p.domain.tld"
ansible_python_interpreter: /usr/bin/python3

Ansible host file: host_vars/worker02.i.domain.tld:

---
wireguard_address: "10.8.0.112/24"
wireguard_endpoint: "worker02.p.domain.tld"
wireguard_persistent_keepalive: "30"
ansible_host: "worker02.p.domain.tld"
ansible_python_interpreter: /usr/bin/python3

As you can see the variables are basically the same as the controller nodes have with one exception: wireguard_persistent_keepalive: "30". My worker nodes (at Hetzner Cloud) and my internal server (my server at home) are connected because I've running Postfix at my cloud nodes and the external Postfix server forwards the received mails to my internal server (and vice versa). I needed the keepalive setting because from time to time the cloud instances and the internal server lost connection and this setting solved the problem. The reason for this is of course because my internal server is behind NAT and the firewall/router must keep the NAT/firewall mapping valid (NAT and Firewall Traversal Persistence).

For my internal server at home (connected via DSL router to the internet) we've this configuration:

---
wireguard_address: "10.8.0.1/24"
wireguard_endpoint: "server.at.home.p.domain.tld"
wireguard_persistent_keepalive: "30"
ansible_host: 192.168.2.254
ansible_port: 22

By default the SSH daemon is listening on a different port than 22 on all of my public nodes but internally I use 22 and that's the reason to set ansible_port: 22 here. Also ansible_host is of course a internal IP for that host. The wireguard_endpoint value is a dynamic DNS entry. Since my IP at home isn't static I need to run a script every minute at my home server that checks if the IP has changed and if so adjusts my DNS record. I use OVH's DynHost feature to accomplish this but you can use and DynDNS provider you want of course. Also I forward incoming traffic on port 51820/UDP to my internal server to allow incoming WireGuard traffic. The wireguard_address needs to be of course part of our WireGuard subnet.

And finally for my workstation (on which I run all ansible-playbook commands):

wireguard_address: "10.8.0.2/24"
wireguard_endpoint: ""
ansible_connection: local
ansible_become: false

As you can see wireguard_endpoint: "" is a empty string here. That means the Ansible role won't set an endpoint for my workstation. Since there is no need for the other hosts to connect to my workstation it doesn't makes sense to have a endpoint defined. So in this case I can access all hosts defined in the Ansible group vpn from my workstation but not the other way round. So the resulting WireGuard config for my workstation looks like this:

[Interface]
Address = 10.8.0.2/24
PrivateKey = ....
ListenPort = 51820

[Peer]
PublicKey = ....
AllowedIPs = 10.8.0.101/32
Endpoint = controller01.p.domain.tld:51820

[Peer]
PublicKey = ....
AllowedIPs = 10.8.0.102/32
Endpoint = controller02.p.domain.tld:51820

[Peer]
PublicKey = ....
AllowedIPs = 10.8.0.103/32
Endpoint = controller03.p.domain.tld:51820

[Peer]
PublicKey = ....
AllowedIPs = 10.8.0.111/32
PersistentKeepalive = 30
Endpoint = worker01.p.domain.tld:51820

[Peer]
PublicKey = ....
AllowedIPs = 10.8.0.112/32
PersistentKeepalive = 30
Endpoint = worker02.p.domain.tld:51820

[Peer]
PublicKey = ....
AllowedIPs = 10.8.0.1/32
PersistentKeepalive = 30
Endpoint = server.at.home.p.domain.tld:51820

The other WireGuard config files (wg0.conf by default) looks similar but of course [Interface] includes the config of that specific host and the [Peer] entries lists the config of the other hosts.

Example Playbooks

- hosts: vpn
  roles:
    - githubixx.ansible_role_wireguard
  hosts: vpn
  roles:
    -
      role: githubixx.ansible_role_wireguard
      tags: role-wireguard

Example inventory using two different WireGuard interfaces on host "multi"

This is a complex example using yaml inventory format:

vpn1:
  hosts:
    multi:
      wireguard_address: 10.9.0.1/32
      wireguard_allowed_ips: "10.9.0.1/32, 192.168.2.0/24"
      wireguard_endpoint: multi.example.com
    nated:
      wireguard_address: 10.9.0.2/32
      wireguard_allowed_ips: "10.9.0.2/32, 192.168.3.0/24"
      wireguard_persistent_keepalive: 15
      wireguard_endpoint: nated.example.com
      wireguard_postup:
        - iptables -t nat -A POSTROUTING -o ens12 -j MASQUERADE
        - iptables -A FORWARD -i %i -j ACCEPT
        - iptables -A FORWARD -o %i -j ACCEPT
      wireguard_postdown:
        - iptables -t nat -D POSTROUTING -o ens12 -j MASQUERADE
        - iptables -D FORWARD -i %i -j ACCEPT
        - iptables -D FORWARD -o %i -j ACCEPT

vpn2:
  hosts:
    # Use a different name, and define ansible_host, to avoid mixing of vars without
    # needing to prefix vars with interface name.
    multi-wg1:
      ansible_host: multi
      wireguard_interface: wg1
      # when using several interface on one host, we must use different ports
      wireguard_port: 51821
      wireguard_address: 10.9.1.1/32
      wireguard_endpoint: multi.example.com
    another:
      wireguard_address: 10.9.1.2/32
      wireguard_endpoint: another.example.com

Sample playbooks for example above:

- hosts: vpn1
  roles:
    - githubixx.ansible_role_wireguard
- hosts: vpn2
  roles:
    - githubixx.ansible_role_wireguard

Testing

This role has a small test setup that is created using Molecule, libvirt (vagrant-libvirt) and QEMU/KVM. Please see my blog post Testing Ansible roles with Molecule, libvirt (vagrant-libvirt) and QEMU/KVM how to setup. The test configuration is here.

Afterwards molecule can be executed:

molecule converge -s kvm

This will setup quite a few virtual machines (VM) with different supported Linux operating systems. To run a few tests:

molecule verify -s kvm

To clean up run

molecule destroy -s kvm

There is also a small Molecule setup that mimics a central WireGuard server with a few clients:

molecule converge -s kvm-single-server

License

GNU General Public License v3.0 or later

Author Information

http://www.tauceti.blog


Download Details:

Author: githubixx
Source Code: https://github.com/githubixx/ansible-role-wireguard

#ansible #wireguard 

akshay L

akshay L

1571752812

Ansible Installation & Configuration on AWS

In this video you will learn Ansible Installation & Configuration on AWS and how to install & configure ansible on ec2 step by step.

Why DevOps is important?

DevOps implementation is going through the roof with most of the largest software organizations around the world invested heavily in its implementation. The core values of devops is effectively based on the Agile Manifesto but with one slight change which moves the focus from creating a working software to one that is more interested in the end-to-end software service mechanism and delivery.

Why should you opt for a DevOps career?

For very long times the development and the operations teams of any software enterprise have stayed at arm’s length. But this organizational cultural shift thanks to devops a lot of changes are happening in forward-thinking enterprises. Learning devops will help you master all the skills needed in order to successfully build, operate, monitor, measure and improve the various processes in IT enterprises by better integrating development and operations. You will grab the best jobs in top MNCs after finishing this Intellipaat devops online training. The entire Intellipaat devops course is in line with the industry needs. There is a huge demand for devops certified professional. The salaries for devops professional are very good.

#Install Ansible #Ansible Installation and Configurationon AWS #Ansible

Awesome Ansible List

Awesome Ansible

A collaborative curated list of awesome Ansible resources, tools, Roles, tutorials and other related stuff.

Ansible is an open source toolkit, written in Python, it is used for configuration management, application deployment, continuous delivery, IT infrastructure automation and automation in general.

Official resources

Official resources by and for Ansible.

Community

Places where to chat with the Ansible community

Tutorials

Tutorials and courses to learn Ansible.

Books

Books about Ansible.

Videos

Video tutorials and Ansible training.

Tools

Tools for and using Ansible.

  • Ansible Tower - Ansible Tower by Red Hat helps you scale IT automation, manage complex deployments and speed productivity. Extend the power of Ansible to your entire team.
  • AWX - AWX provides a web-based user interface, REST API, and task engine built on top of Ansible. It is the upstream project for Tower, a commercial derivative of AWX.
  • Ansible Lint - Checks Playbooks for best practices and behavior that could potentially be improved.
  • Ansible Later - Another best practice scanner. Checks Playbooks and Roles for best practices and behavior that could potentially be improved.
  • Ansible Doctor - Simple annotation like documentation generator for Ansible roles based on Jinja2 templates.
  • Ansible cmdb - Takes the output of Ansible's fact gathering and converts it into a static HTML page.
  • ARA - ARA Records Ansible playbooks and makes them easier to understand and troubleshoot with a reporting API, UI and CLI.
  • Mitogen for Ansible - Speed up Ansible substantially with Mitogen.
  • Molecule - Molecule aids in the development and testing of Ansible roles.
  • Packer Ansible Provisioner - This Provisioner can be used to automate VM Image creation via Packer with Ansible.
  • Excel Ansible Inventory - Turn any Excel Spreadsheet into an Ansible Inventory.
  • terraform.py - Ansible dynamic inventory script for parsing Terraform state files.
  • ansible-navigator - A text-based user interface (TUI) for Ansible.
  • squest - Self-service portal for Ansible Tower job templates.
  • ansible-bender - Tool which bends containers using Ansible playbooks and turns them into container images.
  • ansible-runner - A tool and python library that helps when interfacing with Ansible directly or as part of another system whether that be through a container image interface, as a standalone tool, or as a Python module that can be imported.
  • ansible-builder - Using Ansible content that depends on non-default dependencies can be tricky. Packages must be installed on each node, play nicely with other software installed on the host system, and be kept in sync.
  • kics - SAST Tool that scans your ansible infrastructure as code playbooks for security vulnverables, compliance issues and misconfigurations.
  • php-ansible Library - OOP-Wrapper for Ansible, making Ansible available in PHP.
  • TD4A - Design aid for building and testing jinja2 templates, combines data in yaml format with a jinja2 template and render the output.
  • Ansible Playbook Grapher - Command line tool to create a graph representing your Ansible playbook plays, tasks and roles.
  • ansible-doc-extractor - A tool that extracts documentation from Ansible modules in the HTML form.
  • Ansible Semaphore - Ansible Semaphore is a modern UI for Ansible.

Blog posts and opinions

Best practices and other opinions on Ansible.

German

Playbooks, Roles and Collections

Awesome production ready Playbooks, Roles and Collections to get you up and running.


Download Details:

Author: ansible-community
Source Code: https://github.com/ansible-community/awesome-ansible

License: CC0-1.0 license

#ansible 

Hal  Sauer

Hal Sauer

1591203120

How to Install Wireguard on Ubuntu 18

In this tutorial we will learn what Wireguard is, what it is used for, how to install and configure it, and lastly, how to use it to it wisely.

#tutorials #end point #ifconfig #ipconfig #kernel #kernel module #keypair #netmask #network #network interface #permissions #point-to-point #ppa #private keys #public keys #ssh #systemctl #tunnel #tunneling #ubuntu #ubuntu 18.04 #ufw #umask #vpn #vpn port #wireguard

Nigel  Uys

Nigel Uys

1673452680

Ansible-role-nginx: Ansible Role - Nginx

Ansible Role: Nginx

Note: Please consider using the official NGINX Ansible role from NGINX, Inc.

Installs Nginx on RedHat/CentOS, Debian/Ubuntu, Archlinux, FreeBSD or OpenBSD servers.

This role installs and configures the latest version of Nginx from the Nginx yum repository (on RedHat-based systems), apt (on Debian-based systems), pacman (Archlinux), pkgng (on FreeBSD systems) or pkg_add (on OpenBSD systems). You will likely need to do extra setup work after this role has installed Nginx, like adding your own [virtualhost].conf file inside /etc/nginx/conf.d/, describing the location and options to use for your particular website.

Requirements

None.

Role Variables

Available variables are listed below, along with default values (see defaults/main.yml):

nginx_listen_ipv6: true

Whether or not to listen on IPv6 (applied to all vhosts managed by this role).

nginx_vhosts: []

A list of vhost definitions (server blocks) for Nginx virtual hosts. Each entry will create a separate config file named by server_name. If left empty, you will need to supply your own virtual host configuration. See the commented example in defaults/main.yml for available server options. If you have a large number of customizations required for your server definition(s), you're likely better off managing the vhost configuration file yourself, leaving this variable set to [].

nginx_vhosts:
  - listen: "443 ssl http2"
    server_name: "example.com"
    server_name_redirect: "www.example.com"
    root: "/var/www/example.com"
    index: "index.php index.html index.htm"
    error_page: ""
    access_log: ""
    error_log: ""
    state: "present"
    template: "{{ nginx_vhost_template }}"
    filename: "example.com.conf"
    extra_parameters: |
      location ~ \.php$ {
          fastcgi_split_path_info ^(.+\.php)(/.+)$;
          fastcgi_pass unix:/var/run/php5-fpm.sock;
          fastcgi_index index.php;
          fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
          include fastcgi_params;
      }
      ssl_certificate     /etc/ssl/certs/ssl-cert-snakeoil.pem;
      ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
      ssl_protocols       TLSv1.1 TLSv1.2;
      ssl_ciphers         HIGH:!aNULL:!MD5;

An example of a fully-populated nginx_vhosts entry, using a | to declare a block of syntax for the extra_parameters.

Please take note of the indentation in the above block. The first line should be a normal 2-space indent. All other lines should be indented normally relative to that line. In the generated file, the entire block will be 4-space indented. This style will ensure the config file is indented correctly.

  - listen: "80"
    server_name: "example.com www.example.com"
    return: "301 https://example.com$request_uri"
    filename: "example.com.80.conf"

An example of a secondary vhost which will redirect to the one shown above.

Note: The filename defaults to the first domain in server_name, if you have two vhosts with the same domain, eg. a redirect, you need to manually set the filename so the second one doesn't override the first one

nginx_remove_default_vhost: false

Whether to remove the 'default' virtualhost configuration supplied by Nginx. Useful if you want the base / URL to be directed at one of your own virtual hosts configured in a separate .conf file.

nginx_upstreams: []

If you are configuring Nginx as a load balancer, you can define one or more upstream sets using this variable. In addition to defining at least one upstream, you would need to configure one of your server blocks to proxy requests through the defined upstream (e.g. proxy_pass http://myapp1;). See the commented example in defaults/main.yml for more information.

nginx_user: "nginx"

The user under which Nginx will run. Defaults to nginx for RedHat, www-data for Debian and www on FreeBSD and OpenBSD.

nginx_worker_processes: "{{ ansible_processor_vcpus|default(ansible_processor_count) }}"
nginx_worker_connections: "1024"
nginx_multi_accept: "off"

nginx_worker_processes should be set to the number of cores present on your machine (if the default is incorrect, find this number with grep processor /proc/cpuinfo | wc -l). nginx_worker_connections is the number of connections per process. Set this higher to handle more simultaneous connections (and remember that a connection will be used for as long as the keepalive timeout duration for every client!). You can set nginx_multi_accept to on if you want Nginx to accept all connections immediately.

nginx_error_log: "/var/log/nginx/error.log warn"
nginx_access_log: "/var/log/nginx/access.log main buffer=16k flush=2m"

Configuration of the default error and access logs. Set to off to disable a log entirely.

nginx_sendfile: "on"
nginx_tcp_nopush: "on"
nginx_tcp_nodelay: "on"

TCP connection options. See this blog post for more information on these directives.

nginx_keepalive_timeout: "65"
nginx_keepalive_requests: "100"

Nginx keepalive settings. Timeout should be set higher (10s+) if you have more polling-style traffic (AJAX-powered sites especially), or lower (<10s) if you have a site where most users visit a few pages and don't send any further requests.

nginx_server_tokens: "on"

Nginx server_tokens settings. Controls whether nginx responds with it's version in HTTP headers. Set to "off" to disable.

nginx_client_max_body_size: "64m"

This value determines the largest file upload possible, as uploads are passed through Nginx before hitting a backend like php-fpm. If you get an error like client intended to send too large body, it means this value is set too low.

nginx_server_names_hash_bucket_size: "64"

If you have many server names, or have very long server names, you might get an Nginx error on startup requiring this value to be increased.

nginx_proxy_cache_path: ""

Set as the proxy_cache_path directive in the nginx.conf file. By default, this will not be configured (if left as an empty string), but if you wish to use Nginx as a reverse proxy, you can set this to a valid value (e.g. "/var/cache/nginx keys_zone=cache:32m") to use Nginx's cache (further proxy configuration can be done in individual server configurations).

nginx_extra_http_options: ""

Extra lines to be inserted in the top-level http block in nginx.conf. The value should be defined literally (as you would insert it directly in the nginx.conf, adhering to the Nginx configuration syntax - such as ; for line termination, etc.), for example:

nginx_extra_http_options: |
  proxy_buffering    off;
  proxy_set_header   X-Real-IP $remote_addr;
  proxy_set_header   X-Scheme $scheme;
  proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header   Host $http_host;

See the template in templates/nginx.conf.j2 for more details on the placement.

nginx_extra_conf_options: ""

Extra lines to be inserted in the top of nginx.conf. The value should be defined literally (as you would insert it directly in the nginx.conf, adhering to the Nginx configuration syntax - such as ; for line termination, etc.), for example:

nginx_extra_conf_options: |
  worker_rlimit_nofile 8192;

See the template in templates/nginx.conf.j2 for more details on the placement.

nginx_log_format: |-
  '$remote_addr - $remote_user [$time_local] "$request" '
  '$status $body_bytes_sent "$http_referer" '
  '"$http_user_agent" "$http_x_forwarded_for"'

Configures Nginx's log_format. options.

nginx_default_release: ""

(For Debian/Ubuntu only) Allows you to set a different repository for the installation of Nginx. As an example, if you are running Debian's wheezy release, and want to get a newer version of Nginx, you can install the wheezy-backports repository and set that value here, and Ansible will use that as the -t option while installing Nginx.

nginx_ppa_use: false
nginx_ppa_version: stable

(For Ubuntu only) Allows you to use the official Nginx PPA instead of the system's package. You can set the version to stable or development.

nginx_yum_repo_enabled: true

(For RedHat/CentOS only) Set this to false to disable the installation of the nginx yum repository. This could be necessary if you want the default OS stable packages, or if you use Satellite.

nginx_service_state: started
nginx_service_enabled: yes

By default, this role will ensure Nginx is running and enabled at boot after Nginx is configured. You can use these variables to override this behavior if installing in a container or further control over the service state is required.

Overriding configuration templates

If you can't customize via variables because an option isn't exposed, you can override the template used to generate the virtualhost configuration files or the nginx.conf file.

nginx_conf_template: "nginx.conf.j2"
nginx_vhost_template: "vhost.j2"

If necessary you can also set the template on a per vhost basis.

nginx_vhosts:
  - listen: "80 default_server"
    server_name: "site1.example.com"
    root: "/var/www/site1.example.com"
    index: "index.php index.html index.htm"
    template: "{{ playbook_dir }}/templates/site1.example.com.vhost.j2"
  - server_name: "site2.example.com"
    root: "/var/www/site2.example.com"
    index: "index.php index.html index.htm"
    template: "{{ playbook_dir }}/templates/site2.example.com.vhost.j2"

You can either copy and modify the provided template, or extend it with Jinja2 template inheritance and override the specific template block you need to change.

Example: Configure gzip in nginx configuration

Set the nginx_conf_template to point to a template file in your playbook directory.

nginx_conf_template: "{{ playbook_dir }}/templates/nginx.conf.j2"

Create the child template in the path you configured above and extend geerlingguy.nginx template file relative to your playbook.yml.

{% extends 'roles/geerlingguy.nginx/templates/nginx.conf.j2' %}

{% block http_gzip %}
    gzip on;
    gzip_proxied any;
    gzip_static on;
    gzip_http_version 1.0;
    gzip_disable "MSIE [1-6]\.";
    gzip_vary on;
    gzip_comp_level 6;
    gzip_types
        text/plain
        text/css
        text/xml
        text/javascript
        application/javascript
        application/x-javascript
        application/json
        application/xml
        application/xml+rss
        application/xhtml+xml
        application/x-font-ttf
        application/x-font-opentype
        image/svg+xml
        image/x-icon;
    gzip_buffers 16 8k;
    gzip_min_length 512;
{% endblock %}

Dependencies

None.

Example Playbook

- hosts: server
  roles:
    - { role: geerlingguy.nginx }

Download Details:

Author: Geerlingguy
Source Code: https://github.com/geerlingguy/ansible-role-nginx 
License: MIT license

#ansible #role #nginx