playbooks: replace apt_repository with deb822_repository
ansible.builtin.apt_repository is deprecated and goes away in
ansible-core 2.25.

deb822_repository writes <name>.sources and leaves the old .list file
alone, so each playbook now removes the one apt_repository wrote —
otherwise apt configures the repository twice. The odd filenames come
from apt_repository's default, which collapses non-alphanumerics in the
URI. The module also needs python-debian on the target, so that goes in
alongside the other prerequisites.

Assisted-by: Claude Opus 5 via Claude Code
change xqlzoqrmzztouqmotlwrqtnpnupnuxyx
commit 09321125fd03740779199c638e1d7b02ad4c3b02
author Alpha Chen <alpha@kejadlen.dev>
date
parent msrttvvk
diff --git a/playbooks/docker.yml b/playbooks/docker.yml
index 7cbc9ac..867d8c4 100644
--- a/playbooks/docker.yml
+++ b/playbooks/docker.yml
@@ -13,6 +13,7 @@
           - ca-certificates
           - curl
           - gnupg # for the signing keys
+          - python3-debian # for ansible.builtin.deb822_repository
         state: present
         update_cache: true
 
@@ -30,14 +31,25 @@
       register: dpkg_arch
       changed_when: false
 
+    # Left behind by ansible.builtin.apt_repository; apt reads both formats, so
+    # leaving it would configure the repository twice.
+    - name: Remove one-line Docker repository
+      ansible.builtin.file:
+        path: /etc/apt/sources.list.d/download_docker_com_linux_debian.list
+        state: absent
+
     # echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \
     #   https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
     #   | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
     - name: Add Docker repository
-      ansible.builtin.apt_repository:
-        repo: >-
-          deb [arch={{ dpkg_arch.stdout }} signed-by=/etc/apt/keyrings/docker.asc]
-          https://download.docker.com/linux/debian {{ ansible_facts["distribution_release"] }} stable
+      ansible.builtin.deb822_repository:
+        name: docker
+        types: deb
+        uris: https://download.docker.com/linux/debian
+        suites: '{{ ansible_facts["distribution_release"] }}'
+        components: stable
+        architectures: "{{ dpkg_arch.stdout }}"
+        signed_by: /etc/apt/keyrings/docker.asc
         state: present
 
     # sudo apt-get update
diff --git a/playbooks/syncthing.yml b/playbooks/syncthing.yml
index a592fa0..4772b0d 100644
--- a/playbooks/syncthing.yml
+++ b/playbooks/syncthing.yml
@@ -12,6 +12,13 @@
           - ansible_facts["distribution"] == "Debian"
         fail_msg: "This playbook only supports Debian distributions"
 
+    # ansible.builtin.deb822_repository needs python-debian on the target.
+    - name: Install required packages
+      ansible.builtin.apt:
+        name: python3-debian
+        state: present
+        update_cache: true
+
     # sudo mkdir -p /etc/apt/keyrings
     - name: Create APT keyrings directory
       ansible.builtin.file:
@@ -26,12 +33,24 @@
         dest: /etc/apt/keyrings/syncthing-archive-keyring.gpg
         mode: '0644'
 
+    # Left behind by ansible.builtin.apt_repository; apt reads both formats, so
+    # leaving it would configure the repository twice.
+    - name: Remove one-line Syncthing repository
+      ansible.builtin.file:
+        path: /etc/apt/sources.list.d/apt_syncthing_net.list
+        state: absent
+
     # echo "deb [signed-by=/etc/apt/keyrings/syncthing-archive-keyring.gpg] \
     #   https://apt.syncthing.net/ syncthing stable-v2" \
     #   | sudo tee /etc/apt/sources.list.d/syncthing.list
     - name: Add Syncthing repository
-      ansible.builtin.apt_repository:
-        repo: deb [signed-by=/etc/apt/keyrings/syncthing-archive-keyring.gpg] https://apt.syncthing.net/ syncthing stable-v2
+      ansible.builtin.deb822_repository:
+        name: syncthing
+        types: deb
+        uris: https://apt.syncthing.net/
+        suites: syncthing
+        components: stable-v2
+        signed_by: /etc/apt/keyrings/syncthing-archive-keyring.gpg
         state: present
 
     # sudo apt-get update
diff --git a/playbooks/tailscale.yml b/playbooks/tailscale.yml
index 9f786d7..2b2bf5f 100644
--- a/playbooks/tailscale.yml
+++ b/playbooks/tailscale.yml
@@ -11,6 +11,13 @@
           - ansible_facts["distribution"] == "Debian"
         fail_msg: "This playbook only supports Debian distributions"
 
+    # ansible.builtin.deb822_repository needs python-debian on the target.
+    - name: Install required packages
+      ansible.builtin.apt:
+        name: python3-debian
+        state: present
+        update_cache: true
+
     # curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.noarmor.gpg | sudo tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
     - name: Download Tailscale package signing key
       ansible.builtin.get_url:
@@ -18,13 +25,22 @@
         dest: /usr/share/keyrings/tailscale-archive-keyring.gpg
         mode: "0644"
 
+    # Left behind by ansible.builtin.apt_repository; apt reads both formats, so
+    # leaving it would configure the repository twice.
+    - name: Remove one-line Tailscale repository
+      ansible.builtin.file:
+        path: /etc/apt/sources.list.d/tailscale.list
+        state: absent
+
     # curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.tailscale-keyring.list | sudo tee /etc/apt/sources.list.d/tailscale.list
     - name: Add Tailscale repository
-      ansible.builtin.apt_repository:
-        repo: >-
-          deb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg]
-          https://pkgs.tailscale.com/stable/debian {{ ansible_facts["distribution_release"] }} main
-        filename: tailscale
+      ansible.builtin.deb822_repository:
+        name: tailscale
+        types: deb
+        uris: https://pkgs.tailscale.com/stable/debian
+        suites: '{{ ansible_facts["distribution_release"] }}'
+        components: main
+        signed_by: /usr/share/keyrings/tailscale-archive-keyring.gpg
         state: present
 
     # sudo apt-get update