diff --git a/README.md b/README.md
index fbe61d2..89ae0f4 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,15 @@
-Setup BIRD with BGP
+# Setup BIRD with BGP
Use with network role for loopback/dummy interface configuraton
-BIRD config example:
+# Supported OS
+- AlmaLinux 8/9
+- Rocky Linux 8/9
+- CentOS 7
+- Debian 11/12
+
+# Bird config examples
+
+ Using template config
# Set routing interface
bird_interface: "eth1"
@@ -62,3 +70,102 @@ BIRD config example:
remote_addr: "10.127.2.10"
export:
- STATIC1
+
+
+
+
+ Complete config override
+
+ bird:
+ bgp_asnum: 4200200000
+ bgp_mesh:
+ controller1.example.com:
+ routerid: "10.180.0.101"
+ bgp:
+ - "10.180.0.101"
+ - "192.168.255.101"
+ controller2.example.com:
+ routerid: "10.180.0.102"
+ bgp:
+ - "10.180.0.102"
+ - "192.168.255.102"
+ controller3.example.com:
+ routerid: "10.180.0.103"
+ bgp:
+ - "10.180.0.103"
+ - "192.168.255.103"
+ compute1.example.com:
+ routerid: "10.180.0.104"
+ bgp:
+ - "10.180.0.104"
+ - "192.168.255.104"
+ compute2.example.com:
+ routerid: "10.180.0.105"
+ bgp:
+ - "10.180.0.105"
+ - "192.168.255.105"
+
+ bird_config_override: |
+ log syslog all;
+ router id {{ bird.bgp_mesh[inventory_hostname].bgp[0] }};
+
+ filter bgp_mesh_export {
+ if net ~ [192.168.0.101/32] then accept;
+ if net ~ [192.168.0.102/32] then accept;
+ if net ~ [192.168.0.103/32] then accept;
+ if net ~ [192.168.0.104/32] then accept;
+ if net ~ [192.168.0.105/32] then accept;
+ reject;
+ }
+ filter bgp_mesh_import {
+ if net ~ [192.168.0.101/32] then accept;
+ if net ~ [192.168.0.102/32] then accept;
+ if net ~ [192.168.0.103/32] then accept;
+ if net ~ [192.168.0.104/32] then accept;
+ if net ~ [192.168.0.105/32] then accept;
+ reject;
+ }
+
+ protocol device {
+ }
+
+ protocol direct {
+ ipv4;
+ ipv6;
+ }
+
+ protocol kernel KERNEL4 {
+ merge paths yes;
+ learn;
+ ipv4 {
+ export all;
+ };
+ }
+
+ protocol kernel KERNEL6 {
+ ipv6 {
+ export all;
+ };
+ }
+
+ {% for host in bird.bgp_mesh %}
+ {% for protocol_bgp in bird.bgp_mesh[host].bgp %}
+ {% if inventory_hostname not in host %}
+ protocol bgp {{ host.split(".")[0] }}_{{ loop.index * 100 }} {
+ password "3472e7d08e4aca276d72b5165adfc189";
+ source address {{ bird.bgp_mesh[inventory_hostname].bgp[loop.index0] }};
+ local as {{ bird.bgp_asnum }};
+ neighbor {{ protocol_bgp }} as {{ bird.bgp_asnum }};
+ hold time 10;
+ ipv4 {
+ import filter bgp_mesh_import;
+ export filter bgp_mesh_export;
+ };
+ default bgp_local_pref {{ 300 - (loop.index * 100) }};
+ }
+
+ {% endif %}
+ {% endfor %}
+ {% endfor %}
+
+
diff --git a/defaults/main.yaml b/defaults/main.yaml
index e69de29..848c266 100644
--- a/defaults/main.yaml
+++ b/defaults/main.yaml
@@ -0,0 +1,2 @@
+---
+bird_version: ''
diff --git a/handlers/main.yaml b/handlers/main.yaml
index 7c4de7a..58ecc1d 100644
--- a/handlers/main.yaml
+++ b/handlers/main.yaml
@@ -1,14 +1,17 @@
---
-- name: Restart BIRD
+- name: Restart bird
systemd:
- name: bird
+ name: "{{ bird_unit_name }}"
state: restarted
daemon_reload: yes
+ when:
+ - not bird_setup.changed
+ - not bird_enable_and_start.changed
-- name: Reload BIRD
+- name: Reload bird
systemd:
- name: bird
- state: restarted
+ name: "{{ bird_unit_name }}"
+ state: reloaded
daemon_reload: yes
- name: Restart loopback
diff --git a/tasks/Debian/main.yaml b/tasks/Debian/main.yaml
new file mode 100644
index 0000000..3cc2329
--- /dev/null
+++ b/tasks/Debian/main.yaml
@@ -0,0 +1,49 @@
+---
+- name: Mask bird before install for Debian OS family
+ ansible.builtin.systemd:
+ name: "{{ bird_unit_name }}"
+ masked: yes
+ when: ansible_facts['os_family'] == 'Debian'
+ changed_when: false
+
+- name: Install bird
+ package:
+ name: "{{ bird_package }}"
+ state: present
+ register: bird_setup
+
+- name: Template default bird.conf config
+ when: bird_config_override is not defined
+ block:
+ - name: Add default bird.conf
+ template:
+ src: "bird.conf.j2"
+ dest: "/etc/bird/bird.conf"
+ notify:
+ - Reload bird
+
+- name: Template bird.conf override
+ when: bird_config_override is defined
+ block:
+ - name: Override bird.conf
+ copy:
+ content: "{{ bird_config_override }}"
+ dest: "/etc/bird/bird.conf"
+ notify:
+ - Reload bird
+
+- name: Unmask bird after install for Debian OS family
+ ansible.builtin.systemd:
+ name: "{{ bird_unit_name }}"
+ masked: no
+ when: ansible_facts['os_family'] == 'Debian'
+ changed_when: false
+
+- name: Enable and start bird service
+ systemd:
+ name: "{{ bird_unit_name }}"
+ state: started
+ enabled: yes
+ masked: no
+ daemon_reload: yes
+ register: bird_enable_and_start
diff --git a/tasks/RedHat/7.yaml b/tasks/RedHat/7.yaml
deleted file mode 100644
index aa9a875..0000000
--- a/tasks/RedHat/7.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
----
-- name: Install BIRD
- package:
- name: bird2
- state: present
-
-- name: Add BIRD config
- template:
- src: bird.conf.j2
- dest: /etc/bird.conf
- notify:
- - Reload BIRD
-
-- name: Start BIRD service
- systemd:
- name: bird
- state: started
- enabled: yes
- daemon_reload: yes
-
diff --git a/tasks/RedHat/8.yaml b/tasks/RedHat/8.yaml
deleted file mode 100644
index de71e6a..0000000
--- a/tasks/RedHat/8.yaml
+++ /dev/null
@@ -1,19 +0,0 @@
----
-- name: Install BIRD
- package:
- name: bird
- state: present
-
-- name: Add BIRD config
- template:
- src: bird.conf.j2
- dest: /etc/bird.conf
- notify:
- - Reload BIRD
-
-- name: Start BIRD service
- systemd:
- name: bird
- state: started
- enabled: yes
- daemon_reload: yes
diff --git a/tasks/RedHat/main.yaml b/tasks/RedHat/main.yaml
new file mode 100644
index 0000000..f1175b8
--- /dev/null
+++ b/tasks/RedHat/main.yaml
@@ -0,0 +1,42 @@
+---
+- name: Install bird
+ package:
+ name: "{{ bird_package }}"
+ state: present
+ register: bird_setup
+
+- name: Add bird.conf
+ template:
+ src: bird.conf.j2
+ dest: /etc/bird.conf
+ notify:
+ - Reload bird
+
+- name: Template default bird.conf config
+ when: bird_config_override is not defined
+ block:
+ - name: Add bird.conf
+ template:
+ src: "bird.conf.j2"
+ dest: "/etc/bird.conf"
+ notify:
+ - Reload bird
+
+- name: Template bird.conf override
+ when: bird_config_override is defined
+ block:
+ - name: Override bird.conf
+ copy:
+ content: "{{ bird_config_override }}"
+ dest: "/etc/bird.conf"
+ notify:
+ - Reload bird
+
+- name: Enable and start bird service
+ systemd:
+ name: "{{ bird_unit_name }}"
+ state: started
+ enabled: yes
+ masked: no
+ daemon_reload: yes
+ register: bird_enable_and_start
diff --git a/tasks/main.yaml b/tasks/main.yaml
index 5d3f26e..3961f9a 100644
--- a/tasks/main.yaml
+++ b/tasks/main.yaml
@@ -1,3 +1,18 @@
---
-- name: Include BIRD installation tasks
- include_tasks: "{{ ansible_facts['os_family'] }}/{{ ansible_facts['distribution_major_version'] }}.yaml"
+- name: Load a variable file based on the OS type
+ include_vars: "{{ lookup('first_found', params) }}"
+ vars:
+ params:
+ files:
+ - "{{ ansible_facts['distribution'] }}-{{ ansible_facts['distribution_major_version'] }}.yaml"
+ - "{{ ansible_facts['distribution'] }}-{{ ansible_facts['distribution_version'] }}.yaml"
+ - "{{ ansible_facts['os_family'] }}-{{ ansible_facts['distribution_major_version'] }}.yaml"
+ - "{{ ansible_facts['os_family'] }}-{{ ansible_facts['distribution_version'] }}.yaml"
+ - "{{ ansible_facts['distribution'] }}.yaml"
+ - "{{ ansible_facts['os_family'] }}.yaml"
+ paths:
+ - "vars"
+ tags: bird_vars
+
+- name: Include bird installation tasks
+ include_tasks: "{{ ansible_facts['os_family'] }}/main.yaml"
diff --git a/vars/Debian.yaml b/vars/Debian.yaml
new file mode 100644
index 0000000..7809747
--- /dev/null
+++ b/vars/Debian.yaml
@@ -0,0 +1,3 @@
+bird_package_name: "bird2"
+bird_package: "{{ bird_package_name + '-' + bird_version if (bird_version is defined and (bird_version != '*' and bird_version != '' and bird_version != 'latest')) else bird_package_name }}"
+bird_unit_name: "bird"
diff --git a/vars/RedHat.yaml b/vars/RedHat.yaml
new file mode 100644
index 0000000..ab3807c
--- /dev/null
+++ b/vars/RedHat.yaml
@@ -0,0 +1,3 @@
+bird_package_name: "{{ 'bird2' if ansible_facts['distribution_major_version'] == '7' else 'bird' }}"
+bird_package: "{{ bird_package_name + '-' + bird_version if (bird_version is defined and (bird_version != '*' and bird_version != '' and bird_version != 'latest')) else bird_package_name }}"
+bird_unit_name: "bird"