{"id":15140796,"url":"https://github.com/uoi-io/ansible-haproxy","last_synced_at":"2025-04-05T21:09:44.959Z","repository":{"id":5317201,"uuid":"51856878","full_name":"uoi-io/ansible-haproxy","owner":"uoi-io","description":"Ansible HAproxy role for Unified OpenStack Installer and others.","archived":false,"fork":false,"pushed_at":"2025-03-03T16:56:58.000Z","size":179,"stargazers_count":44,"open_issues_count":1,"forks_count":53,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-29T20:08:04.960Z","etag":null,"topics":["ansible","ansible-playbook","galaxy","haproxy","load-balancer","loadbalancer","loadbalancing","molecule","playbook","role"],"latest_commit_sha":null,"homepage":"https://smartgic.io","language":"Jinja","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/uoi-io.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-02-16T18:06:19.000Z","updated_at":"2025-03-03T16:57:02.000Z","dependencies_parsed_at":"2024-05-10T14:41:14.912Z","dependency_job_id":"1120ece2-6f53-420e-9407-2f9c750b7e06","html_url":"https://github.com/uoi-io/ansible-haproxy","commit_stats":{"total_commits":163,"total_committers":36,"mean_commits":4.527777777777778,"dds":0.8466257668711656,"last_synced_commit":"88604dc16382275bc28ba39a0b67581d2e0ec698"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uoi-io%2Fansible-haproxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uoi-io%2Fansible-haproxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uoi-io%2Fansible-haproxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uoi-io%2Fansible-haproxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/uoi-io","download_url":"https://codeload.github.com/uoi-io/ansible-haproxy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247399879,"owners_count":20932880,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ansible","ansible-playbook","galaxy","haproxy","load-balancer","loadbalancer","loadbalancing","molecule","playbook","role"],"created_at":"2024-09-26T08:41:23.044Z","updated_at":"2025-04-05T21:09:44.939Z","avatar_url":"https://github.com/uoi-io.png","language":"Jinja","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ansible HAproxy (OpenStack ready)\n\n[![CI](https://github.com/uoi-io/ansible-haproxy/actions/workflows/ci.yml/badge.svg)](https://github.com/uoi-io/ansible-haproxy/actions/workflows/ci.yml) [![Ansible Galaxy](https://img.shields.io/badge/galaxy-uoi.haproxy-green.svg?style=flat)](https://galaxy.ansible.com/uoi-io/haproxy/)\n\nThis role provides support for the installation of HAproxy on current distributions:\n\n- Rocky Linux **8** / **9**\n- Fedora **37** / **38** / **39**\n- Debian **10** / **11** / **12**\n- Ubuntu **18.04** / **20.04** / **22.04**\n\nThe role allows you to configure multiple sections of HAproxy:\n\n- Global section\n- Default section\n- Listen section\n- Frontend section\n- Backend section\n- Peer section\n- Stats section\n\n## Requirements\n\nThis role requires at least HAproxy **1.5** _(SSL native support)_ and Ansible **2.8**.\n\n## Role Variables\n\nThere are no variables in the `vars` directory, all variables can be override via the playbook.\n\nEmpty variable like `haproxy_global_uid` wills appears in the `/etc/haproxy/haproxy.cfg` only if a value is define.\n\nVariable like `haproxy_global_stats: []` are arrays, in this example, the array is empty. This variable can be declare in two different ways:\n\n```yaml\nhaproxy_global_stats:\n  - show-legends\n  - show-node\n  - refresh 20s\n```\n\n```yaml\n# file: roles/haproxy/defaults/main.yml\n# Sysctl\nhaproxy_bind_nonlocal_ip: true\nhaproxy_ip_forward: true\n\n# Common\nhaproxy_mode: system  # or docker\nhaproxy_firewalld: true\nhaproxy_selinux: true\nhaproxy_apt_backports: false\n# default value for macOS \u0026 Docker; overridden in `vars/{{ ansible_os_family }}.yml`\nhaproxy_errors_directory: /usr/local/etc/haproxy/errors\n\n# Package customizations\nhaproxy_package: haproxy\nhaproxy_selinux_packages:\n  - python3-libselinux\n  - python3-policycoreutils\nhaproxy_service: haproxy\nhaproxy_bin: haproxy\nhaproxy_config: /etc/haproxy/haproxy.cfg\n\n# Firewall\nhaproxy_fw_ports:\n  - \"{{ haproxy_stats_port }}/tcp\"\n\n# Global\nhaproxy_global_maxconn: 4000\nhaproxy_global_chroot: /var/lib/haproxy\nhaproxy_global_group: haproxy\nhaproxy_global_user: haproxy\nhaproxy_global_uid:\nhaproxy_global_gid:\nhaproxy_global_pidfile: /var/run/haproxy.pid\nhaproxy_global_ca_base:\nhaproxy_global_crt_base:\nhaproxy_global_ssl_bind_options:\nhaproxy_global_ssl_bind_ciphers:\nhaproxy_global_ssl_bind_ciphersuites:\nhaproxy_global_ssl_server_options:\nhaproxy_global_ssl_server_ciphers:\nhaproxy_global_ssl_server_ciphersuites:\nhaproxy_global_ssl_server_verify:\nhaproxy_global_stats: []\nhaproxy_global_description:\nhaproxy_global_ulimit_n:\nhaproxy_global_logs:\n  - 127.0.0.1    local0 debug\nhaproxy_global_daemon: true\n# nbproc is deprecated. Will be removed in version 2.5\n# haproxy_global_nbproc: 8\n# haproxy_global_cpu_maps: [ 1 0, 2 1, 3 2, 4 3, 5 4, 6 5, 7 6, 8 7 ]\nhaproxy_global_tunes:\n  - tune.ssl.default-dh-param: 2048\n\n# Default\nhaproxy_default_logs:\n  - global\nhaproxy_default_log_format:\nhaproxy_default_mode:\nhaproxy_default_maxconn: 4000\nhaproxy_default_options:\n  - dontlognull\n  - forwardfor\n  - http-server-close\nhaproxy_default_retries: 3\nhaproxy_default_timeouts:\n  - http-request 10s\n  - queue 1m\n  - connect 10s\n  - client 1m\n  - server 1m\n  - http-keep-alive 10s\n  - check 10s\nhaproxy_default_balance:\nhaproxy_default_errorfiles:\n  - \"400 {{ haproxy_errors_directory }}/400.http\"\n  - \"403 {{ haproxy_errors_directory }}/403.http\"\nhaproxy_default_http_check:\nhaproxy_default_monitor_uri:\nhaproxy_default_unique_id_format:\n\n# Userlist\nhaproxy_userlist:\n  - stats-auth:\n      groups:\n        - \"admin users admin\"\n        - \"readonly users user\"\n      users:\n        - \"admin insecure-password opqrstuvw\"\n        - \"user insecure-password abcdefghi\"\n\n# Stats with HTTP Basic Auth and a single user\nhaproxy_stats: true\nhaproxy_stats_address: '*'\nhaproxy_stats_port: 9001\nhaproxy_stats_ssl: false\nhaproxy_stats_user: haproxy-stats\nhaproxy_stats_password: B1Gp4sSw0rD!!\nhaproxy_stats_uri: /\nhaproxy_stats_options:\n  - refresh 20s\n  - show-legends\n  - show-node\n  - hide-version\nhaproxy_stats_http_requests:\n  - use-service prometheus-exporter if { path /metrics }\nhaproxy_stats_listener_options:\n  - dontlog-normal\nhaproxy_stats_timeouts:\n  - client 100s\n  - server 100s\n  - connect 100s\n  - queue 100s\n\n# Stats with HTTP Basic Auth using an userlist\nhaproxy_stats: true\nhaproxy_stats_address: \"::\"\nhaproxy_stats_port: 8081\nhaproxy_stats_ssl: false\nhaproxy_stats_uri: /stats\nhaproxy_stats_auth:\nhaproxy_stats_acls:\n  - \"AUTH http_auth(stats-auth)\"\n  - \"AUTH_ADMIN http_auth_group(stats-auth) admin\"\nhaproxy_stats_options:\n  - refresh 5s\n  - show-legends\n  - show-node\n  - http-request auth unless AUTH\n  - admin if AUTH_ADMIN\n\n# SSL\nhaproxy_ssl_certificate: /etc/ssl/uoi.io/uoi.io.pem\nhaproxy_ssl_options: no-sslv3 no-tls-tickets force-tlsv12\nhaproxy_ssl_ciphers: AES128+EECDH:AES128+EDH\nhaproxy_ssl: 'ssl crt {{ haproxy_ssl_certificate }} ciphers {{ haproxy_ssl_ciphers }} {{ haproxy_ssl_options }}'\n\n## Certificate Storage\nhaproxy_certstore:\n  - web:\n      crt_base: /etc/ssl/\n      key_base: /etc/ssl/private/\n      load:\n        - crt \"example.com_fullchain.crt\" key \"example.com.key\" alias \"example_com\"\n  - internal:\n      crt_base: /etc/ssl/\n      key_base: /etc/ssl/private/\n      load:\n        - crt \"example.de_fullchain.crt\" key \"example.de.key\" alias \"example_de\"\n\nhaproxy_ssl: 'tfo ssl crt \"@web/example_com\" alpn h2,http/1.1 ssl-min-ver TLSv1.2'\n\n# Docker\n# see more details in `tasks/docker.yml` and https://docs.ansible.com/ansible/latest/collections/community/general/docker_container_module.html\nhaproxy_docker_name: \"haproxy\"\nhaproxy_docker_image: \"haproxy:alpine\"\nhaproxy_docker_network_mode: default\nhaproxy_docker_network_name: \"haproxy\"\nhaproxy_docker_pull: true\nhaproxy_docker_recreate: false\nhaproxy_docker_ports:\n  - \"8443:8443\"\n  - \"{{ haproxy_stats_port }}:{{ haproxy_stats_port }}\"\nhaproxy_docker_sysctls:\n  net.ipv4.ip_nonlocal_bind: \"{{ 1 if haproxy_bind_nonlocal_ip|bool else 0 }}\"\n  net.ipv4.ip_forward: \"{{ 1 if haproxy_ip_forward|bool else 0 }}\"\n  net.core.somaxconn: 4096\n  net.ipv4.tcp_syncookies: 1\nhaproxy_docker_ulimits:\n  - \"nofile:262144:262144\"\nhaproxy_docker_volumes:\n  - {{ haproxy_config }}+\":/usr/local/etc/haproxy/haproxy.cfg:ro\"\n```\n\n## Dependencies\n\nNone\n\n## Example Playbook\n\nThe below examples show you how to define `frontend`, `backend`, `listen`, `peer`.\n\n```yaml\n# Frontend\nhaproxy_frontend:\n  - dashboard_cluster:\n      binds_ssl:\n        - :443 ssl crt /etc/ssl/uoi.io/uoi.io.pem no-sslv3\n      reqadds:\n        - X-Forwarded-Proto:\\ https\n      default_backend: dashboard_backend\n      logs:\n        - 127.0.0.1 local0 debug\n      acls:\n        - url_static path_beg -i /static /images /javascript /stylesheets\n        - url_static path_end -i .jpg .gif .png .css .js\n      bind_process:\n        - 1\n      log_formats:\n        - \"%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r\"\n      use_backends:\n        - static if url_static\n      capture:\n        - request header Host len 64\n        - request header X-Forwarded-For len 64\n```\n\n```yaml\n# Backend\nhaproxy_backend:\n  - dashboard_backend:\n      balance: source\n      default_server: \"inter 2s downinter 5s rise 3 fall 2 slowstart 30s maxconn 30 maxqueue 64 weight 100\"\n      http_checks:\n        - 'send meth GET uri /check-haproxy.php hdr Host haproxy.check-vhost.de'\n        - 'expect string \"All services running fine\"'\n      bind_process:\n        - 1\n      server_templates:\n        - srv 3 service.local:80 check resolvers mydns init-addr none\n      servers:\n        - ctrl01 10.0.0.67:80 check inter 2000 rise 2 fall 5\n        - ctrl02 10.0.0.68:80 check inter 2000 rise 2 fall 5\n        - ctrl03 10.0.0.69:80 check inter 2000 rise 2 fall 5\n  - static:\n      balance: roundrobin\n      compression:\n        - algo gzip deflate\n        - type text/css text/html application/javascript\n      bind_process:\n        - 1\n      servers:\n        - cnd01 10.0.0.70:8080 check\n        - cnd02 10.0.0.71:8080 check\n        - cnd03 10.0.0.71:8080 check\n```\n\n```yaml\n# Listen\nhaproxy_listen:\n  - dashboard_cluster:\n      mode: http\n      description: Horizon Dashboard\n      balance: roundrobin\n      default_server: \"inter 2s downinter 5s rise 3 fall 2 slowstart 30s maxconn 30 maxqueue 64 weight 100\"\n      binds:\n        - 10.0.0.100:80\n      binds_ssl:\n        - :443 ssl crt /etc/ssl/uoi.io/uoi.io.pem no-sslv3\n      options: [ tcpka, httpchk, tcplog ]\n      http-check: GET /auth/login\n      cookie: SERVERID insert indirect nocache\n      capture:\n        - cookie SERVERID len 32\n      timeouts:\n        - client 90m\n        - server 90m\n      bind_process:\n        - 1\n      http_requests:\n        - set-header X-Haproxy-Current-Date %T\n      servers:\n        - ctrl01 10.0.0.67:80 check cookie ctrl01inter 2000 rise 2 fall 5\n        - ctrl02 10.0.0.68:80 check cookie ctrl02 inter 2000 rise 2 fall 5\n        - ctrl03 10.0.0.69:80 check cookie ctrl03 inter 2000 rise 2 fall 5\n\n  - neutron_api_cluster:\n      binds_ssl:\n        - 10.0.0.100:9696 {{ haproxy_ssl }}\n      options: [ tcpka, httpchk, tcplog ]\n      bind_process: [ 2, 3, 4, 5, 6, 7 ]\n      balance: source\n      servers:\n        - ctrl01 10.0.0.62:9696 check inter 2000 rise 2 fall 5\n        - ctrl02 10.0.0.63:9696 check inter 2000 rise 2 fall 5\n        - ctrl03 10.0.0.64:9696 check inter 2000 rise 2 fall 5\n```\n\n```yaml\n# Peer\nhaproxy_peer:\n  - remote_peers:\n      peers:\n        - lb223 10.0.0.223:1024\n        - lb224 10.0.0.224:1024\n        - lb225 10.0.0.225:1024\n```\n\n```yaml\n# Resolvers\nhaproxy_resolvers:\n  - mydns:\n      nameservers:\n        - 'dns1 10.0.0.1:53'\n        - 'dns3 tcp@10.0.0.3:53'\n      parse_resolv_conf: true\n      resolve_retries: 5\n      timeouts:\n        - 'resolve 1s'\n        - 'retry 1s'\n      holds:\n        - 'other 30s'\n        - 'refused 30s'\n        - 'nx 30s'\n        - 'valid 30s'\n```\n\n### Docker usage example\n\nHere is a short example how to use the role in another playbook and run HAProxy in Docker.\n\n```yaml\n# site.yml\n- hosts: haproxy\n  name: HAProxy load balancer\n  tags:\n    - all\n    - haproxy\n  # can be included either via `role` or `include_role`\n  # roles:\n  #   - uoi-io.haproxy\n  tasks:\n    - include_role:\n        name: uoi-io.haproxy\n```\n\n```yaml\n# (group_vars|environments/\u003cmy env\u003e/group_vars/haproxy.yml)\nhaproxy_mode: docker\nhaproxy_config: \"{{ docker_persistent_path }}/haproxy/haproxy.cfg\"\nhaproxy_firewalld: false\nhaproxy_selinux: false\n# Global\nhaproxy_global_chroot: \"\"\n# SSL\nhaproxy_ssl_certificate: /usr/local/etc/haproxy/ssl/haproxy.crt\n# Frontend\nhaproxy_frontend:\n  # ... frontend definition\n# Backend\nhaproxy_backend_checks: \"check inter 2000 rise 2 fall 5\"\nhaproxy_backend:\n  - my_backend:\n      # ... backend definition\n      # example that hosts can be dinamically linked based on another group\n      servers: |-\n        {%- set _list = [] %}\n        {%- for _host in groups['MY_BACKEND_GROUP'] %}\n          {%- set _list = _list.append(_host.split('.')[0] ~ ' ' ~ _host ~ ':' ~ MY_SERVICE_PORT ~ ' ' ~ haproxy_backend_checks) %}\n        {%- endfor %}\n        {{- _list }}\n# Docker\nhaproxy_docker_ports:\n  - \"6443:6443\"\n  - \"{{ haproxy_stats_port }}:{{ haproxy_stats_port }}\"\n# haproxy_docker_volumes: []\nhaproxy_docker_volumes:\n  - \"{{ haproxy_config }}:/usr/local/etc/haproxy/haproxy.cfg:ro\"\n  - \"{{ docker_persistent_path }}/haproxy/haproxy.key:/usr/local/etc/haproxy/ssl/haproxy.crt.key:ro\"\n  - \"{{ docker_persistent_path }}/haproxy/haproxy.crt:/usr/local/etc/haproxy/ssl/haproxy.crt:ro\"\n```\n\n## RedHat based repository\n\nIf you have own repository with HAProxy, you can install repo file.\nNext example will add repository with HAProxy 2 for CentOS 8\n\n```\n# Repository\nhaproxy_repo_yum:\n  - name: haproxy\n    description: HAProxy 2 repository - $basearch\n    baseurl: https://download.copr.fedorainfracloud.org/results/pzinchuk/haproxy/epel-8-$basearch/\n    priority: 1\n    gpgcheck: true\n    file: haproxy\n    repo_gpgcheck: false\n    skip_if_unavailable: true\n    gpgkey: https://download.copr.fedorainfracloud.org/results/pzinchuk/haproxy/pubkey.gpg\n    enabled: true\n    state: present\n```\n\n## Testing\n\nThis role is using [ansible molecule](https://molecule.readthedocs.io/).\nYou'll just need to install molecule via `pip` and run it.\nCurrently the molecule configuration is based on the `docker` driver.\n\n```console\napt/yum install docker\nsystemctl start docker\npip install docker molecule molecule-plugins pytest-testinfra\nmolecule test\n```\n\n## License\n\nApache\n\n## Author Information\n\nThis role was created in 2016 by Gaëtan Trellu (goldyfruit).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuoi-io%2Fansible-haproxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fuoi-io%2Fansible-haproxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuoi-io%2Fansible-haproxy/lists"}