I have spent some time trying to convert the curl | bash magic coming from official Caddy docs to an ansible playbook. I mean, I have probably not reduced any risks such as lack of transparency, man-in-the-middle attacks, malicious payloads or missing verification of authenticity associated with curl-pipe-bash procedure just rewriting it to ansible.

We are still using a 3rd party repository, albeit a trusted one. Let's say we do this "the ansible way" for the sake of the exercise. At the time of writing, the official installation for Caddy on Ubuntu 22.04 current LTS looks like this:

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy

As I am not that proficient in ansible at this point, and I have previously focused on automating Arch instead of Ubuntu and delved a lot into the rabbit hole named rootless docker, even such a seemingly trivial task took me some time to figure.

Add repository key

The second line, which serves to add the repository key translates to following ansible task:

- name: Add Cloudsmith repository
  apt_key:
    url: "https://dl.cloudsmith.io/public/caddy/stable/gpg.key"
    state: present

After running this task we can check the result on the target machine via deprecated apt-key list utility:

/etc/apt/trusted.gpg
--------------------
pub   rsa4096 2016-04-01 [SC]
      6576 0C51 EDEA 2017 CEA2  CA15 155B 6D79 CA56 EA34
uid           [ unknown] Caddy Web Server <contact@caddyserver.com>
sub   rsa4096 2020-12-29 [S] [expires: 2025-12-28]

There is a difference against the original script where we simply do not specify the file location to be /usr/share/keyrings/caddy-stable-archive-keyring.gpg. The very exact filename is then referenced in the sources:

curl https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt

Which outputs the following:

# Source: Caddy
# Site: https://github.com/caddyserver/caddy
# Repository: Caddy / stable
# Description: Fast, multi-platform web server with automatic HTTPS

deb [signed-by=/usr/share/keyrings/caddy-stable-archive-keyring.gpg] https://dl.cloudsmith.io/public/caddy/stable/deb/debian any-version main

deb-src [signed-by=/usr/share/keyrings/caddy-stable-archive-keyring.gpg] https://dl.cloudsmith.io/public/caddy/stable/deb/debian any-version main

Note the signed-by attribute which references that key file from above. Need to google a little bit more to understand the implications of omitting the file location altogether, though. Let's take a looks once again on the third line of the script:

curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list

It specifically instructs that the file should be named caddy-stable.list. Fortunately, we can specify the filename via the aptly named filename parameter. Note that the .list extension gets appended automatically.

Source lists

With the freshly gathered knowledge, we can construct the following two tasks:

- name: Add Caddy repository to sources list
  apt_repository:
    repo:
      "deb https://dl.cloudsmith.io/public/caddy/stable/deb/debian
      any-version main"
    state: present
    filename: caddy-stable

- name: Add Caddy src repository to sources list
  apt_repository:
    repo:
      "deb-src https://dl.cloudsmith.io/public/caddy/stable/deb/debian
      any-version main"
    state: present
    filename: caddy-stable

I tried to combine this two tasks into one, hoping that the repo would take array but it appears to accept just a string. Anyway, we can double-check back at the host machine:

cat /etc/apt/sources.list.d/caddy-stable.list

Which quite obviously now outputs the following:

deb https://dl.cloudsmith.io/public/caddy/stable/deb/debian any-version main
deb-src https://dl.cloudsmith.io/public/caddy/stable/deb/debian any-version main

The final playlist thus looks like this:

---
- name: Install Caddy web server
  hosts: my_hosts
  become: true
  become_user: root

  tasks:
    - name: Install required packages
      apt:
        update_cache: yes
        name:
          - debian-keyring
          - debian-archive-keyring
          - apt-transport-https
        state: present

    - name: Add Cloudsmith repository
      apt_key:
        url: "https://dl.cloudsmith.io/public/caddy/stable/gpg.key"
        state: present

    - name: Add Caddy repository to sources list
      apt_repository:
        repo:
          "deb https://dl.cloudsmith.io/public/caddy/stable/deb/debian
          any-version main"
        state: present
        filename: caddy-stable

    - name: Add Caddy src repository to sources list
      apt_repository:
        repo:
          "deb-src https://dl.cloudsmith.io/public/caddy/stable/deb/debian
          any-version main"
        state: present
        filename: caddy-stable

    - name: Install Caddy
      apt:
        update_cache: yes
        name: caddy
        state: present

    - name: Enable and start Caddy service
      service:
        name: caddy
        enabled: yes
        state: started

Enjoy!