{"id":44315531,"url":"https://github.com/fccn/ansible-keepalived","last_synced_at":"2026-02-11T05:08:06.938Z","repository":{"id":335180603,"uuid":"1144652158","full_name":"fccn/ansible-keepalived","owner":"fccn","description":"An Ansible role to install and configure Keepalived for high availability (HA) virtual IP (VIP) management across Linux distributions.","archived":false,"fork":false,"pushed_at":"2026-01-28T22:32:35.000Z","size":17,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-29T13:43:53.368Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Jinja","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fccn.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-28T22:29:31.000Z","updated_at":"2026-01-28T22:32:39.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/fccn/ansible-keepalived","commit_stats":null,"previous_names":["fccn/ansible-keepalived"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/fccn/ansible-keepalived","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fccn%2Fansible-keepalived","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fccn%2Fansible-keepalived/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fccn%2Fansible-keepalived/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fccn%2Fansible-keepalived/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fccn","download_url":"https://codeload.github.com/fccn/ansible-keepalived/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fccn%2Fansible-keepalived/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29327111,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-11T03:52:29.695Z","status":"ssl_error","status_checked_at":"2026-02-11T03:52:23.094Z","response_time":97,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2026-02-11T05:08:06.878Z","updated_at":"2026-02-11T05:08:06.930Z","avatar_url":"https://github.com/fccn.png","language":"Jinja","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ansible Role: Keepalived\n\n[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)\n\nAn Ansible role to install and configure Keepalived for high availability (HA) virtual IP (VIP) management across Linux distributions.\n\n## Overview\n\nThis role installs and configures the Keepalived service, which provides load balancing and high availability through VRRP (Virtual Router Redundancy Protocol). It enables automatic failover of virtual IP addresses between nodes.\n\nThe examples demonstrate rolling deployments using the `keepalived_priority_override` variable to temporarily lower node priority, forcing VIPs to fail over to other nodes during maintenance or updates.\n\n## Use cases\n\n### Databases\nUse a VIP to connect to Database clusters, the clients use the VIP to connect instead of each specific node name/IP. When a database node is down, the clients are swapped to other node. For an intervention on one of the nodes, the Keepalived priority is changed, forcing the VIP node swap, and again, making the clients swap node gracefully.\n\n### Load Balancers\n\nIt can be used to configure a VIP on active-passive, or active-active load balancer configuration.\n\nThis pattern can be used on an active-passive layout or also more complicated for example 3 nodes with one or multiple VIPs.\n\n## Requirements\n\n- Ansible 2.9 or higher\n- Linux-based systems (Ubuntu, Debian, CentOS, RHEL)\n- Root or sudo access on target hosts\n\n## Role Variables\n\n### Required Variables\n\n- `keepalived_vrrp_instances` - List of VRRP instance configurations (see examples below)\n\n### Default Variables\n\nSee [defaults/main.yml](defaults/main.yml) for all available variables:\n\n- `keepalived_packages` - Package list to install (default: `[\"keepalived\"]`)\n- `keepalived_health` - Health check script configuration\n- `keepalived_connected_network_interface` - Auto-detected network interface\n- `keepalived_priority_override` - Temporary priority override for rolling deploys \n\n## Usage\n\n### Basic Playbook Example\n\n```yaml\n- name: Configure Keepalived\n  hosts: ha_servers\n  serial: 1  # Deploy sequentially to avoid disruption\n  become: true\n  roles:\n    - keepalived\n```\n\n### Rolling Deploy Pattern\n\nFor zero-downtime deployments, temporarily lower priority to force VIP failover:\n\n```yaml\n- name: Deploy with rolling VIP failover\n  hosts: service_servers\n  serial: 1\n  become: true\n  tasks:\n    - name: Lower keepalived priority to force VIP swap\n      import_role:\n        name: keepalived\n      vars:\n        keepalived_priority_override: 1\n      when: keepalived_vrrp_instances is defined\n\n    # Deploy your application updates here\n\n    - name: Restore keepalived priority\n      import_role:\n        name: keepalived\n      vars:\n        keepalived_priority_override: \"\"\n      when: keepalived_vrrp_instances is defined\n```\n\n## Configuration Examples\n\n### Simple Active-Passive Example (2 Nodes)\n\nFor a basic Redis failover setup:\n\n```yaml\nredis_keepalived_is_primary: \"{{ groups['redis_docker_servers'][0] == inventory_hostname }}\"\nredis_keepalived_state: \"{{ 'MASTER' if redis_keepalived_is_primary else 'BACKUP' }}\"\nredis_keepalived_peer_ipv4: \"{{ hostvars[ (groups['redis_docker_servers'] | difference([inventory_hostname]))[0] ].ansible_host }}\"\nredis_keepalived_priority: \"{{ 200 if redis_keepalived_is_primary else 100 }}\"\n\nredis_keepalived_vrrp_instances:\n  - name: redis_failover_link_ipv4\n    ipv6: false\n    state: \"{{ redis_keepalived_state }}\"\n    id: 41\n    priority: \"{{ keepalived_priority_override if ( keepalived_priority_override | default('') | string | length \u003e 0 ) else redis_keepalived_priority }}\"\n    pass: \"{{ redis_keepalived_pass }}\"\n    peer_ip: \"{{ redis_keepalived_peer_ipv4 }}\"\n    track_script: redis_chk_script\n    virtual_ip:\n      - \"{{ redis_virtual_ipv4 }}/24 dev {{ keepalived_connected_network_interface }} label vipRedis\"\n\nredis_keepalived_health:\n  - name: redis_chk_script\n    # Custom health check script\n    script: /usr/bin/make -C /nau/ops/redis/ --no-print-directory silent-healthcheck\n    timeout: 9\n    interval: 10\n    \n    # Or use a simple TCP port check:\n    # script: /usr/bin/nc -z 127.0.0.1 {{ redis_docker_port }}\n    # interval: 2\n    # timeout: 3\n```\n\n### Advanced Active-Active Example (4 VIPs, 2 Nodes)\n\nConfiguration for load balancers with dual-stack IPv4/IPv6 and active-active setup:\n\n**Inventory:**\n\n```ini\n[balancer_servers]\nlb01-qa.nau.fccn.pt  ansible_host=172.XX.1.XX ansible_public_ipv4=193.136.192.175 ansible_public_ipv6=2001:690:a00:4001::175\nlb02-qa.nau.fccn.pt  ansible_host=172.XX.1.YY ansible_public_ipv4=193.136.192.176 ansible_public_ipv6=2001:690:a00:4001::176\n```\n\n**Variables:**\n\n```yaml\n# VIP Configuration\nbalancer_virtual_ipv4_1: \"193.136.192.180\"\nbalancer_virtual_ipv6_1: \"2001:690:a00:4001::180\"\nbalancer_virtual_ipv4_2: \"193.136.192.183\"\nbalancer_virtual_ipv6_2: \"2001:690:a00:4001::183\"\n\n# Keepalived VRRP Instances (4 VIPs: 2 IPv4 + 2 IPv6)\n# VIP1 is MASTER on node 1, BACKUP on node 2\n# VIP2 is MASTER on node 2, BACKUP on node 1\nbalancer_keepalived_vrrp_instances:\n  - name: failover_link_ipv4_1\n    ipv6: false\n    state: \"{{ balancer_keepalived_state_1 }}\"\n    id: 41\n    priority: \"{{ keepalived_priority_override if ( keepalived_priority_override | default('') | string | length \u003e 0 ) else balancer_keepalived_priority_1 }}\"\n    pass: CHANGEME1\n    peer_ip: \"{{ balancer_keepalived_peer_ipv4 }}\"\n    unicast_src_ip: \"{{ ansible_public_ipv4 }}\"\n    track_script: chk_script\n    virtual_ip:\n      - \"{{ balancer_virtual_ipv4_1 }}/24 dev eth0 label vipLB1\"\n      \n  - name: failover_link_ipv6_1\n    ipv6: true\n    state: \"{{ balancer_keepalived_state_1 }}\"\n    id: 61\n    priority: \"{{ keepalived_priority_override if ( keepalived_priority_override | default('') | string | length \u003e 0 ) else balancer_keepalived_priority_1 }}\"\n    pass: CHANGEME2\n    peer_ip: \"{{ balancer_keepalived_peer_ipv6 }}\"\n    unicast_src_ip: \"{{ ansible_public_ipv6 }}\"\n    track_script: chk_script\n    virtual_ip:\n      - \"{{ balancer_virtual_ipv6_1 }}/64 dev eth0 label vipLB1\"\n\n  - name: failover_link_ipv4_2\n    ipv6: false\n    state: \"{{ balancer_keepalived_state_2 }}\"\n    id: 44\n    priority: \"{{ keepalived_priority_override if ( keepalived_priority_override | default('') | string | length \u003e 0 ) else balancer_keepalived_priority_2 }}\"\n    pass: CHANGEME3\n    peer_ip: \"{{ balancer_keepalived_peer_ipv4 }}\"\n    unicast_src_ip: \"{{ ansible_public_ipv4 }}\"\n    track_script: chk_script\n    virtual_ip:\n      - \"{{ balancer_virtual_ipv4_2 }}/24 dev eth0 label vipLB2\"\n      \n  - name: failover_link_ipv6_2\n    ipv6: true\n    state: \"{{ balancer_keepalived_state_2 }}\"\n    id: 62\n    priority: \"{{ keepalived_priority_override if ( keepalived_priority_override | default('') | string | length \u003e 0 ) else balancer_keepalived_priority_2 }}\"\n    pass: CHANGEME4\n    peer_ip: \"{{ balancer_keepalived_peer_ipv6 }}\"\n    unicast_src_ip: \"{{ ansible_public_ipv6 }}\"\n    track_script: chk_script\n    virtual_ip:\n      - \"{{ balancer_virtual_ipv6_2 }}/64 dev eth0 label vipLB2\"\n\n# State and Priority Logic\nbalancer_keepalived_state_1: \"{{ 'MASTER' if ( groups['balancer_servers'][0] == inventory_hostname ) else 'BACKUP' }}\"\nbalancer_keepalived_state_2: \"{{ 'MASTER' if ( groups['balancer_servers'][1] == inventory_hostname ) else 'BACKUP' }}\"\nbalancer_keepalived_peer_ipv4: \"{{ hostvars[ (groups['balancer_servers'] | difference([inventory_hostname]))[0] ].ansible_public_ipv4 }}\"\nbalancer_keepalived_peer_ipv6: \"{{ hostvars[ (groups['balancer_servers'] | difference([inventory_hostname]))[0] ].ansible_public_ipv6 }}\"\nbalancer_keepalived_priority_1: \"{{ 200 if ( groups['balancer_servers'][0] == inventory_hostname ) else 100 }}\"\nbalancer_keepalived_priority_2: \"{{ 200 if ( groups['balancer_servers'][1] == inventory_hostname ) else 100 }}\"\n\n# Health Check\nkeepalived_health:\n  - name: chk_script\n    script: /usr/bin/nc -z -w 5 127.0.0.1 80\n    interval: 2\n    timeout: 3\n```\n\n### Multi-Service VIP Configuration Pattern\n\nFor environments with multiple services each requiring their own VIPs, aggregate configurations:\n\n```yaml\n# Aggregate all VRRP instances from different services\nkeepalived_vrrp_instances: \"{{\n  ( balancer_keepalived_vrrp_instances  | default([]) ) +\n  ( redis_keepalived_vrrp_instances  | default([]) ) +\n  ( elasticsearch_keepalived_vrrp_instances  | default([]) ) +\n  ( richie_mysql_keepalived_vrrp_instances | default([]) ) +\n  ( openedx_mysql_read_replica_keepalived_vrrp_instances | default([]) ) +\n  ( xtradb_keepalived_vrrp_instances | default([]) ) +\n  ( clickhouse_keepalived_vrrp_instances | default([]) ) +\n  []\n}}\"\n\n# Aggregate all health checks\nkeepalived_health: \"{{\n  ( balancer_keepalived_health | default([]) ) +\n  ( redis_keepalived_health | default([]) ) +\n  ( elasticsearch_keepalived_health | default([]) ) +\n  ( richie_mysql_keepalived_health | default([]) ) +\n  ( openedx_mysql_read_replica_keepalived_health | default([]) ) +\n  ( xtradb_keepalived_health | default([]) ) +\n  ( clickhouse_keepalived_health | default([]) ) +\n  []\n}}\"\n```\n\nThen define service-specific variables in each `group_vars/\u003cservice\u003e_servers.yml` file.\n\n## Important Notes\n\n### Serial Deployment\n\n**Critical:** Always use `serial: 1` (or small numbers) when running playbooks that modify Keepalived configuration to prevent simultaneous priority changes that could cause service disruption:\n\n```yaml\n- name: Deploy with Keepalived\n  hosts: ha_servers\n  serial: \"{{ serial_number | default(1) }}\"\n  become: true\n  gather_facts: true\n  # ...\n```\n\n### VRRP Instance IDs\n\nEnsure VRRP instance IDs (`id:` parameter) are unique across all instances on the same network segment to avoid conflicts.\n\n### Health Checks\n\nHealth check scripts should exit with:\n- `0` - Service is healthy\n- Non-zero - Service is unhealthy (triggers failover)\n\n## Dependencies\n\nNone.\n\n\n## Installation\n\nOn `requirements.yml` file add:\n\n```yaml\nroles:\n- src: git+https://github.com/fccn/ansible-keepalived.git\n  version: \u003chash\u003e\n```\n\nThen install using:\n```bash\nansible-galaxy install -p vendor/roles -r requirements.yml\n```\n\nAlternatively install it using git submodules.\n\ngit submodule add https://github.com/fccn/ansible-docker-deploy.git\n\n## License\n\n[GNU General Public License v3.0](LICENSE)\n\n## Author Information\n\nCreated and maintained by **Ivo Branco** at [FCCN](https://www.fccn.pt/).\n\n## Contributing\n\nContributions are welcome! Please open an issue or submit a pull request.\n\n---\n\n**Repository**: [fccn/ansible-keepalived](https://github.com/fccn/ansible-keepalived)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffccn%2Fansible-keepalived","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffccn%2Fansible-keepalived","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffccn%2Fansible-keepalived/lists"}