diff --git a/playbook3_haproxy.yml b/playbook3_haproxy.yml new file mode 100644 index 0000000..00fa849 --- /dev/null +++ b/playbook3_haproxy.yml @@ -0,0 +1,136 @@ +--- +- name: Configure HAProxy Load Balancer + hosts: proxy + become: true + vars: + vip_address: "172.16.1.253" + backend_servers: "{{ groups['server'] }}" + backend_port: 443 + stats_port: 9000 + stats_uri: "/haproxy_stats" + stats_realm: "HAProxy Statistics" + stats_user: "admin" + stats_password: "haproxy_secure_pass" + ssl_cert_path: "/etc/haproxy/ssl/www.au.team.pem" + server_name: "www.au.team" + + tasks: + - name: Install HAProxy package + ansible.builtin.apt: + name: haproxy + state: present + update_cache: true + tags: haproxy + + - name: Create SSL directory for HAProxy + ansible.builtin.file: + path: /etc/haproxy/ssl + state: directory + mode: '0755' + owner: root + group: root + tags: ssl + + - name: Generate combined PEM certificate for HAProxy + ansible.builtin.shell: | + cat /etc/angie/ssl/www.au.team.crt /etc/angie/ssl/www.au.team.key > {{ ssl_cert_path }} + chmod 600 {{ ssl_cert_path }} + args: + creates: "{{ ssl_cert_path }}" + tags: ssl + + - name: Configure HAProxy with SSL termination and roundrobin + ansible.builtin.template: + content: | + global + log /dev/log local0 + log /dev/log local1 notice + chroot /var/lib/haproxy + stats socket /run/haproxy/admin.sock mode 660 level admin + stats timeout 30s + user haproxy + group haproxy + daemon + ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-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 ssl-min-ver TLSv1.2 no-tls-tickets + + defaults + log global + mode http + option httplog + option dontlognull + timeout connect 5000 + timeout client 50000 + timeout server 50000 + 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 + + # Frontend: HTTPS with SNI support + frontend https_front + bind {{ vip_address }}:443 ssl crt {{ ssl_cert_path }} alpn h2,http/1.1 + bind {{ vip_address }}:80 + server_name {{ server_name }} + + # HTTP to HTTPS redirect + http-request redirect scheme https unless { ssl_fc } + + # HSTS header + http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains" + + # ACL for stats + acl is_stats path_beg {{ stats_uri }} + use_backend stats_backend if is_stats + + default_backend web_backend + + # Backend: Web servers with roundrobin + backend web_backend + balance roundrobin + option httpchk GET / HTTP/1.1\r\nHost:\ {{ server_name }} + http-check expect status 200 + {% for server in backend_servers %} + server {{ server }} {{ hostvars[server]['ansible_host'] | default(server) }}:{{ backend_port }} check ssl verify none + {% endfor %} + + # Stats backend + backend stats_backend + stats enable + stats uri {{ stats_uri }} + stats realm {{ stats_realm }} + stats auth {{ stats_user }}:{{ stats_password }} + stats admin if TRUE + dest: /etc/haproxy/haproxy.cfg + mode: '0644' + backup: true + validate: "haproxy -c -f %s" + notify: Reload haproxy + tags: haproxy + + - name: Add www.au.team to /etc/hosts for local resolution + ansible.builtin.lineinfile: + path: /etc/hosts + regexp: '^127\.0\.1\.1\s+www\.au\.team' + line: "127.0.1.1 {{ server_name }}" + state: present + tags: dns + + - name: Enable and start HAProxy service + ansible.builtin.systemd: + name: haproxy + enabled: true + state: started + daemon_reload: true + tags: haproxy + + handlers: + - name: Reload haproxy + ansible.builtin.systemd: + name: haproxy + state: reloaded + daemon_reload: true \ No newline at end of file