Repository navigation
ansible: add certbot role and serve origins from Let's Encrypt - #4523
ryanaslett wants to merge 6 commits into
Conversation
Installs the distro-packaged certbot and certbot-dns-cloudflare, writes a 0600 credentials file from the secrets repo, issues a certificate via DNS-01, and reloads nginx on renewal through a deploy hook. Renewal is handled by the packaged certbot.timer. Wire it into the ci and ci-release Jenkins plays to issue certificates for ci.nodejs.org and ci-release.nodejs.org. nginx is not yet pointed at the issued certificates. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Signed-off-by: Ryan Aslett <raslett@linuxfoundation.org>
Create the renewal-hooks/deploy directory before installing the hook so a first run on a fresh host works, and drop --deploy-hook since certbot already runs every script in that directory on renewal. Tag the certbot and jenkins-nginx role entries so each can be run alone with --tags without skipping its read-secrets dependency. Issue certificates on www (nodejs.org and *.nodejs.org) and on the unencrypted host. nginx is not yet pointed at them. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Signed-off-by: Ryan Aslett <raslett@linuxfoundation.org>
Tags on a role entry are not inherited by the tasks of its meta dependencies, so running with --tags certbot skipped the secrets decrypt step and left the Cloudflare token undefined. Tag the dependency so the certbot role can be run on its own. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Signed-off-by: Ryan Aslett <raslett@linuxfoundation.org>
Issue one certificate per directly reachable origin name (ci, ci-release, direct and unencrypted) using certbot --webroot, instead of the Cloudflare DNS-01 plugin. This needs no API token and no DNS delegation, and keeps certbot distro-packaged. Serve /.well-known/acme-challenge/ from /var/www/letsencrypt on the port 80 vhosts, and add reload handlers plus an nginx-sites tag so those vhost changes can be deployed without running the whole nginx role. ci-release moves its port 80 redirect into a location so the challenge path is reachable. nginx is not yet pointed at the issued certificates. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Signed-off-by: Ryan Aslett <raslett@linuxfoundation.org>
Point the ci-release nginx vhost at the certificate certbot issues for ci-release.nodejs.org and drop OCSP stapling, which Let's Encrypt no longer supports. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Signed-off-by: Ryan Aslett <raslett@linuxfoundation.org>
Point the ci nginx vhost at the certificate certbot issues for ci.nodejs.org and drop OCSP stapling, which Let's Encrypt no longer supports. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Signed-off-by: Ryan Aslett <raslett@linuxfoundation.org>
|
Additional things: This is using the HTTP-01 verification method (LetsEncrypt hits a Other options I looked at is the DNS-01 verification method, which uses dns to verify and has the advantage of allowing wildcard certs to be issued, however, it required a cloudflare API key to live on the servers running certbot. There is a trick to giving the servers a well scoped key to a non threating domain (like node.dev) by proxying a CNAME from nodejs.org -> node.dev and allowing the servers to make dns mods that way, however certbot didnt have any support for that particular type of indirection, opting to wait until the newer verification method, detailed below, was available. There is a third, newer verification method DNS-PERSIST-01 ->(https://letsencrypt.org/2026/02/18/dns-persist-01) however, that appears to be not actually usable yet (but removes the need to have API keys, so its the someday best way).. (https://www.certkit.io/blog/whats-taking-dns-persist-01-so-long) details the best status I can find on it so far. |
Summary
Adds a
certbotrole that issues and renews Let's Encrypt certificates over HTTP-01 (certbot certonly --webroot), using the distro-packaged certbot and itscertbot.timer. No API token, DNS delegation or extra tooling is involved.certbotrole, wired into the ci, ci-release, www (direct.nodejs.org) and rsync (unencrypted.nodejs.org) plays, each with its own certificate./.well-known/acme-challenge/from/var/www/letsencrypt. ci-release's redirect moved into alocationblock so the challenge path is reachable.jenkins-nginxandnginxget areload nginxhandler, and the nginx site tasks get annginx-sitestag, so vhost changes can be deployed without running the whole nginx role.Refs #4038, #4482. This does not close either; docs and cleanup are tracked in #4038.
Already applied
These were deployed ahead of the 2026-10-23 expiry in #4482, and all four origins serve Let's Encrypt now:
--tags nginx-sitesorjenkins-nginx, then--tags certbot).locationinsites-available/nodejs.org,certbot certonly --webrootfordirect.nodejs.organdorigin.nodejs.org, and the cert paths in/etc/nginx/conf.d/ssl-defaults.conf./etc/nginx/conf.d/ssl-defaults.confwas also edited by hand (it is not in Ansible).Things to know
--key-type rsa, which chains to ISRG Root X1.certbot_domainsis set per host in the playbooks.origin.nodejs.orgis still a live Cloudflare load balancer used by the release Worker, so it is covered by the www certificate./etc/nginx/ssl/are still on the hosts and are not removed here.Test plan
ansible-playbook --syntax-checkon the three playbooks--check --diffbefore each real run, one host at a timecertbot renew --dry-runpasses on rsync, ci-release and ciopenssl s_clientfrom outside shows a Let's Encrypt certificate with a verified chain on all four origins🤖 Generated with Claude Code