global pidfile {{ configuration['pid-file'] }} # master-worker is compatible with foreground with process management master-worker log {{ configuration['log-socket'] }} local0 defaults log global mode http option httplog timeout queue 60s timeout server {{ configuration['request-timeout'] }}s timeout client {{ configuration['request-timeout'] }}s timeout connect {{ configuration['backend-connect-timeout'] }}s retries {{ configuration['backend-connect-retries'] }} {%- set SCHEME_PREFIX_MAPPING = { 'http': 'http_backend', 'https': 'https_backend'} %} {%- macro frontend_entry(slave_instance, scheme, wildcard) %} {#- wildcard switch allows to put dangerous entries in the end, as haproxy parses with first match #} {%- if slave_instance[SCHEME_PREFIX_MAPPING[scheme]]['hostname'] and slave_instance[SCHEME_PREFIX_MAPPING[scheme]]['port'] %} {%- set matched = {'count': 0} %} {%- for host in slave_instance['host_list'] %} {#- Match up to the end or optional port (starting with ':') #} {#- Please note that this matching is quite sensitive to changes and hard to test, so avoid needless changes #} {%- if wildcard and host.startswith('*.') %} {%- do matched.__setitem__('count', matched['count'] + 1) %} # match wildcard {{ host }} acl is_{{ slave_instance['slave_reference'] }} hdr_reg(host) -i {{ host[2:] }}($|:.*) {%- elif not wildcard and not host.startswith('*.') %} {%- do matched.__setitem__('count', matched['count'] + 1) %} acl is_{{ slave_instance['slave_reference'] }} hdr_reg(host) -i ^{{ host }}($|:.*) {%- endif %} {%- endfor %} {%- if matched['count'] > 0 %} use_backend {{ slave_instance['slave_reference'] }}-{{ scheme }} if is_{{ slave_instance['slave_reference'] }} {%- endif %} {%- endif %} {%- endmacro %} # statistic frontend statistic bind {{ configuration['global-ipv6']}}:{{ configuration['statistic-port'] }} ssl crt {{ configuration['statistic-certificate'] }} stats enable stats uri / stats show-desc {{ configuration['statistic-identification'] }} stats auth {{ configuration['statistic-username'] }}:{{ configuration['statistic-password'] }} stats realm {{ configuration['statistic-identification'] }} stats scope http-backend stats scope https-backend frontend http-backend bind {{ configuration['local-ipv4'] }}:{{ configuration['http-port'] }} {%- for slave_instance in backend_slave_list -%} {{ frontend_entry(slave_instance, 'http', False) }} {%- endfor %} {%- for slave_instance in backend_slave_list -%} {{ frontend_entry(slave_instance, 'http', True) }} {%- endfor %} frontend https-backend bind {{ configuration['local-ipv4'] }}:{{ configuration['https-port'] }} {%- for slave_instance in backend_slave_list -%} {{ frontend_entry(slave_instance, 'https', False) }} {%- endfor %} {%- for slave_instance in backend_slave_list -%} {{ frontend_entry(slave_instance, 'https', True) }} {%- endfor %} {%- for slave_instance in backend_slave_list %} {%- for (scheme, prefix) in SCHEME_PREFIX_MAPPING.items() %} {%- set info_dict = slave_instance[prefix] %} {%- if info_dict['hostname'] and info_dict['port'] %} {%- set ssl_list = [] %} {%- if info_dict['scheme'] == 'https' %} {%- if slave_instance['authenticate-to-backend'] %} {%- do ssl_list.append('crt %s' % (configuration['certificate'],)) %} {%- endif %} {%- do ssl_list.append('ssl verify') %} {%- if slave_instance['ssl_proxy_verify'] %} {%- if slave_instance['path_to_ssl_proxy_ca_crt'] %} {%- do ssl_list.append('required ca-file %s' % (slave_instance['path_to_ssl_proxy_ca_crt'],)) %} {%- else %} {#- Backend SSL shall be verified, but not CA provided, disallow connection #} {#- Simply dropping hostname from the dict will result with ignoring it... #} {%- do info_dict.__setitem__('hostname', '') %} {%- endif %} {%- else %} {%- do ssl_list.append('none') %} {%- endif %} {%- endif %} backend {{ slave_instance['slave_reference'] }}-{{ scheme }} {%- set hostname = info_dict['hostname'] %} {%- set port = info_dict['port'] %} {%- set path_list = [info_dict['path'].rstrip('/')] %} {%- set query = info_dict['query'] %} {%- if query %} {%- do path_list.append(query) %} {%- endif %} {%- set path = '?'.join(path_list) %} {%- if hostname and port %} timeout server {{ slave_instance['request-timeout'] }}s timeout connect {{ slave_instance['backend-connect-timeout'] }}s retries {{ slave_instance['backend-connect-retries'] }} {%- set active_check_list = [] %} {%- set active_check_option_list = [] %} {%- if slave_instance['backend-active-check'] %} {%- do active_check_list.append('check') %} {%- do active_check_list.append('inter %ss' % (slave_instance['backend-active-check-interval'])) %} {%- do active_check_list.append('rise %s' % (slave_instance['backend-active-check-rise'])) %} {%- do active_check_list.append('fall %s' % (slave_instance['backend-active-check-fall'])) %} {%- if slave_instance['backend-active-check-http-method'] != 'CONNECT' %} {%- do active_check_option_list.append('option httpchk %s %s %s' % (slave_instance['backend-active-check-http-method'], slave_instance['backend-active-check-http-path'] | urlencode, slave_instance['backend-active-check-http-version'])) %} {%- endif %} {%- do active_check_option_list.append('timeout check %ss' % (slave_instance['backend-active-check-timeout'])) %} {%- endif %} server {{ slave_instance['slave_reference'] }}-backend {{ hostname }}:{{ port }} {{ ' '.join(ssl_list) }} {{ ' ' + ' '.join(active_check_list)}} {%- for active_check_option in active_check_option_list %} {{ active_check_option }} {%- endfor %} {%- if path %} http-request set-path {{ path }}%[path] {%- endif %} {%- endif %} {%- endif %} {%- endfor %} {%- endfor %}