Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement a post-renewal hook script #205

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions roles/step_acme_cert/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,18 @@ before setting up a renewal service using `step-cli ca renew`s `--daemon` mode.
- Renew the cert when its remaining valid time crosses this threshold
- Default: undefined (uses the smallstep default: 1/3 of the certificates valid duration, i.e. 8 hours for a 24h cert)

##### `step_acme_cert_post_renewal_shell`
- Shell with which to run `step_acme_cert_post_renewal_commands`
- Must be a valid shell
- Default: `/bin/sh`

##### `step_acme_cert_post_renewal_commands`
- Run these commands after a cert renewal
- Must be a list of commands executable with the shell specified in `step_acme_cert_post_renewal_shell`
- `${STEP_CLI}`, `${CERT_FILE}` and `${KEY_FILE}` are available for use. All are absolute paths to files.
- Example: `["cp ${CERT_FILE} /path/to/somewhere/", "chmod 400 ${KEY_FILE}"]`
- Default: `[]`

##### `step_acme_cert_renewal_reload_services`
- Reload or restart these systemd services after a cert renewal
- Must be a list of systemd units
Expand Down
2 changes: 2 additions & 0 deletions roles/step_acme_cert/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,6 @@ step_acme_cert_keyfile_defaults:

step_acme_cert_renewal_service: step-renew
#step_acme_cert_renewal_when: 8h
step_acme_cert_post_renewal_shell: "/bin/sh"
step_acme_cert_post_renewal_commands: []
step_acme_cert_renewal_reload_services: []
15 changes: 15 additions & 0 deletions roles/step_acme_cert/meta/argument_specs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,21 @@ argument_specs:
description:
- Renew the cert when its remaining valid time crosses this threshold
- Uses the smallstep default (1/3 of the certs valid duration) if left undefined
step_acme_cert_post_renewal_shell:
type: str
default: /bin/sh
description:
- Shell with which to run commands specified in "step_acme_cert_post_renewal_commands"
- Must be a valid shell
step_acme_cert_post_renewal_commands:
type: list
elements: str
default: []
description:
- Run these commands after a cert renewal
- Must be a list of commands executable with the shell specified in "step_acme_cert_post_renewal_shell"
- "${STEP_CLI}, ${CERT_FILE} and ${KEY_FILE} are available for use. All will be absolute paths to files."
- "Example: C(['cp ${CERT_FILE} /path/to/somewhere/', 'chmod 400 ${KEY_FILE}'])"
step_acme_cert_renewal_reload_services:
type: list
elements: str
Expand Down
8 changes: 8 additions & 0 deletions roles/step_acme_cert/tasks/renewal.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@
changed_when: no
check_mode: no

- name: Post renewal hook script is present
template:
src: step-post-renew-hook.sh.j2
dest: "{{step_cli_steppath}}/{{ step_acme_cert_renewal_service }}_post.sh"
owner: root
group: root
mode: 0744
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason for going with 744 over 755 here? I'm more used to seeing the latter


- name: Renewal service is installed
template:
src: step-renew.service.j2
Expand Down
12 changes: 12 additions & 0 deletions roles/step_acme_cert/templates/step-post-renew-hook.sh.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!{{ step_acme_cert_post_renewal_shell }}
####### added by ansible: maxhoesel.smallstep.step_acme_cert - changes will be overwritten #######
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like a good place to include {{ ansible_managed }}

set -eu
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe also add set -o pipefail for good measure?

export STEP_CLI="{{ step_cli_executable_absolute.stdout }}"
export CERT_FILE="{{ step_acme_cert_certfile_full.path }}"
export KEY_FILE="{{ step_acme_cert_keyfile_full.path }}"
Comment on lines +4 to +6
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know how I feel about these. I get that they're convenient shorthands and that we kind of need them (since we are using step_acme_key/certfile_*full* internally, so we can't just tell people to use step_came_cert_certfile.path or whatever), but i'm wondering whether there's a way to avoid adding these. Then again, I guess having them doesn't hurt either ...

{% for command in step_acme_cert_post_renewal_commands -%}
{{ command }}
{% endfor -%}
{% if step_acme_cert_renewal_reload_services -%}
systemctl try-reload-or-restart {{ step_acme_cert_renewal_reload_services | join(' ') }}
{% endif -%}
2 changes: 1 addition & 1 deletion roles/step_acme_cert/templates/step-renew.service.j2
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Type=simple
Restart=always
RestartSec=1
Environment=STEPPATH={{ step_cli_steppath }}
ExecStart={{ step_cli_executable_absolute.stdout }} ca renew {{ step_acme_cert_certfile_full.path }} {{ step_acme_cert_keyfile_full.path }} --daemon --force{% if step_acme_cert_renewal_when is defined %} --expires-in {{ step_acme_cert_renewal_when }}{% endif %}{% if step_acme_cert_renewal_reload_services %} --exec "systemctl try-reload-or-restart {{ step_acme_cert_renewal_reload_services | join(' ') }}"{% endif %}
ExecStart={{ step_cli_executable_absolute.stdout }} ca renew {{ step_acme_cert_certfile_full.path }} {{ step_acme_cert_keyfile_full.path }} --daemon --force{% if step_acme_cert_renewal_when is defined %} --expires-in {{ step_acme_cert_renewal_when }}{% endif %}{% if step_acme_cert_post_renewal_commands or step_acme_cert_renewal_reload_services %} --exec "{{ step_acme_cert_post_renewal_shell }} {{ step_cli_steppath }}/{{ step_acme_cert_renewal_service }}_post.sh"{% endif %}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that the script already has a shebang, why don't we make the script executable and call it directly here? So --exec /root/.step/renewal_post.sh instead of a call to the shell with parameters?


[Install]
WantedBy=multi-user.target