diff --git a/ansible/services/headscale/deploy_headscale_playbook.yml b/ansible/services/headscale/deploy_headscale_playbook.yml index 1293043..523424d 100644 --- a/ansible/services/headscale/deploy_headscale_playbook.yml +++ b/ansible/services/headscale/deploy_headscale_playbook.yml @@ -1,11 +1,12 @@ - name: Deploy headscale and configure Caddy reverse proxy - hosts: vipy + hosts: spacey become: no vars_files: - ../../infra_vars.yml - ./headscale_vars.yml vars: headscale_domain: "{{ headscale_subdomain }}.{{ root_domain }}" + headscale_base_domain: "tailnet.{{ root_domain }}" tasks: - name: Install required packages @@ -34,6 +35,16 @@ path: /tmp/headscale.deb state: absent + - name: Ensure headscale user exists + become: yes + user: + name: headscale + system: yes + shell: /usr/sbin/nologin + home: /var/lib/headscale + create_home: yes + state: present + - name: Create headscale data directory become: yes file: @@ -50,17 +61,7 @@ state: directory owner: headscale group: headscale - mode: '0755' - - - name: Ensure headscale user exists - become: yes - user: - name: headscale - system: yes - shell: /usr/sbin/nologin - home: /var/lib/headscale - create_home: yes - state: present + mode: '0770' - name: Ensure headscale user owns data directory become: yes @@ -69,6 +70,14 @@ owner: headscale group: headscale recurse: yes + mode: '0750' + + - name: Add counterweight user to headscale group + become: yes + user: + name: counterweight + groups: headscale + append: yes - name: Create ACL policies file become: yes @@ -84,7 +93,7 @@ } owner: headscale group: headscale - mode: '0644' + mode: '0640' notify: Restart headscale - name: Deploy headscale configuration file @@ -135,17 +144,17 @@ path: /etc/headscale/acl.json dns: - base_domain: tailnet.contrapeso.xyz + base_domain: {{ headscale_base_domain | quote }} magic_dns: true search_domains: - - tailnet.contrapeso.xyz + - {{ headscale_base_domain | quote }} nameservers: global: - 1.1.1.1 - 1.0.0.1 owner: root - group: root - mode: '0644' + group: headscale + mode: '0640' notify: Restart headscale - name: Test headscale configuration @@ -165,6 +174,21 @@ enabled: yes state: started + - name: Wait for headscale unix socket to be ready + become: yes + wait_for: + path: /var/run/headscale/headscale.sock + state: present + timeout: 60 + delay: 2 + + - name: Create headscale namespace if it doesn't exist + become: yes + command: headscale users create {{ headscale_namespace }} + register: create_namespace_result + failed_when: create_namespace_result.rc != 0 and 'already exists' not in create_namespace_result.stderr and 'UNIQUE constraint' not in create_namespace_result.stderr + changed_when: create_namespace_result.rc == 0 + - name: Allow HTTPS through UFW become: yes ufw: diff --git a/ansible/services/headscale/headscale_vars.yml b/ansible/services/headscale/headscale_vars.yml index 5dff982..7bc2c9b 100644 --- a/ansible/services/headscale/headscale_vars.yml +++ b/ansible/services/headscale/headscale_vars.yml @@ -6,6 +6,9 @@ headscale_grpc_port: 50443 # Version headscale_version: "0.26.1" +# Namespace for devices (users in headscale terminology) +headscale_namespace: counter-net + # Caddy caddy_sites_dir: /etc/caddy/sites-enabled @@ -13,7 +16,7 @@ caddy_sites_dir: /etc/caddy/sites-enabled headscale_data_dir: /var/lib/headscale # Remote access -remote_host: "{{ groups['vipy'][0] }}" +remote_host: "{{ groups['spacey'][0] }}" remote_user: "{{ hostvars[remote_host]['ansible_user'] }}" remote_key_file: "{{ hostvars[remote_host]['ansible_ssh_private_key_file'] | default('') }}" diff --git a/ansible/services/lnbits/deploy_lnbits_playbook.yml b/ansible/services/lnbits/deploy_lnbits_playbook.yml index 75b24f7..80cc7b2 100644 --- a/ansible/services/lnbits/deploy_lnbits_playbook.yml +++ b/ansible/services/lnbits/deploy_lnbits_playbook.yml @@ -19,28 +19,91 @@ - name: Install required system packages apt: name: - - python3.11 - - python3.11-venv + - python3 - python3-pip - git - curl - build-essential - pkg-config - libffi-dev + - libssl-dev + - zlib1g-dev + - libbz2-dev + - libreadline-dev + - libsqlite3-dev + - libncursesw5-dev + - xz-utils + - tk-dev + - libxml2-dev + - libxmlsec1-dev + - liblzma-dev state: present update_cache: yes - - name: Install Poetry + - name: Install pyenv shell: | - curl -sSL https://install.python-poetry.org | python3 - + curl https://pyenv.run | bash args: - creates: "{{ lookup('env', 'HOME') }}/.local/bin/poetry" + creates: "/home/{{ ansible_user }}/.pyenv" + become: yes + become_user: "{{ ansible_user }}" + environment: + HOME: "/home/{{ ansible_user }}" + + - name: Add pyenv to PATH + lineinfile: + path: "/home/{{ ansible_user }}/.bashrc" + line: 'export PYENV_ROOT="$HOME/.pyenv"' + state: present become: yes become_user: "{{ ansible_user }}" + - name: Add pyenv init to bashrc + lineinfile: + path: "/home/{{ ansible_user }}/.bashrc" + line: 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' + state: present + become: yes + become_user: "{{ ansible_user }}" + + - name: Add pyenv init to bashrc (second line) + lineinfile: + path: "/home/{{ ansible_user }}/.bashrc" + line: 'eval "$(pyenv init -)"' + state: present + become: yes + become_user: "{{ ansible_user }}" + + - name: Install Python 3.12 via pyenv + shell: | + export PYENV_ROOT="$HOME/.pyenv" + export PATH="$PYENV_ROOT/bin:$PATH" + eval "$(pyenv init -)" + pyenv install -s 3.12.7 + pyenv global 3.12.7 + args: + creates: "/home/{{ ansible_user }}/.pyenv/versions/3.12.7/bin/python3.12" + become: yes + become_user: "{{ ansible_user }}" + environment: + HOME: "/home/{{ ansible_user }}" + + - name: Install Poetry + shell: | + export PYENV_ROOT="$HOME/.pyenv" + export PATH="$PYENV_ROOT/bin:$PYENV_ROOT/versions/3.12.7/bin:$PATH" + eval "$(pyenv init -)" + curl -sSL https://install.python-poetry.org | python3 - + args: + creates: "/home/{{ ansible_user }}/.local/bin/poetry" + become: yes + become_user: "{{ ansible_user }}" + environment: + HOME: "/home/{{ ansible_user }}" + - name: Add Poetry to PATH lineinfile: - path: "{{ lookup('env', 'HOME') }}/.bashrc" + path: "/home/{{ ansible_user }}/.bashrc" line: 'export PATH="$HOME/.local/bin:$PATH"' state: present become: yes @@ -60,10 +123,27 @@ group: "{{ ansible_user }}" recurse: yes - - name: Install LNBits dependencies - command: $HOME/.local/bin/poetry install --only main + - name: Configure Poetry to use Python 3.12 + command: /home/{{ ansible_user }}/.local/bin/poetry env use /home/{{ ansible_user }}/.pyenv/versions/3.12.7/bin/python3.12 args: chdir: "{{ lnbits_dir }}/lnbits" + become: yes + become_user: "{{ ansible_user }}" + environment: + HOME: "/home/{{ ansible_user }}" + PATH: "/home/{{ ansible_user }}/.local/bin:/home/{{ ansible_user }}/.pyenv/versions/3.12.7/bin:/home/{{ ansible_user }}/.pyenv/bin:{{ ansible_env.PATH }}" + PYENV_ROOT: "/home/{{ ansible_user }}/.pyenv" + + - name: Install LNBits dependencies + command: /home/{{ ansible_user }}/.local/bin/poetry install --only main + args: + chdir: "{{ lnbits_dir }}/lnbits" + become: yes + become_user: "{{ ansible_user }}" + environment: + HOME: "/home/{{ ansible_user }}" + PATH: "/home/{{ ansible_user }}/.local/bin:/home/{{ ansible_user }}/.pyenv/versions/3.12.7/bin:/home/{{ ansible_user }}/.pyenv/bin:{{ ansible_env.PATH }}" + PYENV_ROOT: "/home/{{ ansible_user }}/.pyenv" - name: Copy .env.example to .env copy: @@ -111,6 +191,8 @@ Restart=always RestartSec=30 Environment=PYTHONUNBUFFERED=1 + Environment="PATH=/home/{{ ansible_user }}/.local/bin:/home/{{ ansible_user }}/.pyenv/versions/3.12.7/bin:/home/{{ ansible_user }}/.pyenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + Environment="PYENV_ROOT=/home/{{ ansible_user }}/.pyenv" [Install] WantedBy=multi-user.target @@ -143,6 +225,8 @@ insertafter: EOF state: present backup: yes + create: yes + mode: '0644' - name: Create Caddy reverse proxy configuration for lnbits copy: