Initial commit

This commit is contained in:
Tyler Hale 2021-09-23 09:54:34 -06:00
parent cc01d8bf27
commit 054a3711f1
Signed by: Tyler
GPG key ID: 3F9270F8F70AC13D
9 changed files with 393 additions and 7 deletions

View file

@ -2,18 +2,69 @@
Ansible playbook that provisions a group of servers to run HAProxy with a shared hosting IP from kepalived. Ansible playbook that provisions a group of servers to run HAProxy with a shared hosting IP from kepalived.
## Requirements
## Variables ## Variables
| Variable | Required | Default | Choices | Description | | Variable | Required | Default | Choices | Description |
| -------- | -------- | ------- | ------- | ----------- | | --------------------------------- | -------- | -------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| | | | | | | haproxy_bind_adapter | Yes | eth0 | | Interface to use for the Shared IP |
| haproxy_keepalived_adapter | Yes | eth0 | | Interface to use for the keepalived communication |
| haproxy_keepalived_adapter_vlan | No | | | When specified, this will setup the given vlan and use that for the keepalived communication to keep the traffic out of the primary network |
| haproxy_keepalived_ip | Yes | 172.16.10.1/24 | | IP to use for the keepalived communication |
| haproxy_keepalived_process_weight | Yes | 10 | | Weight used for tracking the haproxy process on the server |
| haproxy_shared_ip | Yes | | | Shared IP that will be used by the group |
| haproxy_shared_ip_subnet | Yes | /24 | | Subnet for the shared IP |
| haproxy_shared_priority | Yes | 100 | | Keepalived priority for the host - this will |
| haproxy_shared_state | Yes | MASTER | MASTER/BACKUP | What state the keepalived configuration will start with for the desired host - After config starts it will determine if other members exist and adjust based on priority |
| haproxy_shared_virtual_router_id | Yes | 25 | | Virtual Router ID for the keepalived configuration - This should be the same for the group |
## Example ## Example
Execute playbook with needed variables
`ansible-playbook -i hosts site.yml --ask-pass --ask-become-pass`
Inventory File:
```yaml
---
# file: hosts
haproxy:
hosts:
dev-ha01:
ansible_host: 10.1.1.3
haproxy_shared_state: MASTER
haproxy_shared_priority: 101
haproxy_bind_adapter: "eth0"
haproxy_keepalived_adapter: "eth0"
haproxy_keepalived_adapter_vlan: "100"
haproxy_keepalived_ip: 172.16.10.1/24
dev-ha02:
ansible_host: 10.1.1.4
haproxy_shared_state: BACKUP
haproxy_shared_priority: 100
haproxy_bind_adapter: "eth0"
haproxy_keepalived_adapter: "eth0"
haproxy_keepalived_adapter_vlan: "100"
haproxy_keepalived_ip: 172.16.10.2/24
dev-ha03:
ansible_host: 10.1.1.5
haproxy_shared_state: BACKUP
haproxy_shared_priority: 99
haproxy_bind_adapter: "eth0"
haproxy_keepalived_adapter: "eth0"
haproxy_keepalived_adapter_vlan: "100"
haproxy_keepalived_ip: 172.16.10.3/24
vars:
haproxy_shared_ip: "10.10.2.60"
haproxy_shared_ip_subnet: "/24"
haproxy_shared_virtual_router_id: 25
```
## License ## License
See LICENSE file for full license information. See LICENSE file for full license information.
## Screenshots

6
haproxy.yml Normal file
View file

@ -0,0 +1,6 @@
---
# file: haproxy.yml
- hosts: haproxy
roles:
- haproxy

37
hosts.yml Normal file
View file

@ -0,0 +1,37 @@
---
# file: hosts
haproxy:
hosts:
dev-ha01:
ansible_host: 10.1.1.3
haproxy_shared_state: MASTER
haproxy_shared_priority: 101
haproxy_bind_adapter: "eth0"
haproxy_keepalived_adapter: "eth0"
haproxy_keepalived_adapter_vlan: "100"
haproxy_keepalived_ip: 172.16.10.1/24
dev-ha02:
ansible_host: 10.1.1.4
haproxy_shared_state: BACKUP
haproxy_shared_priority: 100
haproxy_bind_adapter: "eth0"
haproxy_keepalived_adapter: "eth0"
haproxy_keepalived_adapter_vlan: "100"
haproxy_keepalived_ip: 172.16.10.2/24
dev-ha03:
ansible_host: 10.1.1.5
haproxy_shared_state: BACKUP
haproxy_shared_priority: 99
haproxy_bind_adapter: "eth0"
haproxy_keepalived_adapter: "eth0"
haproxy_keepalived_adapter_vlan: "100"
haproxy_keepalived_ip: 172.16.10.3/24
vars:
haproxy_shared_ip: "10.10.2.60"
haproxy_shared_ip_subnet: "/24"
haproxy_shared_virtual_router_id: 25

View file

@ -0,0 +1,20 @@
---
# file: roles/haproxy/defaults/main.yml
haproxy_config_file: "example.haproxy.cfg.j2"
# Set for entire group
haproxy_shared_ip: ""
haproxy_shared_ip_subnet: "/24"
haproxy_shared_virtual_router_id: 25
haproxy_keepalived_process_weight: 10
# Set per host
haproxy_shared_state: MASTER
haproxy_shared_priority: 100
haproxy_bind_adapter: "eth0"
haproxy_keepalived_adapter: "eth0"
haproxy_keepalived_adapter_vlan: ""
haproxy_keepalived_ip: 172.16.10.1/24

View file

@ -0,0 +1,26 @@
---
# file: roles/haproxy/handlers/main.yml
- name: reload haproxy
service:
name: haproxy
state: reloaded
become: yes
- name: reload keepalived
service:
name: keepalived
state: reloaded
become: yes
- name: reload firewalld
service:
name: firewalld
state: reloaded
become: yes
- name: Restart SSH
service:
name: sshd
state: restarted
become: yes

View file

@ -0,0 +1,134 @@
---
# file: roles/haproxy/tasks/main.yml
- name: Install Ansible prereq packages
package:
name:
- policycoreutils-python-utils
- NetworkManager
state: latest
become: yes
- name: Install packages
package:
name:
- keepalived
- haproxy
- firewalld
state: latest
become: yes
- name: Add VLAN
nmcli:
conn_name: "{{ haproxy_keepalived_adapter }}.{{ haproxy_keepalived_adapter_vlan }}"
vlanid: "{{ haproxy_keepalived_adapter_vlan }}"
ip4: "{{ haproxy_keepalived_ip }}"
vlandev: "{{ haproxy_keepalived_adapter }}"
autoconnect: yes
type: vlan
state: present
become: yes
when: (haproxy_keepalived_adapter_vlan is defined) and (haproxy_keepalived_ip is defined)
- name: Enable firewall rule for vrrp
firewalld:
rich_rule: 'rule protocol value="vrrp" accept'
permanent: yes
state: enabled
immediate: yes
notify: reload firewalld
become: yes
- name: Allow binding non-local IP
sysctl:
name: net.ipv4.ip_nonlocal_bind
value: "1"
reload: true
state: present
become: yes
- name: Allow binding ip forward
sysctl:
name: net.ipv4.ip_forward
value: "1"
reload: true
state: present
become: yes
- name: Update keepalived configuration
template:
src: keepalived.conf.j2
dest: /etc/keepalived/keepalived.conf
notify: reload keepalived
become: yes
- name: Enable keepalived
service:
name: keepalived
state: started
enabled: yes
become: yes
- name: Limit SSH to only ansible_host
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?ListenAddress '
line: "ListenAddress {{ ansible_host }}"
notify:
- Restart SSH
become: yes
- name: Flush handlers
meta: flush_handlers
- name: Set haproxy_connect_any flag and keep it persistent across reboots
seboolean:
name: haproxy_connect_any
state: yes
persistent: yes
become: yes
- name: Update HAProxy configuration
template:
src: haproxy.cfg.j2
dest: /etc/haproxy/haproxy.cfg
mode: 0644
validate: haproxy -f %s -c -q
notify: reload haproxy
become: yes
- name: Ensure HAProxy is started and enabled on boot.
service:
name: haproxy
state: started
enabled: yes
become: yes
- name: Enable firewall ports for haproxy
firewalld:
rich_rule: 'rule family=ipv4 destination address={{ haproxy_shared_ip }}{{ haproxy_shared_ip_subnet }} port port={{ item.port }} protocol={{ item.protocol }} accept'
permanent: yes
immediate: yes
state: enabled
with_items:
- {port: "22", protocol: "tcp"}
- {port: "80", protocol: "tcp"}
- {port: "443", protocol: "tcp"}
notify: reload firewalld
become: yes
- name: Enable firewall ports for haproxy stats
firewalld:
port: "9999/tcp"
permanent: yes
immediate: yes
state: enabled
notify: reload firewalld
become: yes
- name: Enable firewalld
service:
name: firewalld
state: started
enabled: yes
become: yes

View file

@ -0,0 +1,84 @@
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
#stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats socket /var/lib/haproxy/stats
stats timeout 30s
user haproxy
group haproxy
daemon
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
# See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
tune.ssl.default-dh-param 2048
tune.h2.initial-window-size 1048576
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
{% if ansible_os_family == 'Debian' %}
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
{% endif %}
frontend ssh-in
mode tcp
bind {{ haproxy_shared_ip }}:22
timeout connect 0ms
timeout client 0ms
timeout server 0ms
use_backend example-ssh-backend
frontend http-in
mode http
bind {{ haproxy_shared_ip }}:80
use_backend example-http-backend
frontend https-in
mode tcp
tcp-request inspect-delay 1s
bind {{ haproxy_shared_ip }}:443
tcp-request content accept if { req.ssl_hello_type 1 }
use_backend example-https-backend
backend example-ssh-backend
mode tcp
timeout connect 0ms
timeout client 0ms
timeout server 0ms
server example 10.1.1.11:22 check
backend example-http-backend
mode http
log global
timeout connect 30000
timeout server 30000
retries 3
server example 10.10.2.11:80 check
backend example-https-backend
mode tcp
log global
timeout connect 30000
timeout server 30000
retries 3
server example 10.10.2.11:443 check

View file

@ -0,0 +1,24 @@
vrrp_track_process track_haproxy {
process haproxy
weight {{ haproxy_keepalived_process_weight }}
}
vrrp_instance VI_1 {
{% if haproxy_keepalived_adapter_vlan != '' %}
interface {{ haproxy_keepalived_adapter }}.{{ haproxy_keepalived_adapter_vlan }}
{% else %}
interface {{ haproxy_keepalived_adapter }}
{% endif %}
state {{ haproxy_shared_state }}
virtual_router_id {{ haproxy_shared_virtual_router_id }}
priority {{ haproxy_shared_priority }}
virtual_ipaddress {
{{ haproxy_shared_ip }}{{ haproxy_shared_ip_subnet }} dev {{ haproxy_bind_adapter }}
}
track_process {
track_haproxy
}
}

4
site.yml Normal file
View file

@ -0,0 +1,4 @@
---
## This playbook deploys the whole application stack in this site.
- import_playbook: haproxy.yml