Building a load balanced Ansible Tower cluster

Posted on vr 09 juli 2021 in ansible

Load balancing Ansible Tower cluster

As you might know, I do a bit of YouTubing. One video request I got a couple of times, was to do a video about clustering Ansible Tower behind a load balancer.

As I had never done that before myself, it sounded interesting, so I did it.

Video is here:

In the video, I use a playbook that I promised to put up somewhere, so here it is:

---
- name: configure Tower cluster
  hosts: tower
  become: yes
  vars:
    custom_config: |
      BROADCAST_WEBSOCKET_PROTOCOL = 'http'
      BROADCAST_WEBSOCKET_PORT = 80
      USE_X_FORWARDED_PORT = True
      USE_X_FORWARDED_HOST = True
    tower_base_url: http://main.nontoonyt.lan
    proxy_ip_allowed_list:
      - 192.168.122.8
    remote_host_headers:
      - HTTP_X_FORWARDED_FOR
      - REMOTE_ADDR
      - REMOTE_HOST
    tower_username: admin
    tower_password: redhat123

  tasks:
    # https://access.redhat.com/solutions/5228651 and
    # https://docs.ansible.com/ansible-tower/3.8.3/html/installandreference/proxy-support.html
    - name: drop in configuration file for web sockets over port 80
      ansible.builtin.copy:
        content: "{{ custom_config }}"
        dest: /etc/tower/conf.d/custom.py
        mode: 0640
        owner: root
        group: awx
      notify: restart ansible-tower

    - name: configure tower remote host headers
      ansible.tower.tower_settings:
        name: REMOTE_HOST_HEADERS
        value: "{{ remote_host_headers }}"
        tower_host: http://127.0.0.1
        tower_username: "{{ tower_username }}"
        tower_password: "{{ tower_password }}"
      run_once: yes

    - name: configure proxy ip allowed list
      ansible.tower.tower_settings:
        name: PROXY_IP_ALLOWED_LIST
        value: "{{ proxy_ip_allowed_list }}"
        tower_host: http://127.0.0.1
        tower_username: "{{ tower_username }}"
        tower_password: "{{ tower_password }}"
      run_once: yes

    - name: configure tower base url
      ansible.tower.tower_settings:
        name: TOWER_URL_BASE
        value: "{{ tower_base_url }}"
        tower_host: http://127.0.0.1
        tower_username: "{{ tower_username }}"
        tower_password: "{{ tower_password }}"
      run_once: yes

  handlers:
    - name: restart ansible-tower
      ansible.builtin.service:
        name: ansible-tower
        state: restarted

Same goes for the haproxy configuration file I use to set this up:

global
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    user        haproxy
    group       haproxy
    daemon
    tune.ssl.default-dh-param 2048

    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats

#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
    mode                    http
    option                  redispatch
    option                  contstats
    retries                 3
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    option                  forwardfor

#---------------------------------------------------------------------

listen stats
    bind :9000
    mode http
    option forwardfor       except 127.0.0.0/8
    stats enable
    stats uri /
    stats refresh 3s

frontend tower_fe
    bind *:443 ssl crt /etc/haproxy/haproxy.pem
    default_backend tower_be

backend tower_be
    balance roundrobin
    server tower1_http 192.168.122.161:80 maxconn 100 check weight 6
    server tower2_http 192.168.122.201:80 maxconn 100 check weight 1
    server tower3_http 192.168.122.144:80 maxconn 100 check weight 1
    server tower4_http 192.168.122.80:80  maxconn 100 check weight 1
    server tower5_http 192.168.122.89:80  maxconn 100 check weight 1

If you do this installation, make sure you initiate the Tower installation with:

./setup.sh -e nginx_disable_https=true -- -b

Check out the video if you want to learn more!

Cheers!