From 00e8f234e4ee45508197df1ed2dd14f8c6264508 Mon Sep 17 00:00:00 2001 From: "pulsar89.5" Date: Wed, 12 Apr 2023 14:09:46 +0200 Subject: [PATCH] feat: Create role --- README.md | 165 ++++++++++++++++++++++++++++++++++++++- defaults/main.yml | 34 ++++++++ handlers/main.yml | 8 ++ meta/main.yml | 5 +- tasks/configuration.yml | 37 +++++++++ tasks/installation.yml | 7 ++ tasks/main.yml | 10 +++ templates/keepalived.j2 | 86 ++++++++++++++++++++ templates/notify.bash.j2 | 38 +++++++++ templates/sudoers.j2 | 5 ++ vars/main.yml | 9 +++ 11 files changed, 400 insertions(+), 4 deletions(-) create mode 100644 defaults/main.yml create mode 100644 handlers/main.yml create mode 100644 tasks/configuration.yml create mode 100644 tasks/installation.yml create mode 100644 tasks/main.yml create mode 100644 templates/keepalived.j2 create mode 100644 templates/notify.bash.j2 create mode 100644 templates/sudoers.j2 create mode 100644 vars/main.yml diff --git a/README.md b/README.md index 3edfbf7..32eb8ae 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,164 @@ -# role_modele +# role_keepalived -Modèle \ No newline at end of file +Rôle de déploiement de keepalived. + +## Dépendance + +Le rôle *users* est requis afin que l'utilisateur dédié exécutant les scripts définis via `keepalived_track_scripts` soit créé. + +## Variables + +### keepalived_uid + +Identifiant unique permettant d'identifer les membres. + +*Valeur par défaut: aucune* + +### keepalived_priority + +Priorité de la machine pour prendre l'IP de failover.
+Ce chiffre doit être différent sur chaque machine portant le même identifiant unique. + +*Valeur par défaut: aucune* + +### keepalived_interface + +Interface sur laquelle l'IP de failover sera montée. + +*Valeur par défaut: aucune* + +### keepalived_mail_to + +Adresse mail sur laquelle envoyer les alertes. + +*Valeur par défaut: aucune* + +### keepalived_mail_from + +Adresse mail source depuis laquelle partent les alertes.
+Le serveur d'envoi (smtp) est défini par défaut sur localhost. + +*Valeur par défaut: aucune* + +### keepalived_ipv4 + +Adresse IPv4 de failover. + +*Valeur par défaut: aucune* + +### keepalived_ipv6 + +Adresse IPv6 de failover. + +*Valeur par défaut: aucune* + +### keepalived_peers + +Passer en unicast en utilisant cette liste d'IP. + +*Valeur par défaut: aucune* + +### keepalived_notify_script_enabled + +Booléen permettant d'activer le script de notification.
+Le script est déployé dans `/etc/keepalived/notify.sh`. + +*Valeur par défaut: `false`* + +### keepalived_track_scripts + +Liste de script dont le code retour doit être à zéro pour que le membre conserve ou puisse prendre l'IP de failover. + +*Valeur par défaut: aucune* + +### keepalived_track_processes + +Liste de processus devant fonctionner pour que le membre conserve ou puisse prendre l'IP de failover. + +*Valeur par défaut: aucune* + +## Exemples + +Dans les exemples ci-dessous, j'utilise aussi le rôle *nftables* afin d'installer et configurer le pare-feu logiciel éponyme. + +### host_vars/infra-gw-2315a.nyx.ykn.local.yml + +```yaml +--- + +# BEGIN role_ifupdown +ifupdown_interfaces: + - interface: eth0 + ipv4: + inet: static + address: 192.168.50.250 + mask: 24 + dns: 192.168.50.11 192.168.50.16 + ipv6: + inet: static + address: fd00:ff50::d250 + mask: 64 + dns: fd00:ff50::d011 fd00:ff50::d016 + - interface: eth1 + ipv4: + inet: static + address: 192.168.1.51 + mask: 24 + dns: 192.168.1.254 + ipv6: + inet: auto +# END role_ifupdown +``` + +### group_vars/gw.yml + +```yaml +--- + +# BEGIN role_users +users: + - name: keepalived_script + comment: "Dedicated user for keepalived script" + update_password: on_create + password_lock: true + shell: /bin/bash +# END role_users + +# BEGIN role_nftables +nftables_rules: + - filename: keepalived + rules: + - ip saddr 192.168.50.250 accept + - ip saddr 192.168.50.251 accept + - ip saddr 192.168.50.252 accept +# END role_nftables + +# BEGIN role_keepalived +keepalived_ipv4: 192.168.50.254/24 +keepalived_ipv6: fd00:ff50::d254/64 + +keepalived_uid: "{{ keepalived_ipv4 | split('.') | last | split('/') | first }}" + +keepalived_track_scripts: + - name: check_nftables_service + interval: 5 + command: /usr/bin/systemctl is-active nftables.service +# END role_keepalived +``` + +### playbook.yml + +```yaml +--- + +- name: Déployer les passerelles réseau + hosts: gateways + vars: + primary_interface: "{{ ifupdown_interfaces | first }}" + keepalived_priority: "{{ 255 - (primary_interface.ipv4.address | split('.') | last | int) }}" + keepalived_interface: "{{ primary_interface.interface }}" + roles: + - name: users + - name: nftables + - name: keepalived +``` diff --git a/defaults/main.yml b/defaults/main.yml new file mode 100644 index 0000000..cfc06d7 --- /dev/null +++ b/defaults/main.yml @@ -0,0 +1,34 @@ +--- +# defaults file for keepalived + +keepalived_uid: "" +keepalived_priority: "" +keepalived_interface: "" + +keepalived_mail_to: "" +keepalived_mail_from: "" + +keepalived_ipv4: "" +keepalived_ipv6: "" + +keepalived_peers: [] + +keepalived_notify_enable: false +keepalived_notify_pre: {} +keepalived_notify_is_master: {} +keepalived_notify_is_backup: {} +keepalived_notify_is_fault: {} +keepalived_notify_by_default: {} + +keepalived_track_scripts: [] +# Example: +# - name: check_haproxy_8080 +# command: /usr/bin/nc -zv 127.0.0.1 8080 +# - name: check_haproxy_8081 +# command: /usr/bin/nc -zv 127.0.0.1 8081 + +keepalived_track_processes: [] +# Example: +# - name: check_haproxy +# search: /usr/sbin/haproxy +# quorum: 2 diff --git a/handlers/main.yml b/handlers/main.yml new file mode 100644 index 0000000..156ea70 --- /dev/null +++ b/handlers/main.yml @@ -0,0 +1,8 @@ +--- +# handlers file for keepalived + +- name: Restart keepalived.service + become: true + ansible.builtin.systemd: + state: restarted + name: keepalived.service diff --git a/meta/main.yml b/meta/main.yml index c58bebf..d4cb895 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -1,7 +1,7 @@ galaxy_info: namespace: ykn author: pulsar89.5 - description: Rôle modèle + description: Deploy keepalived license: GPL-3.0-or-later @@ -12,4 +12,5 @@ galaxy_info: versions: - all -dependencies: [] +dependencies: + - role: users diff --git a/tasks/configuration.yml b/tasks/configuration.yml new file mode 100644 index 0000000..3c87119 --- /dev/null +++ b/tasks/configuration.yml @@ -0,0 +1,37 @@ +--- +# tasks file for keepalived + +- name: Deploy configuration + ansible.builtin.template: + src: keepalived.j2 + dest: /etc/keepalived/keepalived.conf + owner: root + group: root + mode: u=rw,g=r,o=r + become: true + notify: Restart keepalived.service + +- name: Deploy sudoers configuration + ansible.builtin.template: + src: sudoers.j2 + dest: /etc/sudoers.d/keepalived_script + owner: root + group: keepalived_script + mode: u=rwx,g=rx,o= + validate: /usr/sbin/visudo -cf %s + when: + - keepalived_notify_enable + - keepalived_sudoers_cmd | length > 0 + become: true + notify: Restart keepalived.service + +- name: Deploy notify script + ansible.builtin.template: + src: notify.bash.j2 + dest: /etc/keepalived/notify.bash + owner: root + group: keepalived_script + mode: u=rwx,g=rx,o= + when: keepalived_notify_enable + become: true + notify: Restart keepalived.service diff --git a/tasks/installation.yml b/tasks/installation.yml new file mode 100644 index 0000000..5a3ce5e --- /dev/null +++ b/tasks/installation.yml @@ -0,0 +1,7 @@ +--- +# tasks file for keepalived + +- name: Install keepalived + ansible.builtin.apt: + name: keepalived + become: true diff --git a/tasks/main.yml b/tasks/main.yml new file mode 100644 index 0000000..06e7530 --- /dev/null +++ b/tasks/main.yml @@ -0,0 +1,10 @@ +--- +# tasks file for keepalived + +- name: Import installation tasks + ansible.builtin.import_tasks: + file: installation.yml + +- name: Import configuration tasks + ansible.builtin.import_tasks: + file: configuration.yml diff --git a/templates/keepalived.j2 b/templates/keepalived.j2 new file mode 100644 index 0000000..6eb67ad --- /dev/null +++ b/templates/keepalived.j2 @@ -0,0 +1,86 @@ +# {{ ansible_managed }} + +global_defs { +{% if keepalived_mail_to | length > 0 %} + notification_email { + {{ keepalived_mail_to }} + } +{% endif %} + +{% if keepalived_mail_from | length > 0 %} + notification_email_from {{ keepalived_mail_from }} + smtp_server 127.0.0.1 + smtp_connect_timeout 30 +{% endif %} + + script_user keepalived_script + enable_script_security + max_auto_priority 50 +} + +{% for script in keepalived_track_scripts %} +vrrp_script {{ script.name }} { + script "{{ script.command }}" + interval {{ script.interval }} +} +{% endfor %} + +{% for process in keepalived_track_processes %} +vrrp_track_process {{ process.name }} { + process "{{ process.search }}" + quorum {{ process.quorum }} +} +{% endfor %} + +vrrp_instance VIP_{{ keepalived_uid }} { + state BACKUP + priority {{ keepalived_priority }} + nopreempt + + interface {{ keepalived_interface }} + virtual_router_id {{ keepalived_uid }} + advert_int 1 + +{% if keepalived_peers | length > 0 %} + unicast_src_ip {{ ansible_facts[keepalived_interface]['ipv4']['address'] }} + unicast_peer { +{% for peer in keepalived_peers %} +{% if peer != ansible_facts[keepalived_interface]['ipv4']['address'] %} + {{ peer }} +{% endif %} +{% endfor %} + } +{% endif %} + +{% if keepalived_ipv4 | length > 0 %} + virtual_ipaddress { + {{ keepalived_ipv4 }} dev {{ keepalived_interface }} scope global + } +{% endif %} + +{% if keepalived_ipv6 | length > 0 %} + virtual_ipaddress_excluded { + {{ keepalived_ipv6 }} dev {{ keepalived_interface }} scope global + } +{% endif %} + +{% if keepalived_notify_enable %} + notify /etc/keepalived/notify.bash +{% endif %} + +{% if keepalived_track_scripts | length > 0 %} + track_script { +{% for script in keepalived_track_scripts %} + {{ script.name }} +{% endfor%} + } +{% endif %} + +{% if keepalived_track_processes | length > 0 %} + track_process { +{% for process in keepalived_track_processes %} + {{ process.name }} +{% endfor %} + } +{% endif %} +} diff --git a/templates/notify.bash.j2 b/templates/notify.bash.j2 new file mode 100644 index 0000000..ac42f2f --- /dev/null +++ b/templates/notify.bash.j2 @@ -0,0 +1,38 @@ +#!/bin/bash +# {{ ansible_managed }} + +TYPE=$1 +NAME=$2 +STATE=$3 + +{% if keepalived_notify_pre | length > 0 %} +{{ keepalived_notify_pre }} +{% endif %} + +# Use keepalived state +case $STATE in +{% if keepalived_notify_is_master | length > 0 %} + "MASTER") + {{ keepalived_notify_is_master | indent(4) }} + exit 0 + ;; +{% endif %} +{% if keepalived_notify_is_backup | length > 0 %} + "BACKUP") + {{ keepalived_notify_is_backup | indent(4) }} + exit 0 + ;; +{% endif %} +{% if keepalived_notify_is_fault | length > 0 %} + "FAULT") + {{ keepalived_notify_is_fault | indent(4) }} + exit 0 + ;; +{% endif %} +{% if keepalived_notify_by_default | length > 0 %} + *) + {{ keepalived_notify_by_default | indent(4) }} + exit 1 + ;; +{% endif %} +esac diff --git a/templates/sudoers.j2 b/templates/sudoers.j2 new file mode 100644 index 0000000..1fdca4a --- /dev/null +++ b/templates/sudoers.j2 @@ -0,0 +1,5 @@ +# {{ ansible_managed }} + +{% for cmd in keepalived_sudoers_cmd %} +keepalived_script ALL=(ALL) NOPASSWD:{{ cmd }} +{% endfor %} diff --git a/vars/main.yml b/vars/main.yml new file mode 100644 index 0000000..3f3c6cb --- /dev/null +++ b/vars/main.yml @@ -0,0 +1,9 @@ +--- +# vars file for keepalived + +users: + - name: keepalived_script + comment: "Dedicated user for keepalived script" + update_password: on_create + password_lock: true + shell: /bin/bash