feat(base): NetBird agent enrollment concern (mesh)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
98eb09d8ba
commit
44c4978b5f
4 changed files with 111 additions and 0 deletions
|
|
@ -27,3 +27,30 @@ render + validate without applying (used by Molecule).
|
|||
- `make test ROLE=base` — Molecule renders + `nft -c` syntax-checks (never applies; it
|
||||
shares the host kernel). Enforcement + the apply/rollback path are verified at ADR-008
|
||||
Level 2 on staging VMs.
|
||||
|
||||
## Mesh enrollment (NetBird agent)
|
||||
|
||||
Enrols the host as a NetBird *agent* on the self-hosted mesh (ADR-016): installs the
|
||||
pinned `netbird` daemon from the upstream APT repo (keyring in `/etc/apt/keyrings`,
|
||||
mirroring the `docker_host` repo idiom) and runs `netbird up` against the coordinator
|
||||
with a setup key. Tagged `mesh`.
|
||||
|
||||
**Additive only — this concern makes no firewall change.** SSH is already gated to the
|
||||
NetBird overlay interface by the `firewall` concern (`base__firewall_mgmt_interface`,
|
||||
default `wt0`); enrolling a host simply brings that interface up. No port is opened here.
|
||||
|
||||
Enrolment is **opt-in**: `base__mesh_enabled` defaults to `false`, so applying `base` to
|
||||
a host not on the mesh is a no-op for this concern. Re-enrolment is guarded on
|
||||
`netbird status` reporting `Management: Connected`, so re-runs are idempotent. The setup
|
||||
key is sourced from `vault.netbird.setup_key` and passed with `no_log` (it lands on the
|
||||
process argv).
|
||||
|
||||
### Variables
|
||||
|
||||
| Variable | Default | Purpose |
|
||||
|------------------------------|--------------------------------------|---------|
|
||||
| `base__mesh_enabled` | `false` | Opt-in switch — include the concern at all. Set per-host/group to enrol. |
|
||||
| `base__mesh_manage` | `true` | Test gate — when `false`, skips the live network/daemon tasks (apt install, status check, `netbird up`) so Molecule can exercise the wiring without a coordinator. |
|
||||
| `base__mesh_management_url` | `https://netbird.askari.wingu.me` | Coordinator (management) URL. |
|
||||
| `base__mesh_setup_key` | `{{ vault.netbird.setup_key }}` | Enrolment setup key, from vault. |
|
||||
| `base__mesh_version` | `"0.72.4"` | Pinned agent version (matches the coordinator). The exact apt version string is confirmed on-host at deploy. |
|
||||
|
|
|
|||
|
|
@ -20,3 +20,13 @@ base__fail2ban_bantime: 1h
|
|||
base__fail2ban_findtime: 10m
|
||||
# base__ssh_authorised_keys lives in group_vars/all/vars.yml (per-person control keys).
|
||||
base__ssh_authorised_keys: []
|
||||
|
||||
# NetBird mesh agent enrollment (ADR-016). Opt-in: default off so applying `base` to a
|
||||
# host not on the mesh is a no-op for this concern. The live actions (apt install over
|
||||
# the network, `netbird up` against the coordinator) are additionally gated by
|
||||
# base__mesh_manage so Molecule can exercise the wiring without a coordinator.
|
||||
base__mesh_enabled: false
|
||||
base__mesh_manage: true
|
||||
base__mesh_management_url: "https://netbird.askari.wingu.me"
|
||||
base__mesh_setup_key: "{{ vault.netbird.setup_key }}"
|
||||
base__mesh_version: "0.72.4" # match the coordinator; exact apt pin confirmed on-host at deploy
|
||||
|
|
|
|||
|
|
@ -22,3 +22,11 @@
|
|||
apply:
|
||||
tags: [hardening]
|
||||
tags: [hardening]
|
||||
|
||||
- name: NetBird mesh enrollment
|
||||
ansible.builtin.include_tasks:
|
||||
file: mesh.yml
|
||||
apply:
|
||||
tags: [mesh]
|
||||
when: base__mesh_enabled | bool
|
||||
tags: [mesh]
|
||||
|
|
|
|||
66
roles/base/tasks/mesh.yml
Normal file
66
roles/base/tasks/mesh.yml
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
---
|
||||
# NetBird agent enrollment (ADR-016). Additive only — no firewall change here.
|
||||
- name: Install NetBird apt prerequisites
|
||||
ansible.builtin.apt:
|
||||
name: [ca-certificates, curl, gnupg]
|
||||
state: present
|
||||
update_cache: true
|
||||
when: base__mesh_manage | bool
|
||||
tags: [mesh]
|
||||
|
||||
- name: Ensure /etc/apt/keyrings exists
|
||||
ansible.builtin.file:
|
||||
path: /etc/apt/keyrings
|
||||
state: directory
|
||||
mode: "0755"
|
||||
when: base__mesh_manage | bool
|
||||
tags: [mesh]
|
||||
|
||||
- name: Add the NetBird APT GPG key
|
||||
ansible.builtin.get_url:
|
||||
url: https://pkgs.netbird.io/debian/public.key
|
||||
dest: /etc/apt/keyrings/netbird.asc
|
||||
mode: "0644"
|
||||
when: base__mesh_manage | bool
|
||||
tags: [mesh]
|
||||
|
||||
- name: Add the NetBird APT repository
|
||||
ansible.builtin.apt_repository:
|
||||
repo: >-
|
||||
deb [signed-by=/etc/apt/keyrings/netbird.asc]
|
||||
https://pkgs.netbird.io/debian stable main
|
||||
filename: netbird
|
||||
state: present
|
||||
when: base__mesh_manage | bool
|
||||
tags: [mesh]
|
||||
|
||||
# The apt pin string can't be confirmed from docs — it might be a bare "0.72.4" or
|
||||
# carry a packaging suffix. The live deploy task confirms the exact on-host string.
|
||||
- name: Install the NetBird agent (pinned)
|
||||
ansible.builtin.apt:
|
||||
name: "netbird={{ base__mesh_version }}"
|
||||
state: present
|
||||
update_cache: true
|
||||
when: base__mesh_manage | bool
|
||||
tags: [mesh]
|
||||
|
||||
- name: Check current NetBird connection status
|
||||
ansible.builtin.command: netbird status
|
||||
register: _netbird_status
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
when: base__mesh_manage | bool
|
||||
tags: [mesh]
|
||||
|
||||
- name: Enrol this host in the mesh
|
||||
ansible.builtin.command: >-
|
||||
netbird up
|
||||
--management-url {{ base__mesh_management_url }}
|
||||
--setup-key {{ base__mesh_setup_key }}
|
||||
register: _netbird_up
|
||||
changed_when: _netbird_up.rc == 0
|
||||
when:
|
||||
- base__mesh_manage | bool
|
||||
- "'Management: Connected' not in (_netbird_status.stdout | default(''))"
|
||||
no_log: true # setup key is on the argv
|
||||
tags: [mesh]
|
||||
Loading…
Add table
Reference in a new issue