Join a fresh host to NetBird idempotently with the keyring, the management URL and the interface blacklist from the vars, and edit the blacklist and log level of a joined one

This commit is contained in:
2026-10-23 20:54:30 +00:00
parent a64d082c0c
commit a4648e0ea7
6 changed files with 97 additions and 14 deletions
@@ -4,3 +4,8 @@ netbird_client:
join_network: join_network:
setup_key: setup_key:
management_url: management_url:
# Interface name prefixes appended to IFaceBlackList in /var/lib/netbird/default.json
iface_blacklist_extra: []
# Overrides the --log-level of the netbird service when set
log_level:
+5
View File
@@ -0,0 +1,5 @@
- name: restart_netbird
systemd:
name: netbird
state: restarted
daemon_reload: true
+49
View File
@@ -0,0 +1,49 @@
- name: Read netbird config
slurp:
src: /var/lib/netbird/default.json
register: netbird_config_file
when: netbird_client.iface_blacklist_extra | default([]) | length > 0
tags: netbird_client_config
- name: Add the extra interface prefixes to IFaceBlackList
when: netbird_config_file.content is defined
vars:
netbird_config: "{{ netbird_config_file.content | b64decode | from_json }}"
netbird_blacklist_missing: "{{ netbird_client.iface_blacklist_extra | difference(netbird_config.IFaceBlackList | default([])) }}"
tags: netbird_client_config
block:
# netbird writes its in-memory config back on exit, so edit only while it is stopped
- name: Stop netbird to edit its config
systemd:
name: netbird
state: stopped
when: netbird_blacklist_missing | length > 0
notify: restart_netbird
register: netbird_stopped
- name: Re-read netbird config after stop
slurp:
src: /var/lib/netbird/default.json
register: netbird_config_stopped
when: netbird_stopped is changed
- name: Write IFaceBlackList
copy:
dest: /var/lib/netbird/default.json
content: "{{ cfg | combine({'IFaceBlackList': cfg.IFaceBlackList | default([]) + netbird_client.iface_blacklist_extra | difference(cfg.IFaceBlackList | default([]))}) | to_nice_json(indent=4, sort_keys=False) }}\n"
mode: "0600"
vars:
cfg: "{{ netbird_config_stopped.content | b64decode | from_json }}"
when: netbird_stopped is changed
- name: Set netbird log level
copy:
dest: /etc/systemd/system/netbird.service.d/20-log-level.conf
content: |
[Service]
ExecStart=
ExecStart=/usr/bin/netbird service run --log-level {{ netbird_client.log_level }} --daemon-addr unix:///var/run/netbird.sock --log-file /var/log/netbird/client.log
mode: "0644"
when: netbird_client.log_level | default('') != ''
notify: restart_netbird
tags: netbird_client_config
+9 -7
View File
@@ -1,26 +1,28 @@
- name: Install Packages - name: Install Packages
# when: docker_file.stat.exists == False
package: package:
name: name:
- ca-certificates - ca-certificates
- curl - curl
- gnupg - gnupg
- name: Add netbird-key # Same keyring path the hand-installed hosts use, so the repository line is identical.
apt_key: - name: Install the netbird repository keyring
url: https://pkgs.wiretrustee.com/debian/public.key ansible.builtin.shell:
state: present cmd: set -o pipefail && curl -fsSL https://pkgs.netbird.io/debian/public.key | gpg --dearmor -o /usr/share/keyrings/netbird-archive-keyring.gpg
executable: /bin/bash
creates: /usr/share/keyrings/netbird-archive-keyring.gpg
- name: Add netbird-repository - name: Add netbird-repository
apt_repository: apt_repository:
repo: "deb https://pkgs.wiretrustee.com/debian stable main" repo: "deb [signed-by=/usr/share/keyrings/netbird-archive-keyring.gpg] https://pkgs.netbird.io/debian stable main"
state: present state: present
filename: netbird filename: netbird
update_cache: yes update_cache: yes
# present, not latest: an upgrade restarts the daemon and drops the tunnels of the node.
- name: Install wireguard & netbird - name: Install wireguard & netbird
package: package:
name: name:
- wireguard - wireguard
- netbird - netbird
state: latest state: present
+28 -7
View File
@@ -1,16 +1,37 @@
- name: Read the netbird status
when: "netbird_client.join_network.setup_key | default('') | length > 0"
command: netbird status -d
register: netbird_status
changed_when: false
failed_when: false
check_mode: false
# Joined means connected to the management server of the vars; without a management_url any server counts.
- name: Join netbird-network - name: Join netbird-network
when: "netbird_client.join_network.setup_key is defined" when:
command: "netbird up --management-url {{ netbird_client.join_network.management_url }} --setup-key {{ netbird_client.join_network.setup_key }}" - "netbird_client.join_network.setup_key | default('') | length > 0"
failed_when: command.rc != 0 - netbird_status.stdout is not search(netbird_joined_pattern, multiline=True)
changed_when: "'Connected' in command.stdout" vars:
register: command netbird_management_url: "{{ netbird_client.join_network.management_url | default('') }}"
netbird_joined_pattern: "^Management: Connected{{ (' to ' ~ (netbird_management_url | regex_escape) ~ '$') if netbird_management_url != '' else '' }}"
netbird_blacklist_extra: "{{ netbird_client.iface_blacklist_extra | default([]) }}"
netbird_up_argv: >-
{{ ['netbird', 'up']
+ (['--management-url', netbird_management_url] if netbird_management_url != '' else [])
+ ['--setup-key', netbird_client.join_network.setup_key]
+ (['--extra-iface-blacklist', netbird_blacklist_extra | join(',')] if netbird_blacklist_extra | length > 0 else []) }}
command:
argv: "{{ netbird_up_argv }}"
no_log: true
changed_when: true
register: join
- name: Wait for netbird-interface to exist - name: Wait for netbird-interface to exist
wait_for: wait_for:
path: "/sys/class/net/wt0" path: "/sys/class/net/wt0"
state: present state: present
when: command.changed when: join is changed
- name: Gather facts to get changes - name: Gather facts to get changes
ansible.builtin.gather_facts: ansible.builtin.gather_facts:
when: command.changed when: join is changed
+1
View File
@@ -2,3 +2,4 @@
- import_tasks: ./join-network.yml - import_tasks: ./join-network.yml
- import_tasks: ./config.yml