r/postgresql-cert: ACME certificates using certbot

This role can be used to get a server certificate for PostgreSQL from an
ACME CA using `certbot`.  It fetches the initial certificate and copies
it to the PostgreSQL configuration directory.  It also sets up a
post-renewal hook script that copies updated certificates and reload
the server.
frigate-exporter
Dustin 2024-06-28 20:34:40 -05:00
parent 9e742dc217
commit 99c309240c
4 changed files with 155 additions and 0 deletions

View File

@ -0,0 +1,8 @@
- name: reload systemd
systemd:
daemon_reload: true
- name: restart certbot-renew timer
systemd:
name: certbot-renew.timer
state: restarted

View File

@ -0,0 +1,114 @@
- name: ensure required packages are installed
package:
name:
- certbot
- postgresql-server # to get postgres user account
state: present
tags:
- install
- name: ensure http port is allowed in firewall (for acme challenge)
firewalld:
service: http
state: enabled
permanent: true
immediate: true
when: host_uses_firewalld|d(true)
tags:
- firewalld
- name: ensure postgresql server certificate exists
command:
certbot certonly -n
--standalone
-d {{ postgresql_cert_domain }}
--server {{ postgresql_cert_acme_server }}
--agree-tos
--email {{ postgresql_cert_acme_email }}
args:
creates: /etc/letsencrypt/live/{{ postgresql_cert_domain }}/fullchain.pem
tags:
- cert
- name: ensure certbot deploy renewal hook script is installed
template:
src: deploy-hook.sh.j2
dest: /etc/letsencrypt/renewal-hooks/deploy/postgresql.sh
owner: root
group: root
mode: u=rwx,go=rx
tags:
- deploy-hook
- name: ensure certbot renewal period is configured for postgresql cert
lineinfile:
line: renew_before_expiry = 8 hours
regexp: '^#?\s*renew_before_expiry\s*='
path: /etc/letsencrypt/renewal/{{ postgresql_cert_domain }}.conf
state: present
tags:
- config
- name: ensure certbot-renew timer unit drop-in directory exists
file:
path: /etc/systemd/system/certbot-renew.timer.d
owner: root
group: root
mode: u=rwx,go=rx
state: directory
tags:
- systemd
- name: ensure certbot-renew timer schedule is configured
template:
src: certbot-renew.timer.j2
dest: /etc/systemd/system/certbot-renew.timer.d/schedule.conf
owner: root
group: root
mode: u=rw,go=r
notify:
- reload systemd
- restart certbot-renew timer
tags:
- systemd
- name: ensure certbot-renew timer is enabled
systemd:
name: certbot-renew.timer
enabled: true
tags:
- service
- name: flush handlers
meta: flush_handlers
- name: ensure certbot-renew timer is running
systemd:
name: certbot-renew.timer
state: started
tags:
- service
- name: ensure postgresql config directory exists
file:
path: /etc/postgresql
state: directory
- name: ensure initial copy of postgresql certificate is in place
copy:
src: /etc/letsencrypt/live/{{ postgresql_cert_domain }}/fullchain.pem
dest: /etc/postgresql/server.cer
remote_src: true
owner: root
group: root
mode: u=rw,go=r
force: false
tags:
- cert
- name: ensure initial copy of postgresql private key is in place
copy:
src: /etc/letsencrypt/live/{{ postgresql_cert_domain }}/privkey.pem
dest: /etc/postgresql/server.key
remote_src: true
owner: root
group: postgres
mode: u=rw,g=r,o=
force: false
tags:
- cert

View File

@ -0,0 +1,3 @@
[Timer]
RandomizedDelaySec=15m
OnCalendar=hourly

View File

@ -0,0 +1,30 @@
#!/bin/sh
# vim: set sw=4 ts=4 sts=4 et :
POSTGRESQL_DOMAIN="{{ postgresql_cert_domain }}"
set -- ${FAILED_DOMAINS}
for domain; do
case ${domain} in
${POSTGRESQL_DOMAIN})
printf 'Certificate renewal failed for %s, not reloading server\n' \
"${domain}" >&2
exit 1
;;
esac
done
set -- ${RENEWED_DOMAINS}
for domain; do
case ${domain} in
${POSTGRESQL_DOMAIN})
install -o root -g root -m u=rw,go=r \
/etc/letsencrypt/live/${POSTGRESQL_DOMAIN}/fullchain.pem \
/etc/postgresql/server.cer
install -o root -g postgres -m u=rw,g=r,o= \
/etc/letsencrypt/live/${POSTGRESQL_DOMAIN}/privkey.pem \
/etc/postgresql/server.key
systemctl reload postgresql
;;
esac
done