Use minit as task manager, cleanup, do not save account in vault each

time
This commit is contained in:
Daniel Berteaud 2024-01-17 23:13:54 +01:00
parent 63e31aed93
commit b6ab88073b
7 changed files with 80 additions and 54 deletions

View File

@ -1,9 +1,9 @@
[[ $c := merge .acme . -]]
job [[ .instance | toJSON ]] {
job "[[ .instance ]]" {
type = "[[ if ne "" .acme.cron ]]service[[ else ]]batch[[ end ]]"
[[- template "common/job_start" $c ]]
[[ template "common/job_start" $c ]]
group "acme-to-vault" {
@ -19,7 +19,7 @@ job [[ .instance | toJSON ]] {
name = "[[ .instance ]][[ .consul.suffix ]]"
port = 8787
[[ template "common/connect" merge $c ]]
[[ template "common/connect" $c ]]
tags = [
"[[ $c.traefik.instance ]].enable=true",
@ -32,13 +32,13 @@ job [[ .instance | toJSON ]] {
}
task "acme-to-vault" {
driver = [[ $c.nomad.driver | toJSON ]]
driver = "[[ $c.nomad.driver ]]"
user = 8787
config {
image = [[ .acme.image | toJSON ]]
image = "[[ .acme.image ]]"
readonly_rootfs = true
pids_limit = 20
pids_limit = 50
[[ template "common/tmpfs" dict "target" "/data" "size" "10000000" ]]
}
@ -59,7 +59,13 @@ VAULT_ADDR=http://localhost:8200
[[- else ]]
VAULT_ADDR=[[ .acme.vault.addr ]]
[[- end ]]
ACME_CRON=[[ .acme.cron ]]
[[- if ne .acme.cron "" ]]
MINIT_MAIN_KIND=cron
MINIT_MAIN_CRON=[[ .acme.cron ]]
MINIT_MAIN_IMMEDIATE=true
[[- else ]]
MINIT_MAIN_KIND=once
[[- end ]]
ACME_KV_ACCOUNT_ROOT=[[ .acme.vault.kv_account_root ]]
[[- range $acc_idx, $account := .acme.accounts ]]
ACME_[[ $acc_idx ]]_CA=[[ $account.ca ]]

View File

@ -1,5 +1,7 @@
job "acme-to-vault" {
type = "service"
type = "service"
datacenters = ["dc1"]
@ -45,9 +47,9 @@ job "acme-to-vault" {
user = 8787
config {
image = "danielberteaud/acme-to-vault:24.1-2"
image = "danielberteaud/acme-to-vault:24.1-4"
readonly_rootfs = true
pids_limit = 20
pids_limit = 50
mount {
type = "tmpfs"
target = "/data"
@ -83,7 +85,9 @@ _EOT
template {
data = <<_EOT
VAULT_ADDR=http://localhost:8200
ACME_CRON=22 0 * * *
MINIT_MAIN_KIND=cron
MINIT_MAIN_CRON=22 0 * * *
MINIT_MAIN_IMMEDIATE=true
ACME_KV_ACCOUNT_ROOT=kv/service/acme-to-vault/account
_EOT
destination = "secrets/acm-to-vault.env"
@ -93,8 +97,8 @@ _EOT
resources {
cpu = 10
memory = 64
memory_max = 128
memory = 100
memory_max = 160
}
}

View File

@ -1,4 +1,4 @@
FROM danielberteaud/alpine:24.1-2 AS vault
FROM danielberteaud/alpine:24.1-4 AS vault
ARG VAULT_VERSION=1.15.4
@ -12,7 +12,7 @@ RUN set -euxo pipefail &&\
unzip -d /usr/local/bin vault_${VAULT_VERSION}_linux_amd64.zip &&\
rm vault_${VAULT_VERSION}_linux_amd64.zip
FROM danielberteaud/alpine:24.1-2
FROM danielberteaud/alpine:24.1-4
MAINTAINER Daniel Berteaud <dbd@ehtrace.com>
ARG VAULT_VERSION=1.15.4
@ -24,6 +24,9 @@ ENV ACME_HTTP_PORT=8787 \
ACME_0_CA=https://acme-staging-v02.api.letsencrypt.org/directory \
ACME_0_KV_CERT_ROOT=kv/service/traefik/certs \
ACME_0_KV_ACCOUNT_ROOT=kv/service/acme-to-vault/account \
MINIT_MAIN_KIND=once \
MINIT_MAIN_NAME=acme-to-vault \
MINIT_MAIN=acme-to-vault.sh \
VAULT_ADDR=https://vault.service.example.org:8200 \
VAULT_DISABLE_MLOCK=true
@ -34,10 +37,8 @@ RUN set -eu &&\
curl \
openssl \
ca-certificates \
tini \
lego \
jq \
supercronic \
&&\
mkdir -p /data &&\
# Use very open permissions so we can easily mount a tmpfs over /data \
@ -48,4 +49,4 @@ COPY root/ /
EXPOSE ${ACME_HTTP_PORT}
ENTRYPOINT ["tini", "--", "/entrypoint.sh"]
CMD ["acme-to-vault.sh"]
CMD ["minit"]

View File

@ -51,24 +51,31 @@ main(){
log_and_run "lego ${LEGO_OPTS} --domains=$(printenv ${CERT}) ${ACTION} --${ACTION}-hook /usr/local/bin/upload-to-vault.sh"
done
echo "Saving ACME account ${EMAIL} for ${ACME_CA} on vault"
CA=$(echo ${ACME_CA} | sed -E 's|^https?://([^/:]+).*|\1|')
vault kv put ${ACME_KV_ACCOUNT_ROOT}/${CA}/${EMAIL} \
metadata=@/data/acme/accounts/${CA}/${EMAIL}/account.json \
key=@/data/acme/accounts/${CA}/${EMAIL}/keys/${EMAIL}.key
if ! vault kv get ${ACME_KV_ACCOUNT_ROOT}/${CA}/${EMAIL} > /dev/null 2>&1; then
echo "Saving ACME account ${EMAIL} for ${ACME_CA} on vault"
vault kv put ${ACME_KV_ACCOUNT_ROOT}/${CA}/${EMAIL} \
metadata=@/data/acme/accounts/${CA}/${EMAIL}/account.json \
key=@/data/acme/accounts/${CA}/${EMAIL}/keys/${EMAIL}.key
else
if [ "$(vault kv get -field metadata ${ACME_KV_ACCOUNT_ROOT}/${CA}/${EMAIL} | sha256sum | awk '{ print $1 }')" != "$(sha256sum /data/acme/accounts/${CA}/${EMAIL}/account.json | awk '{ print $1 }')" ]; then
echo "Updating metadata of account ${EMAIL} for ${ACME_CA} on vault"
vault kv patch ${ACME_KV_ACCOUNT_ROOT}/${CA}/${EMAIL} \
metadata=@/data/acme/accounts/${CA}/${EMAIL}/account.json
else
echo "Metadata of account ${EMAIL} for ${ACME_CA} already in vault"
fi
if [ "$(vault kv get -field key ${ACME_KV_ACCOUNT_ROOT}/${CA}/${EMAIL} | sha256sum | awk '{ print $1 }')" != "$(sha256sum /data/acme/accounts/${CA}/${EMAIL}/keys/${EMAIL}.key | awk '{ print $1 }')" ]; then
echo "Updating key of account ${EMAIL} for ${ACME_CA} on vault"
vault kv patch ${ACME_KV_ACCOUNT_ROOT}/${CA}/${EMAIL} \
key=@/data/acme/accounts/${CA}/${EMAIL}/keys/${EMAIL}.key
else
echo "Key of account ${EMAIL} for ${ACME_CA} already in vault"
fi
fi
done
}
# Run once at start of the container
main
# If a cron expression is defined, run a cron daemon
if [ -n "${ACME_CRON}" -a -z "${ACME_CRON_RUNNING:-}" ]; then
echo "Running using cron with expression ${ACME_CRON}"
cat <<_EOF > /data/crontab
${ACME_CRON} /usr/local/bin/acme-to-vault.sh
_EOF
export ACME_CRON_RUNNING=true
supercronic /data/crontab
fi

View File

@ -24,6 +24,9 @@ ENV ACME_HTTP_PORT=8787 \
ACME_0_CA=https://acme-staging-v02.api.letsencrypt.org/directory \
ACME_0_KV_CERT_ROOT=kv/service/traefik/certs \
ACME_0_KV_ACCOUNT_ROOT=kv/service/acme-to-vault/account \
MINIT_MAIN_KIND=once \
MINIT_MAIN_NAME=acme-to-vault \
MINIT_MAIN=acme-to-vault.sh \
VAULT_ADDR=https://vault.service.example.org:8200 \
VAULT_DISABLE_MLOCK=true
@ -34,10 +37,8 @@ RUN set -eu &&\
curl \
openssl \
ca-certificates \
tini \
lego \
jq \
supercronic \
&&\
mkdir -p /data &&\
# Use very open permissions so we can easily mount a tmpfs over /data \
@ -48,4 +49,4 @@ COPY root/ /
EXPOSE ${ACME_HTTP_PORT}
ENTRYPOINT ["tini", "--", "/entrypoint.sh"]
CMD ["acme-to-vault.sh"]
CMD ["minit"]

View File

@ -51,24 +51,31 @@ main(){
log_and_run "lego ${LEGO_OPTS} --domains=$(printenv ${CERT}) ${ACTION} --${ACTION}-hook /usr/local/bin/upload-to-vault.sh"
done
echo "Saving ACME account ${EMAIL} for ${ACME_CA} on vault"
CA=$(echo ${ACME_CA} | sed -E 's|^https?://([^/:]+).*|\1|')
vault kv put ${ACME_KV_ACCOUNT_ROOT}/${CA}/${EMAIL} \
metadata=@/data/acme/accounts/${CA}/${EMAIL}/account.json \
key=@/data/acme/accounts/${CA}/${EMAIL}/keys/${EMAIL}.key
if ! vault kv get ${ACME_KV_ACCOUNT_ROOT}/${CA}/${EMAIL} > /dev/null 2>&1; then
echo "Saving ACME account ${EMAIL} for ${ACME_CA} on vault"
vault kv put ${ACME_KV_ACCOUNT_ROOT}/${CA}/${EMAIL} \
metadata=@/data/acme/accounts/${CA}/${EMAIL}/account.json \
key=@/data/acme/accounts/${CA}/${EMAIL}/keys/${EMAIL}.key
else
if [ "$(vault kv get -field metadata ${ACME_KV_ACCOUNT_ROOT}/${CA}/${EMAIL} | sha256sum | awk '{ print $1 }')" != "$(sha256sum /data/acme/accounts/${CA}/${EMAIL}/account.json | awk '{ print $1 }')" ]; then
echo "Updating metadata of account ${EMAIL} for ${ACME_CA} on vault"
vault kv patch ${ACME_KV_ACCOUNT_ROOT}/${CA}/${EMAIL} \
metadata=@/data/acme/accounts/${CA}/${EMAIL}/account.json
else
echo "Metadata of account ${EMAIL} for ${ACME_CA} already in vault"
fi
if [ "$(vault kv get -field key ${ACME_KV_ACCOUNT_ROOT}/${CA}/${EMAIL} | sha256sum | awk '{ print $1 }')" != "$(sha256sum /data/acme/accounts/${CA}/${EMAIL}/keys/${EMAIL}.key | awk '{ print $1 }')" ]; then
echo "Updating key of account ${EMAIL} for ${ACME_CA} on vault"
vault kv patch ${ACME_KV_ACCOUNT_ROOT}/${CA}/${EMAIL} \
key=@/data/acme/accounts/${CA}/${EMAIL}/keys/${EMAIL}.key
else
echo "Key of account ${EMAIL} for ${ACME_CA} already in vault"
fi
fi
done
}
# Run once at start of the container
main
# If a cron expression is defined, run a cron daemon
if [ -n "${ACME_CRON}" -a -z "${ACME_CRON_RUNNING:-}" ]; then
echo "Running using cron with expression ${ACME_CRON}"
cat <<_EOF > /data/crontab
${ACME_CRON} /usr/local/bin/acme-to-vault.sh
_EOF
export ACME_CRON_RUNNING=true
supercronic /data/crontab
fi

View File

@ -5,7 +5,7 @@ instance: acme-to-vault
acme:
# The Docker image to use
image: '[[ .docker.repo ]]acme-to-vault:24.1-2'
image: '[[ .docker.repo ]]acme-to-vault:24.1-4'
# If a cron expression is defined, the service will stay running and renew certs.
# If an empty string, the container will exit after running once
@ -14,8 +14,8 @@ acme:
# Resource allocation
resources:
cpu: 10
memory: 64
memory_max: 128
memory: 100
memory_max: 160
# Vault related settings
vault: