--- - name: Tailscale pre-auth key required (skipped if auth key exists) fail: msg: > You must include a Node Pre-Authorization key. Set a `tailscale_auth_key` ansible-vault encrypted variable. You can create this key from: https://login.tailscale.com/admin/settings/authkeys when: tailscale_auth_key is not defined # Print an error message to the console but proceed anyway - name: Unstable warning fail: msg: Installing Tailscale from the unstable branch. This is bleeding edge and may have issues. Be warned. when: release_stability | lower == 'unstable' ignore_errors: yes # this is for debugging purposes # - name: Detecting operating system # debug: # msg: "{{ ansible_distribution }} {{ ansible_distribution_major_version }} ({{ ansible_distribution_release }})" # ansible_distribution == Debian matches Raspbian too - name: Debian and Ubuntu when: ansible_distribution == 'Ubuntu' or ansible_distribution == 'Debian' ansible.builtin.include_tasks: debian.yml - name: Zorin OS when: ansible_distribution == 'Zorin OS' ansible.builtin.include_tasks: zorinos.yml - name: Enable Tailscale service ansible.builtin.systemd: name: "{{ tailscale_service }}" state: started enabled: yes # on a fresh install, this task returns non-zero return code with # "stdout": "Logged out." (task fails, playbook stops here) # why am I bothering with these checks, if all it does is causing the playbook to fail? # - name: Check if Tailscale is connected # ansible.builtin.command: tailscale status # changed_when: false # register: tailscale_status # failed_when: tailscale_status.rc != 0 # - name: Print Tailscale status # debug: # var: tailscale_status # when: verbose | bool # Note the use of include_tasks to nest two loops inside each other # https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html#defining-inner-and-outer-variable-names-with-loop-var #- name: Set IPv4/6 forwarding for clients that advertise routes or exit nodes # block: # Note about the quirky behaviour of lookup() in this context: # Without wantlist=true, this code fails if the tailnets variable contains # just a single tailnet (but not if it contains more than one). # With wantlist=true, this code seems to work for both n==1 and n>1. Weird. # - name: Enable IP forwarding for Tailscale clients # ansible.builtin.include_tasks: ip-forwarding.yml # NOTE, the lookup() returns key/value subkeys (what we want is in "value") # ALSO, watch out: since the lookup() returns our list inside a subkey, # using loop_control.loop_var: only leads to weird errors. We handle this # by assignment inside the ip-forwarding.yml file instead. # https://docs.ansible.com/ansible/latest/collections/ansible/builtin/dict_lookup.html # loop: "{{ lookup('ansible.builtin.dict', tailnets, wantlist=true) }}" # END OF BLOCK # Bring up Tailscale service on clients connected to tailscale.com # I don't think this is not useful for Headscale due to the way keys are set up # initially, at least not until I understand it better - name: Bring up Tailscale.com clients ansible.builtin.include_tasks: tailscale.com.yml # loop: "{{ lookup('ansible.builtin.dict', tailnets, wantlist=true) }}"