{"id":19647877,"url":"https://github.com/nl2go/ansible-role-hetzner-failover","last_synced_at":"2025-07-03T20:32:35.466Z","repository":{"id":101457587,"uuid":"240535315","full_name":"nl2go/ansible-role-hetzner-failover","owner":"nl2go","description":"Ansible role providing a HA setup using hetzner vSwitch and keepalived","archived":false,"fork":false,"pushed_at":"2020-05-04T14:33:50.000Z","size":74,"stargazers_count":9,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-30T16:35:27.660Z","etag":null,"topics":["ansible","ansible-role","failover-ip","hetzner","keepalived","molecule"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nl2go.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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":"2020-02-14T15:10:10.000Z","updated_at":"2024-06-18T18:16:16.000Z","dependencies_parsed_at":null,"dependency_job_id":"f604ddc3-7cd0-46f5-a6bd-1f0be8f106f5","html_url":"https://github.com/nl2go/ansible-role-hetzner-failover","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/nl2go/ansible-role-hetzner-failover","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nl2go%2Fansible-role-hetzner-failover","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nl2go%2Fansible-role-hetzner-failover/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nl2go%2Fansible-role-hetzner-failover/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nl2go%2Fansible-role-hetzner-failover/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nl2go","download_url":"https://codeload.github.com/nl2go/ansible-role-hetzner-failover/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nl2go%2Fansible-role-hetzner-failover/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263399669,"owners_count":23460741,"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-role","failover-ip","hetzner","keepalived","molecule"],"created_at":"2024-11-11T14:46:17.959Z","updated_at":"2025-07-03T20:32:35.444Z","avatar_url":"https://github.com/nl2go.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.com/nl2go/ansible-role-hetzner-failover.svg?branch=master)](https://travis-ci.com/nl2go/ansible-role-hetzner-failover)\n[![Ansible Galaxy](https://img.shields.io/badge/role-nl2go.hetzner_failover-blue.svg)](https://galaxy.ansible.com/nl2go/hetzner_failover/)\n[![GitHub tag (latest by date)](https://img.shields.io/github/v/tag/nl2go/ansible-role-hetzner-failover)](https://galaxy.ansible.com/nl2go/hetzner_failover)\n[![Ansible Galaxy Downloads](https://img.shields.io/ansible/role/d/46553.svg?color=blue)](https://galaxy.ansible.com/nl2go/hetzner_failover/)\n\n# Ansible Role: Hetzner failover using a vSwitch and keepalived\n\nAn Ansible Role that was inspired by [an article about hetzner failover](https://dtone.engineering/2019/from_failovers_to_keepalived_over_vswitches_with_hetzner/) by @dtone. It aims to deploy a highly available setup of 2 servers sharing a single IP by utilizing [hetzner vSwitch](https://wiki.hetzner.de/index.php/Vswitch/en) and keepalived. The role should be used together with the [nl2go vSwitch role](https://github.com/nl2go/ansible-role-hetzner-vswitch) for setting up the vSwitch. It needs an extra IP subnet with public IP adresses to be ordered for the configured vSwitch. The role does *NOT* utilize the failover IP service provided by hetzner.\n\n## Prerequisites\n\n- Existing [Hetzner Online GmbH Account](https://accounts.hetzner.com).\n- Configured [Hetzner Robot Webservice Account](https://robot.your-server.de/preferences).\n\n## Configuration\n\nThe following configuration fragments show the setup of a vSwitch named failover with the vlan id `4023` using private adresses from the `192.168.100.0/24` subnet and the IP `154.222.4.34` from the additional IP subnet `154.222.4.32/29` as failover IP. The additional subnet has to be ordered manually after the vSwitch is created by the vSwitch role.\n\n### vSwitch configuration  \n\nvSwitch configuration according to the [vSwitch role](https://github.com/nl2go/ansible-role-hetzner-vswitch):\n\n```yaml\nhetzner_vswitch_instances:\n- name: failover\n    vlan: 4023\n    ipv4_address: 192.168.200.0\n    ipv4_netmask: 255.255.255.0\n```\n\n### keepalived configuration  \n\n```yaml\nhetzner_failover_keepalived_public_virtual_router_id: 42\n\nhetzner_failover_keepalived_public_ipaddress: 154.222.4.34 # single IP from the additional IP subnet used as failover IP\nhetzner_failover_keepalived_public_network_prefix: 29 # netmask prefix of the additional IP subnet\nhetzner_failover_keepalived_public_default_gateway: 154.222.4.33 # gateway IP of the additional IP subnet\n\nhetzner_failover_keepalived_vswich_id: 4023 # should match the vlan id configured in hetzner_vswitch_instances\n```\n\n### hosts configuration\n\n```yaml\nall:\n  hosts:\n    keepalived-test-1:\n      ansible_host: 123.124.125.1 # main IP of host 1\n      hetzner_vswitch_host:\n        - name: failover\n          ipv4_address: 192.168.200.1 # vSwitch IP of host 1\n      hetzner_failover_keepalived_state: MASTER\n      hetzner_failover_keepalived_vswitch_ip: 192.168.200.1 # IP of the host in the vSwitch VLAN has to be repeated here\n      hetzner_failover_keepalived_peer_ip: 192.168.200.2 # vSwitch IP of the host keepalived should peer with\n    keepalived-test-2:\n      ansible_host: 123.124.125.2 # main IP of host 2\n      hetzner_vswitch_host:\n        - name: failover\n          ipv4_address: 192.168.200.2 # vSwitch IP of host 2\n      hetzner_failover_keepalived_state: BACKUP\n      hetzner_failover_keepalived_vswitch_ip: 192.168.200.2 # IP of the host in the vSwitch VLAN has to be repeated here\n      hetzner_failover_keepalived_peer_ip: 192.168.200.1 # vSwitch IP of the host keepalived should peer with\n```\n### Notify Script\n\nCustom notify script may be utilized to perform additional actions after the failover.\n\n```yaml\nhetzner_failover_keepalived_notify_script: /usr/local/bin/keepalived_notify.sh\n```\n\nTo run custom notify script specify the script path within the `hetzner_failover_keepalived_notify_script` variable.\n\n```yaml\nhetzner_failover_keepalived_notify_script_master:\n  - service foo reload\n```\n\nTo perform additional actions on the instance switching to the master state without overriding the whole notify script use \n`hetzner_failover_keepalived_notify_script_master` variable.\n\n```yaml\nhetzner_failover_keepalived_notify_script_backup:\n  - service foo reload\n```\n\nTo perform additional actions on the instance switching to the backup state without overriding the whole notify script use\n`hetzner_failover_keepalived_notify_script_backup` variable.\n\n## Dependencies\n\n- [ansible-role-hetzner-vswitch](https://github.com/nl2go/ansible-role-hetzner-vswitch)\n\n## Example Playbook\n\n```yaml\n- hosts: all\n  roles:\n    - nl2go.hetzner_vswitch\n    - nl2go.hetzner_failover\n```\n\n## Development\n\nUse [docker-molecule](https://github.com/nl2go/docker-molecule) following the instructions to run [Molecule](https://molecule.readthedocs.io/en/stable/)\nor install [Molecule](https://molecule.readthedocs.io/en/stable/) locally (not recommended, version conflicts might appear).\n\nProvide Hetzner Cloud token:\n\n    export HCLOUD_TOKEN=123abc456efg\n\nUse following to run tests:\n\n    molecule test --all\n\n## Maintainers\n\n- [dirkaholic](https://github.com/dirkaholic)\n\n## License\n\nSee the [LICENSE.md](LICENSE.md) file for details.\n\n## Author Information\n\nThis role was created by in 2020 by [Newsletter2Go GmbH](https://www.newsletter2go.com/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnl2go%2Fansible-role-hetzner-failover","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnl2go%2Fansible-role-hetzner-failover","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnl2go%2Fansible-role-hetzner-failover/lists"}