system-config/playbooks/roles/letsencrypt-request-certs
James E. Blair 7f96224ef9 Update letsencrypt role docs to suggest a specific order
In reviews on https://review.opendev.org/819923 we discovered we
are inconsistent in how we create certs.  Suggest a specific course
of action and record the reasoning.

Change-Id: I974a1717a74e759ca8805dcb707efc7fe29ba53f
2021-12-03 14:24:13 -08:00
..
defaults Fix letsencrypt_self_generate_tokens defaults 2021-10-06 08:40:43 -07:00
tasks letsencrypt : don't use staging in the gate 2021-10-06 15:34:21 +11:00
README.rst Update letsencrypt role docs to suggest a specific order 2021-12-03 14:24:13 -08:00

Request certificates from letsencrypt

The role requests certificates (or renews expiring certificates, which is fundamentally the same thing) from letsencrypt for a host. This requires the acme.sh tool and driver which should have been installed by the letsencrypt-acme-sh-install role.

This role does not create the certificates. It will request the certificates from letsencrypt and populate the authentication data into the acme_txt_required variable. These values need to be installed and activated on the DNS server by the letsencrypt-install-txt-record role; the letsencrypt-create-certs will then finish the certificate provision process.

Role Variables

If set to True will use the letsencrypt staging environment, rather than make production requests. Useful during initial provisioning of hosts to avoid affecting production quotas.

A host wanting a certificate should define a dictionary variable letsencyrpt_certs. Each key in this dictionary is a separate certificate to create (i.e. a host can create multiple separate certificates). Each key should have a list of hostnames valid for that certificate. The certificate will be named for the first entry. Naming the cert for the service (rather than the hostname) will simplify references to the file (for example in Apache VirtualHost configs), so listing it first is preferred.

For example:

letsencrypt_certs:
  hostname-main-cert:
    - hostname.opendev.org
    - hostname01.opendev.org
  hostname-secondary-cert:
    - foo.opendev.org

will ultimately result in two certificates being provisioned on the host in /etc/letsencrypt-certs/hostname.opendev.org and /etc/letsencrypt-certs/foo.opendev.org.

Note the creation role letsencrypt-create-certs will call a handler letsencrypt updated {{ key }} (for example, letsencrypt updated hostname-main-cert) when that certificate is created or updated. Because Ansible errors if a handler is called with no listeners, you must define a listener for event. letsencrypt-create-certs has handlers/main.yaml where handlers can be defined. Since handlers reside in a global namespace, you should choose an appropriately unique name.

Note that each entry will require a CNAME pointing the ACME challenge domain to the TXT record that will be created in the signing domain. For example above, the following records would need to be pre-created:

_acme-challenge.hostname01.opendev.org.  IN   CNAME  acme.opendev.org.
_acme-challenge.hostname.opendev.org.    IN   CNAME  acme.opendev.org.
_acme-challenge.foo.opendev.org.         IN   CNAME  acme.opendev.org.

The hostname in the first entry for each certificate will be registered with the letsencrypt-config-certcheck for periodic freshness tests; from the example above, hostname01.opendev.org and foo.opendev.org would be checked. By default this will check on port 443; if the certificate is actually active on another port you can specify it after a colon; e.g. foo.opendev.org:5000 would indicate this host listens with this certificate on port 5000.