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"