feat(lego): allow running multiple instances with systemd templates

This commit is contained in:
Johanna Dorothea Reichmann 2023-09-20 15:39:07 +02:00
parent 53fb5ced5c
commit 348a387de3
No known key found for this signature in database
GPG key ID: 03624C433676E465
6 changed files with 69 additions and 39 deletions

View file

@ -1,6 +1,10 @@
---
lego_instance: ~
lego_base_path: "/opt/lego"
lego_certificate_store: "{{ lego_base_path }}/certificates"
lego_instance_base_path: >-
/opt/lego{{ ('-' ~ lego_instance) if lego_instance else ''}}
lego_certificate_store: >-
{{ lego_instance_base_path }}/certificates
lego_certificate_store_user: "{{ lego_user_res.uid | default(lego_user) }}"
lego_certificate_store_group: "{{ lego_user_res.group | default(lego_user) }}"
lego_certificate_store_mode: "0750"
@ -9,8 +13,10 @@ lego_version: "4.12.3"
lego_system_type: "linux"
lego_system_arch: "amd64"
lego_executable: "{{ lego_base_path }}/lego"
lego_account_base_path: "{{ lego_base_path }}/accounts"
lego_account_base_path: >-
{{ lego_instance_base_path }}/accounts
lego_cap_net_bind_service: true
lego_default_systemd_instance: "lego"
lego_enable_metrics_textfile: false
@ -80,7 +86,7 @@ lego_configuration_defaults:
server: "{{ lego_letsencrypt_servers[lego_letsencrypt_environment] }}"
accept-tos: true
email: "{{ lego_certificate.email }}"
path: "{{ lego_base_path }}"
path: "{{ lego_instance_base_path }}"
key-type: "{{ lego_configuration_default_key_type }}"
run: {}
renew:
@ -90,7 +96,6 @@ lego_configuration_defaults:
lego_install_dependencies: false
lego_dependencies:
Debian:
"11":
- "python3-cryptography"
all:
- "acl"
- "python3-cryptography"

View file

@ -1,5 +1,6 @@
---
- name: "Run lego"
listen: lego_run
become: true
become_user: "{{ lego_user_res.name }}"
environment: "{{ lego_configuration_merged.environment }}"
@ -7,5 +8,6 @@
register: "lego_run"
- name: "Reload systemd"
listen: systemd_reload
systemd:
daemon_reload: true

View file

@ -18,16 +18,19 @@
tags: ["prepare", "prepare-lego"]
- name: "Ensure base directory for lego is created"
file:
path: "{{ lego_base_path }}"
ansible.builtin.file:
path: "{{ item }}"
state: "directory"
owner: "{{ lego_certificate_store_user }}"
group: "{{ lego_certificate_store_group }}"
mode: "0755"
loop:
- "{{ lego_base_path }}"
- "{{ lego_instance_base_path }}"
tags: ["prepare", "prepare-lego"]
- name: "Ensure certificate directory exists and has the configured permissions"
file:
ansible.builtin.file:
path: "{{ lego_certificate_store }}"
state: "directory"
owner: "{{ lego_certificate_store_user }}"
@ -136,7 +139,8 @@
path: "{{ lego_certificate_store }}/{{ lego_certificate.domains[0] }}.crt"
register: "lego_certificate_stat"
changed_when: "not lego_certificate_stat.stat.exists"
notify: ["Run lego"]
notify:
- "lego_run"
tags: ["deploy", "deploy-lego"]
- name: "Fetch certificate info"
@ -163,7 +167,8 @@
}}
when: "lego_certificate_stat.stat.exists"
changed_when: "not lego_certificate_sans_equal"
notify: ["Run lego"]
notify:
- "lego_run"
tags: ["deploy", "deploy-lego"]
- name: "Compare pubkey type, notify handler if it differs"
@ -177,41 +182,49 @@
}}
when: "lego_certificate_stat.stat.exists"
changed_when: "lego_certificate_pubkey_type_differs"
notify: ["Run lego"]
notify:
- "lego_run"
tags: ["deploy", "deploy-lego"]
- name: "Ensure systemd unit file for lego is templated"
template:
ansible.builtin.template:
src: "lego.service.j2"
dest: "{{ lego_systemd_path }}/lego.service"
dest: "{{ lego_systemd_path }}/lego@.service"
owner: "root"
group: "root"
mode: "0755"
notify: ["Reload systemd"]
notify:
- "systemd_reload"
tags: ["deploy", "deploy-lego"]
- name: "Ensure systemd timer for lego is templated"
template:
ansible.builtin.template:
src: "lego.timer.j2"
dest: "{{ lego_systemd_path }}/lego.timer"
dest: "{{ lego_systemd_path }}/lego{{ ('-' ~ lego_instance) if lego_instance else '' }}.timer"
owner: "root"
group: "root"
mode: "0755"
notify: ["Reload systemd"]
notify:
- "systemd_reload"
tags: ["deploy", "deploy-lego"]
- name: "Ensure env file per instance is templated"
ansible.builtin.template:
src: "lego.env.j2"
dest: "{{ lego_base_path }}/{{ lego_instance | default(lego_default_systemd_instance) }}.conf"
- name: "Flush handlers to ensure systemd has loaded the unit files"
meta: "flush_handlers"
- name: "Enable lego.service"
systemd:
name: "lego.service"
ansible.builtin.systemd:
name: "lego{{ ('@' ~ lego_instance) if lego_instance else '' }}.service"
enabled: true
tags: ["deploy", "deploy-lego"]
- name: "Enable lego.timer"
systemd:
name: "lego.timer"
ansible.builtin.systemd:
name: "lego{{ ('-' ~ lego_instance) if lego_instance else '' }}.timer"
state: "started"
enabled: true
tags: ["deploy", "deploy-lego"]

View file

@ -0,0 +1,18 @@
LEGO_USER={{ lego_user_res.name }}
LEGO_GROUP={{ lego_user_res.group }}
LEGO_CERT_STORE_OWNER={{ lego_certificate_store_user }}
LEGO_CERT_STORE_GROUP={{ lego_certificate_store_group }}
LEGO_CERT_STORE_PATH={{ lego_certificate_store }}
LEGO_CERT_STORE_MODE={{ lego_certificate_store_mode }}
LEGO_CWD={{ lego_instance_base_path }}
LEGO_COMMAND={{ lego_command_systemd }}
{% if lego_enable_metrics_textfile %}
LEGO_ENABLE_METRICS=true
{% endif %}
{% if lego_post_renewal_script is defined %}
LEGO_POST_RENEW_HOOK_PATH={{ lego_post_renewal_script }}
{% endif %}
{% for envvar in lego_configuration_merged.environment %}
{{ envvar }}={{ lego_configuration_merged.environment[envvar] }}
{% endfor %}

View file

@ -5,24 +5,16 @@ Description=lego - Let's Encrypt client written in Go
StandardOutput=journal
StandardError=journal
SyslogIdentifier=lego
{% for envvar in lego_configuration_merged.environment %}
Environment={{ envvar }}={{ lego_configuration_merged.environment[envvar] }}
{% endfor %}
EnvironmentFile={{ lego_base_path }}/%i.conf
Type=oneshot
Group={{ lego_user_res.group }}
User={{ lego_user_res.name }}
WorkingDirectory={{ lego_base_path }}
ExecStartPre=+-chown {{ lego_certificate_store_user }}:{{ lego_certificate_store_group }} {{ lego_certificate_store }}
ExecStartPre=+-chmod {{ lego_certificate_store_mode }} {{ lego_certificate_store }}
ExecStart={{ lego_command_systemd }}
ExecStartPost=+-/bin/sh -c 'chown {{ lego_certificate_store_user }}:{{ lego_certificate_store_group }} {{ lego_certificate_store }}/*'
ExecStartPost=+-/bin/sh -c 'chmod 0640 {{ lego_certificate_store }}/*'
{% if lego_enable_metrics_textfile %}
ExecStartPost=+-/usr/bin/python3 {{ lego_base_path }}/metrics-textfile.py
{% endif %}
{% if lego_post_renewal_script is defined %}
ExecStartPost=+-{{ lego_post_renewal_script }}
{% endif %}
ExecStartPre=+-/usr/bin/bash -c 'chown $(getent passwd | awk -F: \'$$3 == ${LEGO_CERT_STORE_OWNER} {print $$1}\'):$(getent group | grep ${LEGO_CERT_STORE_GROUP} | cut -d ':' -f1) ${LEGO_CERT_STORE_PATH}'
ExecStartPre=+-/usr/bin/bash -c "chmod ${LEGO_CERT_STORE_MODE} ${LEGO_CERT_STORE_PATH}"
ExecStart=/usr/bin/bash -c 'cd $LEGO_CWD && sudo -u ${LEGO_USER} -g $(getent group | grep ${LEGO_GROUP} | cut -d ':' -f1) ${LEGO_COMMAND}'
ExecStartPost=+-/bin/sh -c 'chown ${LEGO_CERT_STORE_OWNER}:${LEGO_CERT_STORE_GROUP} ${LEGO_CERT_STORE_PATH}/*'
ExecStartPost=+-/bin/sh -c 'chmod 0640 ${LEGO_CERT_STORE_PATH}/*'
ExecStartPost=+-/usr/bin/bash -c 'test -n "${LEGO_ENABLE_METRICS-}" && /usr/bin/python3 ${LEGO_CWD}/metrics-textfile.py'
ExecStartPost=+-${LEGO_POST_RENEW_HOOK_PATH}
[Install]
WantedBy=multi-user.target
DefaultInstance={{ lego_default_systemd_instance }}

View file

@ -20,7 +20,7 @@ RandomizedDelaySec={{ lego_timer_random_delay }}
Persistent={{ lego_timer_persistent | string }}
{% endif %}
Unit=lego.service
Unit=lego{{ ('@' ~ lego_instance) if lego_instance else ''}}.service
[Install]
WantedBy=timers.target