--- # ============================================================================= # NetBird v1.6 Deployment - SSL Mode with Public IP (Self-Signed) # ============================================================================= # Uses Caddy's internal CA with self-signed certificates for HTTPS on IP. # Browser will show certificate warning - this is expected. # # Note: Let's Encrypt supports IP certificates now, but Caddy's implementation # is incomplete (GitHub issue #7399). Using self-signed as reliable fallback. # # Prerequisites: # 1. VPS with public IP address # 2. Port 80 and 443 accessible # 3. Create group_vars/vault.yml from vault.yml.example # # Run: # ansible-playbook -i inventory.yml playbook-ssl-ip.yml --ask-vault-pass # ============================================================================= - name: Deploy NetBird v1.6 (SSL Mode - Public IP Self-Signed) hosts: netbird_servers become: true gather_facts: true vars_files: - group_vars/netbird_servers.yml - group_vars/vault.yml pre_tasks: - name: Set SSL-IP variables (override group_vars) ansible.builtin.set_fact: netbird_domain: "{{ ansible_default_ipv4.address }}" netbird_protocol: "https" relay_protocol: "rels" relay_port: 443 signal_port: 443 single_account_domain: "netbird.local" tasks: # ========================================================================= # Prerequisites # ========================================================================= - name: Update apt cache ansible.builtin.apt: update_cache: true cache_valid_time: 3600 - name: Install prerequisites ansible.builtin.apt: name: - apt-transport-https - ca-certificates - curl - gnupg - lsb-release - jq state: present # ========================================================================= # Docker Installation # ========================================================================= - name: Check if Docker is installed ansible.builtin.command: docker --version register: docker_installed changed_when: false failed_when: false - name: Create keyrings directory ansible.builtin.file: path: /etc/apt/keyrings state: directory mode: "0755" when: docker_installed.rc != 0 - name: Add Docker GPG key ansible.builtin.shell: | curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg chmod a+r /etc/apt/keyrings/docker.gpg args: creates: /etc/apt/keyrings/docker.gpg when: docker_installed.rc != 0 - name: Add Docker repository ansible.builtin.apt_repository: repo: "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable" state: present filename: docker when: docker_installed.rc != 0 - name: Install Docker packages ansible.builtin.apt: name: - docker-ce - docker-ce-cli - containerd.io - docker-buildx-plugin - docker-compose-plugin state: present update_cache: true when: docker_installed.rc != 0 - name: Start and enable Docker ansible.builtin.systemd: name: docker state: started enabled: true # ========================================================================= # NetBird Directory Structure # ========================================================================= - name: Create NetBird directory ansible.builtin.file: path: "{{ netbird_base_dir }}" state: directory mode: "0755" # ========================================================================= # Deploy Configuration Files # ========================================================================= - name: Deploy docker-compose.yml ansible.builtin.template: src: templates/docker-compose.yml.j2 dest: "{{ netbird_base_dir }}/docker-compose.yml" mode: "0644" - name: Deploy Caddyfile (SSL-IP mode) ansible.builtin.template: src: templates/Caddyfile-ssl-ip.j2 dest: "{{ netbird_base_dir }}/Caddyfile" mode: "0644" - name: Deploy management.json ansible.builtin.template: src: templates/management.json.j2 dest: "{{ netbird_base_dir }}/management.json" mode: "0644" - name: Deploy dashboard.env ansible.builtin.template: src: templates/dashboard.env.j2 dest: "{{ netbird_base_dir }}/dashboard.env" mode: "0640" - name: Deploy relay.env ansible.builtin.template: src: templates/relay.env.j2 dest: "{{ netbird_base_dir }}/relay.env" mode: "0640" - name: Deploy turnserver.conf ansible.builtin.template: src: templates/turnserver.conf.j2 dest: "{{ netbird_base_dir }}/turnserver.conf" mode: "0644" # ========================================================================= # Firewall (UFW) # ========================================================================= - name: Install UFW ansible.builtin.apt: name: ufw state: present - name: Allow SSH community.general.ufw: rule: allow port: "22" proto: tcp - name: Allow HTTP (for ACME challenge) community.general.ufw: rule: allow port: "80" proto: tcp - name: Allow HTTPS community.general.ufw: rule: allow port: "443" proto: tcp - name: Allow HTTPS UDP (HTTP/3) community.general.ufw: rule: allow port: "443" proto: udp - name: Allow TURN UDP community.general.ufw: rule: allow port: "3478" proto: udp - name: Allow TURN TCP community.general.ufw: rule: allow port: "3478" proto: tcp - name: Enable UFW community.general.ufw: state: enabled policy: deny # ========================================================================= # Start Services # ========================================================================= - name: Pull Docker images ansible.builtin.command: cmd: docker compose pull chdir: "{{ netbird_base_dir }}" changed_when: true - name: Start NetBird services ansible.builtin.command: cmd: docker compose up -d chdir: "{{ netbird_base_dir }}" changed_when: true # ========================================================================= # Wait for Services # ========================================================================= - name: Wait for Management API to be available ansible.builtin.uri: url: "https://{{ netbird_domain }}/api/users" method: GET status_code: [200, 401, 403] validate_certs: false register: api_check until: api_check.status in [200, 401, 403] retries: 30 delay: 10 # ========================================================================= # Display Summary # ========================================================================= - name: Display deployment status ansible.builtin.debug: msg: | ============================================ NetBird v1.6 Deployed Successfully! (SSL-IP) ============================================ Dashboard: https://{{ netbird_domain }} Note: Using self-signed certificate (Caddy internal CA). Your browser will show a certificate warning - accept it to proceed. Initial Setup: 1. Access the dashboard (accept certificate warning) 2. Create your first user (admin) 3. Generate setup keys for battalions Connect peers with: netbird up --management-url https://{{ netbird_domain }} --setup-key View logs: ssh root@{{ ansible_host }} "cd {{ netbird_base_dir }} && docker compose logs -f" ============================================