initial commit

This commit is contained in:
boris committed 2026-07-08 16:38:55 +01:00
commit 3586c571f3
24 files changed
+887

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
.ansible/
*.retry
+55
View File
@@ -0,0 +1,55 @@
# nbops-ansible-router
Ansible framework for building a Debian 13 BIRD router VM from an initial Debian 12 install.
The first stage performs the Debian 12 to Debian 13 dist upgrade. Router configuration then installs WireGuard and BIRD, applies forwarding sysctl values, and renders configs from variables.
## Layout
- `site.yml` - main entry point.
- `inventories/production/hosts.yml` - VM inventory placeholder.
- `group_vars/routers.yml` - shared router variables.
- `roles/debian_dist_upgrade` - Debian 12 to Debian 13 upgrade workflow.
- `roles/bird_router` - WireGuard, sysctl forwarding, CZ.NIC BIRD packages, and BIRD configuration.
## Usage
Edit `inventories/production/hosts.yml`, then run:
```sh
ansible-playbook site.yml
```
To run only the OS upgrade stage:
```sh
ansible-playbook site.yml --tags debian_upgrade
```
The upgrade role expects the VM to start on Debian 12/bookworm and upgrades it to Debian 13/trixie.
## Router Secrets
WireGuard private keys are read from environment variables by default:
```sh
export WG1_PRIVATEKEY='...'
export WG2_PRIVATEKEY='...'
ansible-playbook site.yml
```
For production, prefer Ansible Vault group vars instead of committing secrets. Public keys, allowed IPs, BGP peers, package track, and package version are defined in `group_vars/routers.yml`.
## BIRD Package Track
The router role configures the CZ.NIC Labs apt repository for BIRD. Defaults:
- `bird_track: bird2`
- `bird_package_version: 2.19.1-cznic.1~trixie`
To test BIRD 3 later, set:
```yaml
bird_track: bird3
bird_package_version: ""
```
+12
View File
@@ -0,0 +1,12 @@
[defaults]
inventory = inventories/production/hosts.yml
roles_path = roles
host_key_checking = True
retry_files_enabled = False
interpreter_python = auto_silent
local_tmp = .ansible/tmp
[privilege_escalation]
become = True
become_method = sudo
become_ask_pass = False
+151
View File
@@ -0,0 +1,151 @@
router id 82.215.64.105;
log syslog all;
log "/var/log/bird/bird.log" { debug, trace, remote, warning, error, auth, fatal, bug };
#log "/var/log/bird/info-bird.log" { info };
protocol device { scan time 5; }
protocol direct { ipv6; }
protocol kernel {
ipv6 { export none; };
# ipv6;
scan time 15;
# learn;
}
protocol kernel {
ipv4;
scan time 15;
# export filter rt_export;
# learn;
}
protocol static announcev6 {
ipv6;
description "Static v6 Routes";
# route 2a12:bec0:6b0::/44 blackhole;
route 2a12:bec0:6b1::/48 via 2a12:bec2:b00b::201;
# route 2a12:bec0:6b9::/48 via 2a12:bec2:b00b::1f7;
# route 2a12:bec0:210:4::/64 via 2a12:bec0:210:4::1; #Pete-tunnel
# route 2a12:bec0:218::/48 via 2a12:bec0:210:4::2; #Pete-range
}
protocol static announcev4 {
ipv4;
description "Static v4 Routes";
}
protocol static {
ipv6;
}
protocol static {
ipv4;
}
filter rt_importv4 {
accept;
}
filter rt_importv6 {
accept;
}
filter rt_nothanks {
if (net ~ [ fd00:dead:beef:c0::/80 ]) then
reject;
if (net ~ [ fd4d:6169:6c69:6f77::/64 ]) then
reject;
if (net ~ [ fd7a:115c:a1e0::/48 ]) then
reject;
if (net ~ [ fd8c:c43c:133e::/64 ]) then
reject;
if (net ~ [ fd8c:c43c:133e:1::/64 ]) then
reject;
if (net ~ [ fd8c:c43c:133e:2::/64 ]) then
reject;
if (net ~ [ fd00:1::/64 ]) then
reject;
if (net ~ [ 2a12:bec2:b00b::/64 ]) then
reject;
if (net ~ [ ::10.10.10.1/128 ]) then
reject;
if (net ~ [ 2a12:bec0:210:3::/64 ]) then
reject;
else
accept;
}
filter sbehop {
gw = 2a12:bec0:210:3::1;
accept;
}
filter brt_importv6 {
reject;
}
filter rt_export {
if (proto = "announcev4") then
accept;
if (proto = "announcev6") then
accept;
# reject_bogon_asns();
# reject_v6_bogon_prefixes();
# reject_smallv6_prefixes();
# reject_long_aspaths();
reject;
# accept; #export Any Accepted Prefixes
}
#EBGP upstream sessions
protocol bgp tgj4 {
# debug all;
local 172.22.10.2 as 213026;
neighbor 172.22.10.1 as 199519;
# default bgp_local_pref 20;
multihop 255;
ipv6 {
export limit 30;
import filter sbehop;
export filter rt_nothanks;
graceful restart on;
};
}
protocol bgp scaleblade6 {
# debug all;
local 2a12:bec2:b00b::201 as 213026;
neighbor 2a12:bec1::2 as 52041;
multihop 255;
# default bgp_local_pref 20;
ipv6 {
export limit 50;
import filter rt_importv6;
export filter rt_nothanks;
graceful restart on;
};
}
#IBGP sessions
protocol bgp ntbx {
local 172.18.72.1 as 213026;
neighbor 172.18.72.2 as 213026;
multihop 255;
ipv6 {
import limit 20;
# import none;
import filter rt_importv6;
export filter rt_export;
# export none;
};
# ipv4 {
# import limit 20;
# import none;
# export filter rt_export;
## graceful restart on;
# };
}
+3
View File
@@ -0,0 +1,3 @@
BIRD_RUN_USER=bird
BIRD_RUN_GROUP=bird
#BIRD_ARGS=
+3
View File
@@ -0,0 +1,3 @@
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.default.forwarding = 1
net.ipv4.ip_forward = 1
+16
View File
@@ -0,0 +1,16 @@
# Wireguard to pfSense
[Interface]
PrivateKey = ${WG1_PRIVATEKEY}
Address = 2a12:bec0:6b1::1/64,172.18.72.1/30
ListenPort = 51825
MTU = 1430
PreUp = ip neigh add proxy 82.215.64.187 dev eth0
PostDown = ip neigh del proxy 82.215.64.187 dev eth0
[Peer]
PublicKey = SsGjCLJBKQFDuxSnVgwua77fvb/ha4KFRiJcCBk7vF0=
AllowedIPs = 2a12:bec0:6b1::2/64,2a12:bec0:6b9::/48,172.18.72.0/30,82.215.64.187/32
#2a12:bec0:6b9:2::/64,2a12:bec0:6b9:3::/64,2a12:bec0:6b9:10::/64,2a12:bec0:6b9::/48,172.18.72.0/30,82.215.64.187/32
+13
View File
@@ -0,0 +1,13 @@
# Wireguard to TGJ
[Interface]
PrivateKey = ${WG2_PRIVATEKEY}
Address = 2a12:bec0:210:3::2/64,172.22.10.2/30
ListenPort = 51820
MTU = 1430
[Peer]
PublicKey = 1XaLeqKZimM1cS57dPzTSf/UGW8bThADjf+oBmRF82I=
AllowedIPs = 2a12:bec0:21f::2/64,172.22.10.1/30,2a12:bec0:212::/48,2a12:bec0:210::/48,2a12:bec0:214::/48
Endpoint = v4.router.colo.tgj.services:51869
PersistentKeepalive = 25
+8
View File
@@ -0,0 +1,8 @@
82.215.64.187 = Virtual Home IP used by Bird
82.215.64.105 = BIRD VPS IP
82.215.64.169 = VPS IP
v4.router.colo.tgj.services:51869 = TGJ WG Remote Node
82.215.64.187 is cloud-init added to the default interface, this should be removed in wireguard PreUp, or ansible config
Should use ansible variables for allowedIPs, private / public keys, etc. anything that should not be committed to github should be in group vars or envy
+115
View File
@@ -0,0 +1,115 @@
---
debian_upgrade_target_release: trixie
debian_upgrade_target_major_version: "13"
debian_upgrade_source_major_version: "12"
debian_upgrade_reboot_timeout: 1800
router_external_interface: eth0
router_virtual_home_ip: 82.215.64.187
router_bird_vps_ip: 82.215.64.105
router_vps_ip: 82.215.64.169
router_sysctl:
net.ipv6.conf.all.forwarding: 1
net.ipv6.conf.default.forwarding: 1
net.ipv4.ip_forward: 1
bird_enable: true
bird_track: bird2
bird_package_version: 2.19.1-cznic.1~trixie
bird_router_id: 82.215.64.105
bird_local_as: 213026
bird_run_user: bird
bird_run_group: bird
bird_log_file: /var/log/bird/bird.log
bird_sbehop_gateway: 2a12:bec0:210:3::1
bird_static_routes_v6:
- prefix: 2a12:bec0:6b1::/48
via: 2a12:bec2:b00b::201
bird_reject_prefixes_v6:
- fd00:dead:beef:c0::/80
- fd4d:6169:6c69:6f77::/64
- fd7a:115c:a1e0::/48
- fd8c:c43c:133e::/64
- fd8c:c43c:133e:1::/64
- fd8c:c43c:133e:2::/64
- fd00:1::/64
- 2a12:bec2:b00b::/64
- ::10.10.10.1/128
- 2a12:bec0:210:3::/64
bird_bgp_sessions:
- name: tgj4
local_address: 172.22.10.2
local_as: 213026
neighbor_address: 172.22.10.1
neighbor_as: 199519
address_family: ipv6
export_limit: 30
import_filter: sbehop
export_filter: rt_nothanks
graceful_restart: true
- name: scaleblade6
local_address: 2a12:bec2:b00b::201
local_as: 213026
neighbor_address: 2a12:bec1::2
neighbor_as: 52041
address_family: ipv6
export_limit: 50
import_filter: rt_importv6
export_filter: rt_nothanks
graceful_restart: true
- name: ntbx
local_address: 172.18.72.1
local_as: 213026
neighbor_address: 172.18.72.2
neighbor_as: 213026
address_family: ipv6
import_limit: 20
import_filter: rt_importv6
export_filter: rt_export
wireguard_enable: true
wireguard_interfaces:
- name: wg1
description: WireGuard to pfSense
private_key_env: WG1_PRIVATEKEY
address:
- 2a12:bec0:6b1::1/64
- 172.18.72.1/30
listen_port: 51825
mtu: 1430
pre_up:
- "ip addr del 82.215.64.187/32 dev eth0 2>/dev/null || true"
- "ip neigh add proxy 82.215.64.187 dev eth0 2>/dev/null || true"
post_down:
- "ip neigh del proxy 82.215.64.187 dev eth0 2>/dev/null || true"
peers:
- public_key: SsGjCLJBKQFDuxSnVgwua77fvb/ha4KFRiJcCBk7vF0=
allowed_ips:
- 2a12:bec0:6b1::2/64
- 2a12:bec0:6b9::/48
- 172.18.72.0/30
- 82.215.64.187/32
- name: wg2
description: WireGuard to TGJ
private_key_env: WG2_PRIVATEKEY
address:
- 2a12:bec0:210:3::2/64
- 172.22.10.2/30
listen_port: 51820
mtu: 1430
peers:
- public_key: 1XaLeqKZimM1cS57dPzTSf/UGW8bThADjf+oBmRF82I=
allowed_ips:
- 2a12:bec0:21f::2/64
- 172.22.10.1/30
- 2a12:bec0:212::/48
- 2a12:bec0:210::/48
- 2a12:bec0:214::/48
endpoint: v4.router.colo.tgj.services:51869
persistent_keepalive: 25
+7
View File
@@ -0,0 +1,7 @@
all:
children:
routers:
hosts:
router-vm:
ansible_host: 10.10.10.10
ansible_user: debian
+34
View File
@@ -0,0 +1,34 @@
---
router_external_interface: eth0
router_sysctl:
net.ipv6.conf.all.forwarding: 1
net.ipv6.conf.default.forwarding: 1
net.ipv4.ip_forward: 1
wireguard_enable: true
wireguard_package_name: wireguard-tools
wireguard_interfaces: []
bird_enable: true
bird_track: bird2
bird_package_name: "{{ bird_track }}"
bird_package_version: ""
bird_cznic_repo_enabled: true
bird_cznic_repo_base_url: https://pkg.labs.nic.cz
bird_cznic_repo_distribution: "{{ ansible_facts.distribution_release | default('trixie') }}"
bird_cznic_key_url: https://pkg.labs.nic.cz/gpg
bird_config_path: /etc/bird/bird.conf
bird_envvars_path: /etc/bird/envvars
bird_service_name: bird
bird_router_id: 127.0.0.1
bird_local_as: 64512
bird_run_user: bird
bird_run_group: bird
bird_log_file: /var/log/bird/bird.log
bird_sbehop_gateway: ""
bird_static_routes_v6: []
bird_static_routes_v4: []
bird_reject_prefixes_v6: []
bird_bgp_sessions: []
+20
View File
@@ -0,0 +1,20 @@
---
- name: Reload sysctl
ansible.builtin.command: sysctl --system
listen: reload_sysctl
changed_when: false
- name: Restart WireGuard interfaces
ansible.builtin.systemd:
name: "wg-quick@{{ item.name }}"
state: restarted
loop: "{{ wireguard_interfaces }}"
listen: restart_wireguard_interfaces
when: wireguard_enable
- name: Restart BIRD
ansible.builtin.systemd:
name: "{{ bird_service_name }}"
state: restarted
listen: restart_bird
when: bird_enable
+131
View File
@@ -0,0 +1,131 @@
- name: Validate BIRD package track
ansible.builtin.assert:
that:
- bird_track in ['bird2', 'bird3']
fail_msg: "bird_track must be either bird2 or bird3."
when: bird_enable
- name: Install repository prerequisites
ansible.builtin.apt:
name:
- apt-transport-https
- ca-certificates
- python3-debian
state: present
update_cache: true
when: bird_enable and bird_cznic_repo_enabled
- name: Configure CZ.NIC Labs BIRD apt repository
ansible.builtin.deb822_repository:
name: "cznic-labs-{{ bird_track }}"
types: deb
uris: "{{ bird_cznic_repo_base_url }}/{{ bird_track }}"
suites: "{{ bird_cznic_repo_distribution }}"
components: main
signed_by: "{{ bird_cznic_key_url }}"
state: present
when: bird_enable and bird_cznic_repo_enabled
- name: Update package cache after configuring CZ.NIC repository
ansible.builtin.apt:
update_cache: true
when: bird_enable and bird_cznic_repo_enabled
- name: Install WireGuard tools
ansible.builtin.apt:
name: "{{ wireguard_package_name }}"
state: present
when: wireguard_enable
- name: Install selected BIRD package
ansible.builtin.apt:
name: "{{ bird_package_name if bird_package_version | length == 0 else bird_package_name + '=' + bird_package_version }}"
state: present
when: bird_enable
- name: Configure router sysctl values
ansible.builtin.template:
src: router-sysctl.conf.j2
dest: /etc/sysctl.d/99-router.conf
owner: root
group: root
mode: "0644"
notify: reload_sysctl
- name: Ensure WireGuard configuration directory exists
ansible.builtin.file:
path: /etc/wireguard
state: directory
owner: root
group: root
mode: "0700"
when: wireguard_enable
- name: Validate WireGuard private keys are provided
ansible.builtin.assert:
that:
- >-
(item.private_key is defined and item.private_key | length > 0)
or
(item.private_key_env is defined and lookup('ansible.builtin.env', item.private_key_env) | length > 0)
fail_msg: "Private key for {{ item.name }} is missing. Set it via Ansible Vault or the matching environment lookup."
loop: "{{ wireguard_interfaces }}"
no_log: true
when: wireguard_enable
- name: Configure WireGuard interfaces
ansible.builtin.template:
src: wg.conf.j2
dest: "/etc/wireguard/{{ item.name }}.conf"
owner: root
group: root
mode: "0600"
loop: "{{ wireguard_interfaces }}"
no_log: true
notify: restart_wireguard_interfaces
when: wireguard_enable
- name: Enable WireGuard interfaces
ansible.builtin.systemd:
name: "wg-quick@{{ item.name }}"
enabled: true
state: started
loop: "{{ wireguard_interfaces }}"
when: wireguard_enable
- name: Ensure BIRD log directory exists
ansible.builtin.file:
path: "{{ bird_log_file | dirname }}"
state: directory
owner: "{{ bird_run_user }}"
group: "{{ bird_run_group }}"
mode: "0755"
when: bird_enable
- name: Configure BIRD environment
ansible.builtin.template:
src: bird-envvars.j2
dest: "{{ bird_envvars_path }}"
owner: root
group: root
mode: "0644"
notify: restart_bird
when: bird_enable
- name: Configure BIRD
ansible.builtin.template:
src: bird.conf.j2
dest: "{{ bird_config_path }}"
owner: root
group: "{{ bird_run_group }}"
mode: "0640"
validate: "bird -p -c %s"
notify: restart_bird
when: bird_enable
- name: Enable BIRD service
ansible.builtin.systemd:
name: "{{ bird_service_name }}"
enabled: true
state: started
when: bird_enable
@@ -0,0 +1,3 @@
BIRD_RUN_USER={{ bird_run_user }}
BIRD_RUN_GROUP={{ bird_run_group }}
#BIRD_ARGS=
+109
View File
@@ -0,0 +1,109 @@
router id {{ bird_router_id }};
log syslog all;
log "{{ bird_log_file }}" { debug, trace, remote, warning, error, auth, fatal, bug };
protocol device { scan time 5; }
protocol direct { ipv6; }
protocol kernel {
ipv6 { export none; };
scan time 15;
}
protocol kernel {
ipv4;
scan time 15;
}
protocol static announcev6 {
ipv6;
description "Static v6 Routes";
{% for route in bird_static_routes_v6 %}
{% if route.blackhole | default(false) %}
route {{ route.prefix }} blackhole;
{% else %}
route {{ route.prefix }} via {{ route.via }};
{% endif %}
{% endfor %}
}
protocol static announcev4 {
ipv4;
description "Static v4 Routes";
{% for route in bird_static_routes_v4 %}
{% if route.blackhole | default(false) %}
route {{ route.prefix }} blackhole;
{% else %}
route {{ route.prefix }} via {{ route.via }};
{% endif %}
{% endfor %}
}
protocol static {
ipv6;
}
protocol static {
ipv4;
}
filter rt_importv4 {
accept;
}
filter rt_importv6 {
accept;
}
filter rt_nothanks {
{% for prefix in bird_reject_prefixes_v6 %}
if (net ~ [ {{ prefix }} ]) then reject;
{% endfor %}
accept;
}
filter sbehop {
gw = {{ bird_sbehop_gateway }};
accept;
}
filter brt_importv6 {
reject;
}
filter rt_export {
if (proto = "announcev4") then accept;
if (proto = "announcev6") then accept;
reject;
}
{% for session in bird_bgp_sessions %}
protocol bgp {{ session.name }} {
local {{ session.local_address }} as {{ session.local_as }};
neighbor {{ session.neighbor_address }} as {{ session.neighbor_as }};
multihop {{ session.multihop | default(255) }};
{{ session.address_family | default('ipv6') }} {
{% if session.import_limit is defined %}
import limit {{ session.import_limit }};
{% endif %}
{% if session.export_limit is defined %}
export limit {{ session.export_limit }};
{% endif %}
{% if session.import_filter is defined %}
import filter {{ session.import_filter }};
{% else %}
import none;
{% endif %}
{% if session.export_filter is defined %}
export filter {{ session.export_filter }};
{% else %}
export none;
{% endif %}
{% if session.graceful_restart | default(false) %}
graceful restart on;
{% endif %}
};
}
{% endfor %}
@@ -0,0 +1,3 @@
{% for key, value in router_sysctl | dictsort %}
{{ key }} = {{ value }}
{% endfor %}
+39
View File
@@ -0,0 +1,39 @@
# {{ item.description | default(item.name) }}
[Interface]
{% if item.private_key is defined %}
PrivateKey = {{ item.private_key }}
{% else %}
PrivateKey = {{ lookup('ansible.builtin.env', item.private_key_env) }}
{% endif %}
Address = {{ item.address | join(',') }}
{% if item.listen_port is defined %}
ListenPort = {{ item.listen_port }}
{% endif %}
{% if item.mtu is defined %}
MTU = {{ item.mtu }}
{% endif %}
{% for command in item.pre_up | default([]) %}
PreUp = {{ command }}
{% endfor %}
{% for command in item.post_up | default([]) %}
PostUp = {{ command }}
{% endfor %}
{% for command in item.pre_down | default([]) %}
PreDown = {{ command }}
{% endfor %}
{% for command in item.post_down | default([]) %}
PostDown = {{ command }}
{% endfor %}
{% for peer in item.peers | default([]) %}
[Peer]
PublicKey = {{ peer.public_key }}
AllowedIPs = {{ peer.allowed_ips | join(',') }}
{% if peer.endpoint is defined %}
Endpoint = {{ peer.endpoint }}
{% endif %}
{% if peer.persistent_keepalive is defined %}
PersistentKeepalive = {{ peer.persistent_keepalive }}
{% endif %}
{% endfor %}
@@ -0,0 +1,10 @@
---
debian_upgrade_source_major_version: "12"
debian_upgrade_target_major_version: "13"
debian_upgrade_target_release: trixie
debian_upgrade_reboot_timeout: 1800
debian_upgrade_sources_list_path: /etc/apt/sources.list
debian_upgrade_sources_backup_path: /etc/apt/sources.list.bookworm.bak
debian_upgrade_deb822_sources_path: /etc/apt/sources.list.d/debian.sources
debian_upgrade_deb822_sources_backup_path: /etc/apt/sources.list.d/debian.sources.bookworm.bak
@@ -0,0 +1,6 @@
---
- name: Reboot after Debian dist upgrade
ansible.builtin.reboot:
msg: Rebooting after Debian dist upgrade
reboot_timeout: "{{ debian_upgrade_reboot_timeout }}"
listen: reboot_after_debian_dist_upgrade
+118
View File
@@ -0,0 +1,118 @@
---
- name: Validate current host is Debian
ansible.builtin.assert:
that:
- ansible_facts.distribution == "Debian"
fail_msg: "This role only supports Debian hosts."
- name: Validate expected source Debian major version
ansible.builtin.assert:
that:
- ansible_facts.distribution_major_version == debian_upgrade_source_major_version
fail_msg: >-
Expected Debian {{ debian_upgrade_source_major_version }} before upgrade,
found Debian {{ ansible_facts.distribution_major_version }}.
success_msg: "Host is Debian {{ debian_upgrade_source_major_version }} and ready for upgrade."
when: ansible_facts.distribution_major_version != debian_upgrade_target_major_version
- name: Update package cache on current release
ansible.builtin.apt:
update_cache: true
cache_valid_time: 3600
when: ansible_facts.distribution_major_version != debian_upgrade_target_major_version
- name: Upgrade installed packages before release change
ansible.builtin.apt:
upgrade: dist
autoremove: true
autoclean: true
when: ansible_facts.distribution_major_version != debian_upgrade_target_major_version
- name: Check for classic apt sources list
ansible.builtin.stat:
path: "{{ debian_upgrade_sources_list_path }}"
register: debian_upgrade_sources_list_stat
when: ansible_facts.distribution_major_version != debian_upgrade_target_major_version
- name: Check for deb822 apt sources
ansible.builtin.stat:
path: "{{ debian_upgrade_deb822_sources_path }}"
register: debian_upgrade_deb822_sources_stat
when: ansible_facts.distribution_major_version != debian_upgrade_target_major_version
- name: Back up current apt sources
ansible.builtin.copy:
src: "{{ debian_upgrade_sources_list_path }}"
dest: "{{ debian_upgrade_sources_backup_path }}"
remote_src: true
mode: "0644"
force: false
when:
- ansible_facts.distribution_major_version != debian_upgrade_target_major_version
- debian_upgrade_sources_list_stat.stat.exists
- name: Back up current deb822 apt sources
ansible.builtin.copy:
src: "{{ debian_upgrade_deb822_sources_path }}"
dest: "{{ debian_upgrade_deb822_sources_backup_path }}"
remote_src: true
mode: "0644"
force: false
when:
- ansible_facts.distribution_major_version != debian_upgrade_target_major_version
- debian_upgrade_deb822_sources_stat.stat.exists
- name: Configure Debian target release classic apt sources
ansible.builtin.template:
src: sources.list.j2
dest: "{{ debian_upgrade_sources_list_path }}"
owner: root
group: root
mode: "0644"
when:
- ansible_facts.distribution_major_version != debian_upgrade_target_major_version
- debian_upgrade_sources_list_stat.stat.exists or not debian_upgrade_deb822_sources_stat.stat.exists
- name: Configure Debian target release deb822 apt sources
ansible.builtin.template:
src: debian.sources.j2
dest: "{{ debian_upgrade_deb822_sources_path }}"
owner: root
group: root
mode: "0644"
when:
- ansible_facts.distribution_major_version != debian_upgrade_target_major_version
- debian_upgrade_deb822_sources_stat.stat.exists
- name: Update package cache for target release
ansible.builtin.apt:
update_cache: true
when: ansible_facts.distribution_major_version != debian_upgrade_target_major_version
- name: Perform Debian dist upgrade
ansible.builtin.apt:
upgrade: dist
autoremove: true
autoclean: true
dpkg_options: force-confdef,force-confold
environment:
DEBIAN_FRONTEND: noninteractive
APT_LISTCHANGES_FRONTEND: none
notify: reboot_after_debian_dist_upgrade
when: ansible_facts.distribution_major_version != debian_upgrade_target_major_version
- name: Flush reboot handler before verification
ansible.builtin.meta: flush_handlers
- name: Gather facts after possible upgrade
ansible.builtin.setup:
- name: Verify Debian target version
ansible.builtin.assert:
that:
- ansible_facts.distribution == "Debian"
- ansible_facts.distribution_major_version == debian_upgrade_target_major_version
fail_msg: >-
Debian upgrade did not finish as expected. Found
{{ ansible_facts.distribution }} {{ ansible_facts.distribution_major_version }}.
success_msg: "Host is running Debian {{ debian_upgrade_target_major_version }}."
@@ -0,0 +1,11 @@
Types: deb
URIs: http://deb.debian.org/debian
Suites: {{ debian_upgrade_target_release }} {{ debian_upgrade_target_release }}-updates
Components: main contrib non-free non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
Types: deb
URIs: http://security.debian.org/debian-security
Suites: {{ debian_upgrade_target_release }}-security
Components: main contrib non-free non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
@@ -0,0 +1,3 @@
deb http://deb.debian.org/debian {{ debian_upgrade_target_release }} main contrib non-free non-free-firmware
deb http://deb.debian.org/debian {{ debian_upgrade_target_release }}-updates main contrib non-free non-free-firmware
deb http://security.debian.org/debian-security {{ debian_upgrade_target_release }}-security main contrib non-free non-free-firmware
+15
View File
@@ -0,0 +1,15 @@
---
- name: Prepare Debian router base system
hosts: routers
become: true
gather_facts: true
roles:
- role: debian_dist_upgrade
tags:
- debian_upgrade
- role: bird_router
tags:
- bird
- router