diff --git a/haproxy.yml b/haproxy.yml new file mode 100644 index 0000000..ec2039f --- /dev/null +++ b/haproxy.yml @@ -0,0 +1,8 @@ +--- +- hosts: + - emma + + become: yes + + roles: + - haproxy diff --git a/host_vars/emma.ccchb.de b/host_vars/emma.ccchb.de index d29f526..740cc7a 100644 --- a/host_vars/emma.ccchb.de +++ b/host_vars/emma.ccchb.de @@ -1,4 +1,23 @@ --- +haproxy_v4: 176.9.59.104 +haproxy_v6: 2a01:4f8:150:926f::2 + +haproxy_http: + - host: 'ccchb.de' + addr: '2a01:238:4246:1e00:2207:546f:6a47:6050' + - host: 'www.ccchb.de' + addr: '2a01:238:4246:1e00:2207:546f:6a47:6050' + - host: 'cloud.ccchb.de' + addr: '2a01:4f8:150:926f::5' + +haproxy_https: + - host: 'ccchb.de' + addr: '2a01:238:4246:1e00:2207:546f:6a47:6050' + - host: 'www.ccchb.de' + addr: '2a01:238:4246:1e00:2207:546f:6a47:6050' + - host: 'cloud.ccchb.de' + addr: '2a01:4f8:150:926f::5' + bhyve_ipv4: 10.0.0.0 bhyve_ipv6: 2a01:4f8:150:926f::4 bhyve_pool: emma @@ -87,3 +106,18 @@ bhyve_guests: volsize: 64g volblocksize: 64k primarycache: metadata + + - name: docloc-irc + index: 5 + enabled: true + ram: 1G + cpus: 1 + image: debian-10.5.0-amd64-netinst.iso + order: + - DISKS + disks: + - name: disk + properties: + volsize: 32g + volblocksize: 64k + primarycache: metadata diff --git a/roles/haproxy/handlers/main.yml b/roles/haproxy/handlers/main.yml new file mode 100644 index 0000000..732e514 --- /dev/null +++ b/roles/haproxy/handlers/main.yml @@ -0,0 +1,11 @@ +--- +- name: Reload s6-rc + service: + name: s6-rc + state: reloaded + +- name: Restart HAProxy + command: s6-svc -t /run/service/haproxy + +- name: Reload HAProxy + command: s6-svc -2 /run/service/haproxy diff --git a/roles/haproxy/tasks/main.yml b/roles/haproxy/tasks/main.yml new file mode 100644 index 0000000..9651f51 --- /dev/null +++ b/roles/haproxy/tasks/main.yml @@ -0,0 +1,155 @@ +--- +- name: Install HAProxy + package: + name: haproxy + state: present + notify: + - Restart HAProxy + +- name: Create HAProxy group + group: + name: haproxy + gid: 20001 + notify: + - Restart HAProxy + +- name: Create HAProxy user + user: + name: haproxy + uid: 20001 + group: haproxy + create_home: no + home: /var/empty + notify: + - Restart HAProxy + +- name: Create HAProxy service directories + file: + path: '/etc/s6-rc/service/{{ item }}' + state: directory + owner: root + group: wheel + mode: 0755 + with_items: + - haproxy + - haproxy/env + - haproxy/data + - haproxy-log + - haproxy-log/env + +- name: Generate HAProxy service scripts + template: + dest: '/etc/s6-rc/service/{{ item }}' + src: '{{ item }}.j2' + mode: 0555 + owner: root + group: wheel + with_items: + - haproxy/run + - haproxy/finish + - haproxy/data/check + - haproxy-log/run + - haproxy-log/finish + notify: + - Reload s6-rc + - Restart HAProxy + +- name: Generate HAProxy service configuration + copy: + dest: '/etc/s6-rc/service/{{ item.name }}' + content: '{{ item.content }}' + mode: 0444 + owner: root + group: wheel + loop_control: + label: '{{ item.name }} = {{ item.content }}' + notify: + - Reload s6-rc + - Restart HAProxy + with_items: + - name: haproxy/type + content: longrun + - name: haproxy/notification-fd + content: 3 + - name: haproxy/producer-for + content: haproxy-log + - name: haproxy/env/NAME + content: haproxy + - name: haproxy/env/PATH + content: /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/root/bin + - name: haproxy/env/BIND_V4 + content: '{{ haproxy_v4 }}' + - name: haproxy/env/BIND_V6 + content: '{{ haproxy_v6 }}' + + - name: haproxy-log/type + content: longrun + - name: haproxy-log/notification-fd + content: 3 + - name: haproxy-log/consumer-for + content: haproxy + - name: haproxy-log/env/NAME + content: haproxy + - name: haproxy-log/env/PATH + content: /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/root/bin + - name: haproxy-log/env/MODE + content: '750' + - name: haproxy-log/env/USER + content: s6-log + - name: haproxy-log/env/GROUP + content: s6-log + - name: haproxy-log/env/DIR + content: /var/log/haproxy + +- name: Create HAProxy configuration directory + file: + path: /usr/local/etc/haproxy + state: directory + owner: root + group: wheel + mode: 0755 + +- name: Configure HAProxy + template: + dest: '/usr/local/etc/haproxy/{{ item }}' + src: '{{ item }}.j2' + owner: root + group: wheel + mode: 0444 + notify: + - Reload HAProxy + with_items: + - defaults.cfg + - global.cfg + - http.cfg + +- name: Config HAProxy HTTP backends + template: + dest: '/usr/local/etc/haproxy/http_{{ item.host }}.cfg' + src: http_host.cfg.j2 + owner: root + group: wheel + mode: 0444 + notify: + - Reload HAProxy + with_items: '{{ haproxy_http }}' + +- name: Enable HAProxy HTTP backends + lineinfile: + path: /usr/local/etc/haproxy/http.map + regex: '^{{ item.host }} ' + line: '{{ item.host }} http_{{ item.host }}' + notify: + - Reload HAProxy + with_items: '{{ haproxy_http }}' + +- name: Make sure the http map exists + command: env touch /usr/local/etc/haproxy/http.map + args: + creates: + /usr/local/etc/haproxy/http.map + notify: + - Reload HAProxy + +- name: Flush handlers + meta: flush_handlers diff --git a/roles/haproxy/templates/defaults.cfg.j2 b/roles/haproxy/templates/defaults.cfg.j2 new file mode 100644 index 0000000..f8f1692 --- /dev/null +++ b/roles/haproxy/templates/defaults.cfg.j2 @@ -0,0 +1,14 @@ +# {{ ansible_managed }} + +defaults + log global + + mode http + option httplog + + option clitcpka + option srvtcpka + timeout client 30s + timeout server 30s + timeout connect 5s + diff --git a/roles/haproxy/templates/global.cfg.j2 b/roles/haproxy/templates/global.cfg.j2 new file mode 100644 index 0000000..58da31c --- /dev/null +++ b/roles/haproxy/templates/global.cfg.j2 @@ -0,0 +1,7 @@ +# {{ ansible_managed }} +global + chroot /var/empty + log stdout format raw local0 info + user haproxy + group haproxy + diff --git a/roles/haproxy/templates/haproxy-log/finish.j2 b/roles/haproxy/templates/haproxy-log/finish.j2 new file mode 100644 index 0000000..00e3945 --- /dev/null +++ b/roles/haproxy/templates/haproxy-log/finish.j2 @@ -0,0 +1,13 @@ +#!/usr/local/bin/execlineb -S2 +# {{ ansible_managed }} + +s6-envdir ./env +multisubstitute { + importas -i -u NAME NAME +} + +fdmove -c 1 2 +ifelse { test "${1}" -eq 0 } { + echo "${NAME}: Stopped." +} + echo "${NAME}: Failed with exit status (${1}, ${2})." diff --git a/roles/haproxy/templates/haproxy-log/run.j2 b/roles/haproxy/templates/haproxy-log/run.j2 new file mode 100644 index 0000000..2c30043 --- /dev/null +++ b/roles/haproxy/templates/haproxy-log/run.j2 @@ -0,0 +1,30 @@ +#!/usr/local/bin/execlineb +# {{ ansible_managed }} + +s6-envdir ./env +multisubstitute { + importas -i -u NAME NAME + importas -i -u USER USER + importas -i -u GROUP GROUP + importas -i -u MODE MODE + importas -i -u DIR DIR +} + +foreground { fdmove -c 1 2 echo "${NAME} log: Starting." } + +ifelse -n { install -d -o "${USER}" -g "${GROUP}" -m "${MODE}" "$DIR" } { + foreground { fdmove -c 1 2 echo "${NAME} log: Failed to create logging directory." } + false +} + +ifelse -n { fdmove 1 3 echo } { + foreground { fdmove -c 1 2 echo "${NAME} log: Failed to signal readiness." } + false +} + +foreground { fdmove -c 1 2 echo "${NAME} log: Ready." } + +fdmove -c 2 1 + +s6-envuidgid $USER +s6-log T $DIR diff --git a/roles/haproxy/templates/haproxy/data/check.j2 b/roles/haproxy/templates/haproxy/data/check.j2 new file mode 100644 index 0000000..1d82c1e --- /dev/null +++ b/roles/haproxy/templates/haproxy/data/check.j2 @@ -0,0 +1,18 @@ +#!/usr/local/bin/execlineb -P +# {{ ansible_managed }} + +s6-envdir ./env +multisubstitute { + importas -i -u NAME NAME +} + +ifelse { + redirfd -w 1 /dev/null + fdmove -c 2 1 + pipeline { echo quit } nc -U /var/run/haproxy.master +} { + foreground { fdmove -c 1 2 echo "${NAME}: Ready." } + true +} + foreground { fdmove -c 1 2 echo "${NAME}: Poll." } + false diff --git a/roles/haproxy/templates/haproxy/finish.j2 b/roles/haproxy/templates/haproxy/finish.j2 new file mode 100644 index 0000000..00e3945 --- /dev/null +++ b/roles/haproxy/templates/haproxy/finish.j2 @@ -0,0 +1,13 @@ +#!/usr/local/bin/execlineb -S2 +# {{ ansible_managed }} + +s6-envdir ./env +multisubstitute { + importas -i -u NAME NAME +} + +fdmove -c 1 2 +ifelse { test "${1}" -eq 0 } { + echo "${NAME}: Stopped." +} + echo "${NAME}: Failed with exit status (${1}, ${2})." diff --git a/roles/haproxy/templates/haproxy/run.j2 b/roles/haproxy/templates/haproxy/run.j2 new file mode 100644 index 0000000..dd5ec09 --- /dev/null +++ b/roles/haproxy/templates/haproxy/run.j2 @@ -0,0 +1,13 @@ +#!/usr/local/bin/execlineb -P +# {{ ansible_managed }} + +s6-envdir ./env +multisubstitute { + importas -i -u NAME NAME +} + +foreground { fdmove -c 1 2 echo "${NAME}: Starting." } +s6-notifyoncheck -d -w 100 -n 70 + +fdmove -c 2 1 +haproxy -W -S /var/run/haproxy.master,uid,0,gid,0,mode,0600 -db -- /usr/local/etc/haproxy diff --git a/roles/haproxy/templates/http.cfg.j2 b/roles/haproxy/templates/http.cfg.j2 new file mode 100644 index 0000000..577e74a --- /dev/null +++ b/roles/haproxy/templates/http.cfg.j2 @@ -0,0 +1,6 @@ +frontend http + log global + bind ${BIND_V4}:80 + bind ${BIND_V6}:80 + use_backend %[req.hdr(host),lower,map(/usr/local/etc/haproxy/http.map)] + diff --git a/roles/haproxy/templates/http_host.cfg.j2 b/roles/haproxy/templates/http_host.cfg.j2 new file mode 100644 index 0000000..639f934 --- /dev/null +++ b/roles/haproxy/templates/http_host.cfg.j2 @@ -0,0 +1,4 @@ +# {{ ansible_managed }} + +backend http_{{ item.host }} + server {{ item.host }} {{ item.addr }}:{{ item.port | default("80") }} diff --git a/roles/haproxy/vars/main.yml b/roles/haproxy/vars/main.yml new file mode 100644 index 0000000..b73aa1d --- /dev/null +++ b/roles/haproxy/vars/main.yml @@ -0,0 +1,14 @@ +--- +haproxy_s6_dirs: + - haproxy-a + - haproxy-a/env + - haproxy-a/data + + - haproxy-b + - haproxy-b/env + - haproxy-b/data + +haproxy_s6_templates: + - run + - finish + - data/check