Skip to content
Snippets Groups Projects
Commit d0297528 authored by Thomas Schneider's avatar Thomas Schneider
Browse files

Add role for lego ACME client

parent a444637d
No related branches found
No related tags found
1 merge request!50Draft: Add role for lego ACME client
Pipeline #5598 failed
---
lego_acme_server_base: acme-v02.api.letsencrypt.org
# lego_account_mail: root@example.org
# The following two variables are defaults for the respective entries in a
# `lego_certificates` entry.
lego_method:
type: http
subtype: webroot
lego_hooks:
services: {}
extra: {}
lego_global_args: []
# lego_certificates:
# # Default case, only one domain
# foo.example.org: {}
# bar.example.org:
# domains:
# # bar.example.org is already included
# - baz.example.org
# - qux.example.org
# account_mail: other@example.org
# method:
# type: dns
# subtype: rfc2136
# extra_args:
# - --foo
# - --bar baz
# extra_env:
# RFC2136_NAMESERVER: 127.0.0.1
# hooks:
# services:
# nginx.service: try-restart
# httpd.service: try-reload-or-restart
# extra:
# 10-install.sh: |
# #!/bin/sh
# set -e
# install -u foo -g foo -m 0644 "$LEGO_CERT_PATH" /etc/foo/cert.pem
# install -u foo -g foo -m 0600 "$LEGO_CERT_KEY_PATH" /etc/foo/key.pem
---
- name: Reload systemd
systemd:
daemon_reload: true
---
- name: Install instance config
template:
src: env-inst.j2
dest: /etc/lego/{{ item.key }}.env
owner: root
group: root
mode: "0600"
register: install_instance_config
- name: Create hooks directory
file:
path: /etc/lego/hooks/{{ item.key }}
state: directory
owner: root
group: root
mode: "0700"
- name: Install service hook
template:
src: 99-services.sh.j2
dest: /etc/lego/hooks/{{ item.key }}/99-services
owner: root
group: root
mode: "0700"
when: item.value.hooks.services != {}
- name: Install additional hooks
copy:
content: "{{ j.value }}"
dest: /etc/lego/hooks/{{ item.key }}/{{ j.key }}
owner: root
group: root
mode: "0700"
loop: "{{ item.value.hooks.extra | dict2items }}"
loop_control:
loop_var: j
# Yes, this should be a handler, but they cannot be as dynamic as we need it.
- name: Start lego
systemd:
name: lego-run@{{ item.key }}.service
state: started
when: install_instance_config.changed
- name: Enable renewal timer
systemd:
name: lego-renew@{{ item.key }}.timer
state: started
enabled: true
---
- name: Install lego
apt:
name: lego
- name: Create config and hooks directory
file:
path: "{{ item }}"
state: directory
owner: root
group: root
mode: "0700"
loop:
- /etc/lego
- /etc/lego/hooks
- name: Install systemd service files
template:
src: "{{ item }}.j2"
dest: /etc/systemd/system/{{ item }}
owner: root
group: root
mode: "0644"
loop:
- lego-run@.service
- lego-renew@.service
- lego-renew@.timer
notify:
- Reload systemd
- meta: flush_handlers
- name: Process individual certificate instances
loop: "{{ lego_certificates | dict2items }}"
loop_control:
label: "{{ item.key }}"
loop_var: _item
vars:
item: "{{ cert_skeleton | combine(_item, recursive=True) }}"
include_tasks: certificate.yml
#!/bin/sh
{% for svc, action in item.value.hooks.services.items() %}
set -- systemctl "{{ action }}" "{{ svc }}"
"$@"
ret=$?
if [ $ret -ne 0 ]; then
echo "(command was: $*)"
exit $ret
fi
{% endfor %}
{# -*- systemd -*- #}
{% macro execstart(typ) %}
ExecStart=/usr/bin/lego $LEGO_GLOBAL_ARGS $LEGO_ARGS \
--server https://${LEGO_ACME_SERVER_BASE}/directory \
--path $STATE_DIRECTORY \
--accept-tos \
{{ typ }} \
{% if typ == "renew" %}
--no-random-sleep \
{% endif %}
--{{ typ }}-hook='run-parts --report /etc/lego/hooks/%i/'
{% endmacro %}
{% macro systemd_boilerplate(typ) %}
[Unit]
Wants=network-online.target
After=network-online.target
[Service]
EnvironmentFile=/etc/lego/%i.env
StateDirectory=lego
StateDirectoryMode=0700
RuntimeDirectory=lego
Type=oneshot
{{ execstart(typ) }}
# PrivateDevices=yes
# NoNewPrivileges=yes
# ProtectHome=yes
TimeoutStartSec=5min
#CapabilityBoundingSet=CAP_CHOWN
# Empty = no capabilities at all
CapabilityBoundingSet=
NoNewPrivileges=yes
PrivateTmp=yes
PrivateDevices=yes
ProtectSystem=strict
ProtectHome=yes
ProtectHostname=yes
ProtectClock=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectKernelLogs=yes
ProtectControlGroups=yes
RestrictRealtime=yes
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
LockPersonality=yes
SystemCallFilter=@system-service
SystemCallArchitectures=native
{% endmacro %}
{% if lego_global_args is iterable and not lego_global_args is string -%}
LEGO_GLOBAL_ARGS="{{ lego_global_args | join(' ') }}"
{% else %}
LEGO_GLOBAL_ARGS="{{ lego_global_args }}"
{% endif %}
LEGO_ACME_SERVER_BASE="{{ lego_acme_server_base }}"
LEGO_CERT_DOMAIN="{{ item.key }}"
LEGO_ARGS="\
--email {{ item.value.account_mail }} \
--{{ item.value.method.type }} \
{% if item.value.method.type == "http" and item.value.method.subtype == "webroot" %}
--http.webroot /run/lego \
{% endif %}
--domains {{ item.key }} \
{% for d in item.value.domains %}
--domains {{ d }} \
{% endfor %}
{% for i in item.value.extra_args %}
{{ i }} \
{% endfor %}
"
{% for k, v in item.value.extra_env.items() %}
{{ k }}="{{ v }}"
{% endfor %}
{# -*- systemd -*- #}
{% from "_macros.j2" import systemd_boilerplate -%}
[Unit]
Description=lego ACME client -- renewal for %i
{{ systemd_boilerplate("renew") }}
{# -*- systemd -*- #}
[Unit]
Description=lego ACME client -- renewal for %i timer
[Timer]
OnCalendar=weekly
RandomizedDelaySec=1d
Persistent=true
[Install]
WantedBy=timers.target
{# -*- systemd -*- #}
{% from "_macros.j2" import systemd_boilerplate -%}
[Unit]
Description=lego ACME client -- setup for %i
{{ systemd_boilerplate("run") }}
---
cert_skeleton:
value:
account_mail: "{{ lego_account_mail }}"
domains: []
method: "{{ lego_method }}"
extra_args: []
extra_env: {}
hooks: "{{ lego_hooks }}"
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment