spantaleev / matrix-docker-ansible-deploy

🐳 Matrix (An open network for secure, decentralized communication) server setup using Ansible and Docker
GNU Affero General Public License v3.0
4.78k stars 1.03k forks source link

Traefik DNS-01 Challenge - error="no domain was given" - OVH API #3034

Open pm-McFly opened 9 months ago

pm-McFly commented 9 months ago

Playbook Configuration:

My vars.yml file looks like this:

---
# The bare domain name which represents your Matrix identity.
# Matrix user ids for your server will be of the form (`@user:<matrix-domain>`).
#
# Note: this playbook does not touch the server referenced here.
# Installation happens on another server ("matrix.<matrix-domain>").
#
# If you've deployed using the wrong domain, you'll have to run the Uninstalling step,
# because you can't change the Domain after deployment.
#
# Example value: example.com
matrix_domain: domain.tld
# matrix_fqn_domain: matrix.domain.tld
# The Matrix homeserver software to install.
# See:
#  - `roles/custom/matrix-base/defaults/main.yml` for valid options
# - the `docs/configuring-playbook-IMPLEMENTATION_NAME.md` documentation page, if one is available for your implementation choice
matrix_homeserver_implementation: synapse

# A secret used as a base, for generating various other secrets.
# You can put any string here, but generating a strong one is preferred (e.g. `pwgen -s 64 1`).
matrix_homeserver_generic_secret_key: 'SECRET'

# By default, the playbook manages its own Traefik (https://doc.traefik.io/traefik/) reverse-proxy server.
# It will retrieve SSL certificates for you on-demand and forward requests to all other components.
# For alternatives, see `docs/configuring-playbook-own-webserver.md`.
matrix_playbook_reverse_proxy_type: playbook-managed-traefik

# This is something which is provided to Let's Encrypt when retrieving SSL certificates for domains.
#
# In case SSL renewal fails at some point, you'll also get an email notification there.
#
# If you decide to use another method for managing SSL certificates (different than the default Let's Encrypt),
# you won't be required to define this variable (see `docs/configuring-playbook-ssl-certificates.md`).
#
# Example value: someone@example.com
devture_traefik_config_certificatesResolvers_acme_email: 'email@domain.tld'

# A Postgres password to use for the superuser Postgres user (called `matrix` by default).
#
# The playbook creates additional Postgres users and databases (one for each enabled service)
# using this superuser account.
devture_postgres_connection_password: 'PASSWORD'

# By default, we configure Coturn's external IP address using the value specified for `ansible_host` in your `inventory/hosts` file.
# If this value is an external IP address, you can skip this section.
#
# If `ansible_host` is not the server's external IP address, you have 2 choices:
# 1. Uncomment the line below, to allow IP address auto-detection to happen (more on this below)
# 2. Uncomment and adjust the line below to specify an IP address manually
#
# By default, auto-detection will be attempted using the `https://ifconfig.co/json` API.
# Default values for this are specified in `matrix_coturn_turn_external_ip_address_auto_detection_*` variables in the Coturn role
# (see `roles/custom/matrix-coturn/defaults/main.yml`).
#
# If your server has multiple IP addresses, you may define them in another variable which allows a list of addresses.
# Example: `matrix_coturn_turn_external_ip_addresses: ['1.2.3.4', '4.5.6.7']`
#
# matrix_coturn_turn_external_ip_address: ''

#
## SRV Delegation
#
matrix_well_known_matrix_server_enabled: false

# To serve the federation from any domain, as long as the path match
matrix_nginx_proxy_container_labels_traefik_proxy_matrix_federation_rule: PathPrefix(`/_matrix`)

# To let Traefik know which domains' certificates to serve
matrix_nginx_proxy_container_labels_additional_labels: |
  traefik.http.routers.matrix-nginx-proxy-matrix-federation.tls.domains.main="domain.tld"
  traefik.http.routers.matrix-nginx-proxy-matrix-federation.tls.domains.sans="*.domain.tld"

# Add a new ACME configuration without having to disable the default one, since it would have a wide range of side effects
devture_traefik_configuration_extension_yaml: |
  certificatesResolvers:
    dns:
      acme:
        # To use a staging endpoint for testing purposes, uncomment the line below.
        # caServer: https://acme-staging-v02.api.letsencrypt.org/directory
        email: {{ devture_traefik_config_certificatesResolvers_acme_email | to_json }}
        dnsChallenge:
          provider: ovh
          resolvers:
            - "1.1.1.1:53"
            - "8.8.8.8:53"
        storage: {{ devture_traefik_config_certificatesResolvers_acme_storage | to_json }}

# Instruct thep laybook to use the new ACME configuration
devture_traefik_certResolver_primary: "dns"

# Configure the environment variables needed by Traefik to automate the ACME DNS Challenge
devture_traefik_environment_variables: |
  OVH_APPLICATION_KEY=app_key
  OVH_APPLICATION_SECRET=app_secret
  OVH_CONSUMER_KEY=consumer_key
  OVH_ENDPOINT=ovh-eu
  #  LEGO_DISABLE_CNAME_SUPPORT=true

devture_traefik_config_log_level: DEBUG

# Only depend on docker.service, this removes the dependency on the certificate exporter, might imply the need to manually restart Coturn on the first installation once the certificates are obtained, afterwards, the reload service should handle things
matrix_coturn_systemd_required_services_list: ['docker.service']

# This changes the path of the loaded certificate, while maintaining the original functionality, we're now loading the wildcard certificate.
matrix_coturn_container_additional_volumes: |
  {{
    (
      [
       {
         'src': (matrix_ssl_config_dir_path + '/live/*.' + matrix_domain + '/fullchain.pem'),
         'dst': '/fullchain.pem',
         'options': 'ro',
       },
       {
         'src': (matrix_ssl_config_dir_path + '/live/*.' + matrix_domain + '/privkey.pem'),
         'dst': '/privkey.pem',
         'options': 'ro',
       },
      ] if matrix_playbook_reverse_proxy_type in ['playbook-managed-nginx', 'other-nginx-non-container'] and matrix_coturn_tls_enabled else []
    )
    +
    (
      [
       {
         'src': (devture_traefik_certs_dumper_dumped_certificates_dir_path +  '/*.' + matrix_domain + '/certificate.crt'),
         'dst': '/certificate.crt',
         'options': 'ro',
       },
       {
         'src': (devture_traefik_certs_dumper_dumped_certificates_dir_path +  '/*.' + matrix_domain + '/privatekey.key'),
         'dst': '/privatekey.key',
         'options': 'ro',
       },
      ] if matrix_playbook_reverse_proxy_type in ['playbook-managed-traefik', 'other-traefik-container'] and devture_traefik_certs_dumper_enabled and matrix_coturn_tls_enabled else []
    )
  }}

#
## Synapse
#
#matrix_synapse_workers_enabled: true
matrix_synapse_report_stats: true

#
## Synapse Admin UI
#
matrix_synapse_admin_enabled: true

#
## Shared Secret Auth
#
matrix_synapse_ext_password_provider_shared_secret_auth_enabled: true
matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret: 'SECRET'

#
## Hydrogen
#
matrix_client_hydrogen_enabled: true

#
## synapse_auto_compressor
#
matrix_synapse_auto_compressor_enabled: true

#
## sliding proxy
#
matrix_sliding_sync_enabled: true

# vim:ft=yaml

Matrix Server:

Ansible: Running on my laptop to deploy on my VPS hosted by OVH.

pmarty in matrix-docker-ansible-deploy on git master took 17s 
ubnt nu > : ansible --version                                                                                                    
ansible [core 2.16.1]
  config file = /home/pmarty/Documents/misc/matrix-docker-ansible-deploy/ansible.cfg
  configured module search path = ['/home/pmarty/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/pmarty/.local/pipx/venvs/ansible/lib/python3.11/site-packages/ansible
  ansible collection location = /home/pmarty/.ansible/collections:/usr/share/ansible/collections
  executable location = /home/pmarty/.local/bin/ansible
  python version = 3.11.6 (main, Oct  8 2023, 05:06:43) [GCC 13.2.0] (/home/pmarty/.local/pipx/venvs/ansible/bin/python)
  jinja version = 3.1.2
  libyaml = True

pmarty in matrix-docker-ansible-deploy on git master 
ubnt nu > : just --version                                                                                                                                 
just 1.14.0

pmarty in matrix-docker-ansible-deploy on git master 
ubnt nu > : pipx --version                                                                                                                                 
1.2.0

Problem description:

Traefik struggles at generating the SSL certificate via the DNS-01 challenge. When opening the logs I found out that apparently the domain list was empty, and thus no domain could be treated. Although when crawling over the OVH API manually myself I can obtain the domain list correctly.

I have modified the permissions to be more permissive on the API usage but same result.

déc. 12 09:21:16 matrix-host matrix-traefik[95264]: time="2023-12-12T08:21:16Z" level=info msg="Configuration loaded from file: /config/traefik.yml"
déc. 12 09:21:16 matrix-host matrix-traefik[95264]: time="2023-12-12T08:21:16Z" level=info msg="Traefik version 2.10.7 built on 2023-12-06T15:54:59Z"
déc. 12 09:21:16 matrix-host matrix-traefik[95264]: time="2023-12-12T08:21:16Z" level=info msg="\nStats collection is disabled.\nHelp us improve Traefik by turning this feature on :)\nMore details on: https://doc.traefik.io/traefik/contributing/data-collection/\n"
déc. 12 09:21:16 matrix-host matrix-traefik[95264]: time="2023-12-12T08:21:16Z" level=info msg="Starting provider aggregator aggregator.ProviderAggregator"
déc. 12 09:21:16 matrix-host matrix-traefik[95264]: time="2023-12-12T08:21:16Z" level=info msg="Starting provider *file.Provider"
déc. 12 09:21:16 matrix-host matrix-traefik[95264]: time="2023-12-12T08:21:16Z" level=error msg="Error while building configuration (for the first time): http cannot be a standalone element (type *dynamic.HTTPConfiguration)" providerName=file
déc. 12 09:21:16 matrix-host matrix-traefik[95264]: time="2023-12-12T08:21:16Z" level=info msg="Starting provider *traefik.Provider"
déc. 12 09:21:16 matrix-host matrix-traefik[95264]: time="2023-12-12T08:21:16Z" level=info msg="Starting provider *docker.Provider"
déc. 12 09:21:16 matrix-host matrix-traefik[95264]: time="2023-12-12T08:21:16Z" level=info msg="Starting provider *acme.ChallengeTLSALPN"
déc. 12 09:21:16 matrix-host matrix-traefik[95264]: time="2023-12-12T08:21:16Z" level=info msg="Starting provider *acme.Provider"
déc. 12 09:21:16 matrix-host matrix-traefik[95264]: time="2023-12-12T08:21:16Z" level=info msg="Testing certificate renew..." ACME CA="https://acme-v02.api.letsencrypt.org/directory" providerName=default.acme
déc. 12 09:21:16 matrix-host matrix-traefik[95264]: time="2023-12-12T08:21:16Z" level=info msg="Starting provider *acme.Provider"
déc. 12 09:21:16 matrix-host matrix-traefik[95264]: time="2023-12-12T08:21:16Z" level=info msg="Testing certificate renew..." providerName=dns.acme ACME CA="https://acme-v02.api.letsencrypt.org/directory"
déc. 12 09:21:17 matrix-host matrix-traefik[95264]: time="2023-12-12T08:21:17Z" level=warning msg="The domain { []} is duplicated in the configuration but will be process by ACME provider only once." providerName=dns.acme ACME CA="https://acme-v02.api.letsencrypt.org/directory" routerName=matrix-nginx-proxy-matrix-federation@docker rule="Host(`matrix.domain.tld`)"
déc. 12 09:21:17 matrix-host matrix-traefik[95264]: time="2023-12-12T08:21:17Z" level=error msg="Unable to obtain ACME certificate for domains \"\"" providerName=dns.acme error="no domain was given" ACME CA="https://acme-v02.api.letsencrypt.org/directory" routerName=matrix-nginx-proxy-matrix-federation@docker rule="Host(`matrix.domain.tld`)"
déc. 12 09:21:21 matrix-host matrix-traefik[95264]: time="2023-12-12T08:21:21Z" level=warning msg="The domain { []} is duplicated in the configuration but will be process by ACME provider only once." rule="Host(`matrix.domain.tld`)" providerName=dns.acme ACME CA="https://acme-v02.api.letsencrypt.org/directory" routerName=matrix-nginx-proxy-matrix-federation@docker
déc. 12 09:21:21 matrix-host matrix-traefik[95264]: time="2023-12-12T08:21:21Z" level=error msg="Unable to obtain ACME certificate for domains \"\"" rule="Host(`matrix.domain.tld`)" error="no domain was given" providerName=dns.acme ACME CA="https://acme-v02.api.letsencrypt.org/directory" routerName=matrix-nginx-proxy-matrix-federation@docker
déc. 12 09:21:23 matrix-host matrix-traefik[95264]: time="2023-12-12T08:21:23Z" level=warning msg="The domain { []} is duplicated in the configuration but will be process by ACME provider only once." routerName=matrix-nginx-proxy-matrix-federation@docker rule="Host(`matrix.domain.tld`)" providerName=dns.acme ACME CA="https://acme-v02.api.letsencrypt.org/directory"
déc. 12 09:21:23 matrix-host matrix-traefik[95264]: time="2023-12-12T08:21:23Z" level=error msg="Unable to obtain ACME certificate for domains \"\"" error="no domain was given" providerName=dns.acme ACME CA="https://acme-v02.api.letsencrypt.org/directory" routerName=matrix-nginx-proxy-matrix-federation@docker rule="Host(`matrix.domain.tld`)"

I have tried to tweak on different config and parameters but nothing seems to be working more properly.

A Debug version of the log is available attached. traefik-dns-01-debug.txt

Additional context I have a domain name and want to host different services (matrix, webserver, mail, etc.). As the VM I am using for the matrix is isolated from the rest I rather use the DNS SRV method so I can have a dediacted instance for matrix and point the domain on another IP.

domain type target
domain.tld. A IP A
*.domain.tld. CNAME domain.tld.
www.domain.tld. CNAME domain.tld.
matrix.domain.tld. A IP B
element.domain.tld. CNAME matrix.domain.tld.
hydrogen.domain.tld. CNAME matrix.domain.tld.
_matrix._tcp.domain.tld. SRV 10 0 8448 matrix.domain.tld.
_matrix-identity._tcp.domain.tld. SRV 10 0 443 matrix.domain.tld.
pm-McFly commented 9 months ago

I have just tried my API credentials through a manual certbot test and it seems to be okay:

pmarty in ~
ubnt nu x : sudo certbot certonly --dns-ovh --dns-ovh-credentials ~/.secrets/certbot/ovh.ini -d domain.tld
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): email@domain.tld

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf. You must
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: y

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: y
Account registered.
Requesting a certificate for domain.tld
Unsafe permissions on credentials configuration file: /home/pmarty/.secrets/certbot/ovh.ini
Waiting 120 seconds for DNS changes to propagate

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/domain.tld/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/domain.tld/privkey.pem
This certificate expires on 2024-03-11.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
 * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
 * Donating to EFF:                    https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

certbot was installed on my ubuntu laptop via snap.

pm-McFly commented 9 months ago

Same results when using the python3-certbot and python3-certbot-dns-ovh packages on the Debian server.

If someone has an idea regarding the configuration?

pm-McFly commented 9 months ago

Waiting for any leads, I have modified the configuration in order to serve my own certificates from traefik. I have tried and validated two options:

1. Serving certificates generated outside the server (Upload through ansible)

#
## SRV Delegation
#
matrix_well_known_matrix_server_enabled: false

# To serve the federation from any domain, as long as the path match
matrix_nginx_proxy_container_labels_traefik_proxy_matrix_federation_rule: PathPrefix(`/_matrix`)

# To let Traefik know which domains' certificates to serve
matrix_nginx_proxy_container_labels_additional_labels: |
  traefik.http.routers.matrix-nginx-proxy-matrix-federation.tls.domains.main="domain.tld"
  traefik.http.routers.matrix-nginx-proxy-matrix-federation.tls.domains.sans="*.domain.tld"

# Disable ACME / Let's Encrypt support.
devture_traefik_config_certificatesResolvers_acme_enabled: false

# Disabling ACME support (above) automatically disables the creation of the SSL directory.
# Force-enable it here, because we'll add our certificate files there.
devture_traefik_ssl_dir_enabled: true

# Tell Traefik to load our custom configuration file (certificates.yml).
# The file is created below, in `aux_file_definitions`.
# The `/config/..` path is an in-container path, not a path on the host (like `/matrix/traefik/config`). Do not change it!
devture_traefik_configuration_extension_yaml: |
  providers:
    file:
      filename: /config/certificates.yml
      watch: true

# Use the aux role to create our custom files on the server.
# If you'd like to do this manually, you remove this `aux_file_definitions` variable.
aux_file_definitions:
  # Create the privkey.pem file on the server by
  # uploading a file from the computer where Ansible is running.
  - dest: "{{ devture_traefik_ssl_dir_path }}/privkey.pem"
    src: /path/on/your/ansible/running/machine/privkey.pem
    # Alternatively, comment out `src` above and uncomment the lines below to provide the certificate content inline.
    # Note the indentation level.
    # content: |
    #   FILE CONTENT
    #   HERE

  # Create the cert.pem file on the server
  # uploading a file from the computer where Ansible is running.
  - dest: "{{ devture_traefik_ssl_dir_path }}/fullchain.pem"
    src: /path/on/your/ansible/running/machine/fullchain.pem
    # Alternatively, comment out `src` above and uncomment the lines below to provide the certificate content inline.
    # Note the indentation level.
    # content: |
    #   FILE CONTENT
    #   HERE

  # Create the custom Traefik configuration.
  # The `/ssl/..` paths below are in-container paths, not paths on the host (/`matrix/traefik/ssl/..`). Do not change them!
  - dest: "{{ devture_traefik_config_dir_path }}/certificates.yml"
    content: |
      tls:
        certificates:
          - certFile: /ssl/fullchain.pem
            keyFile: /ssl/privkey.pem
        stores:
          default:
            defaultCertificate:
              certFile: /ssl/fullchain.pem
              keyFile: /ssl/privkey.pem

# Only depend on docker.service, this removes the dependency on the certificate exporter, might imply the need to manually restart Coturn on the first installation once the certificates are obtained, afterwards, the reload service should handle things
matrix_coturn_systemd_required_services_list: ['docker.service']

# This changes the path of the loaded certificate, while maintaining the original functionality, we're now loading the wildcard certificate.
matrix_coturn_container_additional_volumes: |
  {{
    (
      [
       {
         'src': (matrix_ssl_config_dir_path + '/live/*.' + matrix_domain + '/fullchain.pem'),
         'dst': '/fullchain.pem',
         'options': 'ro',
       },
       {
         'src': (matrix_ssl_config_dir_path + '/live/*.' + matrix_domain + '/privkey.pem'),
         'dst': '/privkey.pem',
         'options': 'ro',
       },
      ] if matrix_playbook_reverse_proxy_type in ['playbook-managed-nginx', 'other-nginx-non-container'] and matrix_coturn_tls_enabled else []
    )
    +
    (
      [
       {
         'src': (devture_traefik_certs_dumper_dumped_certificates_dir_path +  '/*.' + matrix_domain + '/certificate.crt'),
         'dst': '/certificate.crt',
         'options': 'ro',
       },
       {
         'src': (devture_traefik_certs_dumper_dumped_certificates_dir_path +  '/*.' + matrix_domain + '/privatekey.key'),
         'dst': '/privatekey.key',
         'options': 'ro',
       },
      ] if matrix_playbook_reverse_proxy_type in ['playbook-managed-traefik', 'other-traefik-container'] and devture_traefik_certs_dumper_enabled and matrix_coturn_tls_enabled else []
    )
  }}

2. Serve certificates generated on your server

#
## SRV Delegation
#
matrix_well_known_matrix_server_enabled: false

# To serve the federation from any domain, as long as the path match
matrix_nginx_proxy_container_labels_traefik_proxy_matrix_federation_rule: PathPrefix(`/_matrix`)

# To let Traefik know which domains' certificates to serve
matrix_nginx_proxy_container_labels_additional_labels: |
  traefik.http.routers.matrix-nginx-proxy-matrix-federation.tls.domains.main="domain.tld"
  traefik.http.routers.matrix-nginx-proxy-matrix-federation.tls.domains.sans="*.domain.tld"

# Disable ACME / Let's Encrypt support.
devture_traefik_config_certificatesResolvers_acme_enabled: false

# Disabling ACME support (above) automatically disables the creation of the SSL directory.
# Force-enable it here, because we'll add our certificate files there.
devture_traefik_ssl_dir_enabled: true

# Tell Traefik to load our custom configuration file (certificates.yml).
# The file is created below, in `aux_file_definitions`.
# The `/config/..` path is an in-container path, not a path on the host (like `/matrix/traefik/config`). Do not change it!
devture_traefik_configuration_extension_yaml: |
  providers:
    file:
      filename: /config/certificates.yml
      watch: true

# Use the aux role to create our custom files on the server.
# If you'd like to do this manually, you remove this `aux_file_definitions` variable.
aux_file_definitions:
  # Uploading the files is not needed anymore.
  # By placing your files directly in `/matrix/traefik/ssl/`,
  # They will be directly mounted in the countainer thanks to the docker bind mount
  # /!\ **Mind the ownership of the files `matrix:matrix`**
  #     otherwise traefik will not be able to read them /!\

  # Create the custom Traefik configuration.
  # The `/ssl/..` paths below are in-container paths, not paths on the host (/`matrix/traefik/ssl/..`). Do not change them!
  - dest: "{{ devture_traefik_config_dir_path }}/certificates.yml"
    content: |
      tls:
        certificates:
          - certFile: /ssl/fullchain.pem
            keyFile: /ssl/privkey.pem
        stores:
          default:
            defaultCertificate:
              certFile: /ssl/fullchain.pem
              keyFile: /ssl/privkey.pem

# Only depend on docker.service, this removes the dependency on the certificate exporter, might imply the need to manually restart Coturn on the first installation once the certificates are obtained, afterwards, the reload service should handle things
matrix_coturn_systemd_required_services_list: ['docker.service']

# This changes the path of the loaded certificate, while maintaining the original functionality, we're now loading the wildcard certificate.
matrix_coturn_container_additional_volumes: |
  {{
    (
      [
       {
         'src': (matrix_ssl_config_dir_path + '/live/*.' + matrix_domain + '/fullchain.pem'),
         'dst': '/fullchain.pem',
         'options': 'ro',
       },
       {
         'src': (matrix_ssl_config_dir_path + '/live/*.' + matrix_domain + '/privkey.pem'),
         'dst': '/privkey.pem',
         'options': 'ro',
       },
      ] if matrix_playbook_reverse_proxy_type in ['playbook-managed-nginx', 'other-nginx-non-container'] and matrix_coturn_tls_enabled else []
    )
    +
    (
      [
       {
         'src': (devture_traefik_certs_dumper_dumped_certificates_dir_path +  '/*.' + matrix_domain + '/certificate.crt'),
         'dst': '/certificate.crt',
         'options': 'ro',
       },
       {
         'src': (devture_traefik_certs_dumper_dumped_certificates_dir_path +  '/*.' + matrix_domain + '/privatekey.key'),
         'dst': '/privatekey.key',
         'options': 'ro',
       },
      ] if matrix_playbook_reverse_proxy_type in ['playbook-managed-traefik', 'other-traefik-container'] and devture_traefik_certs_dumper_enabled and matrix_coturn_tls_enabled else []
    )
  }}

I am using this solution so certbot will automatically renew the certificate and install it where it needs to be placed.