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

create pre and post hooks #80

Merged

Conversation

wvh-github
Copy link
Contributor

Cleaned up version of pr 75.

  • Move 'stop' services to pre-hook and post-hook. This way they will also be stopped and started when renewing.
  • remove service stop/start tasks
  • add pre-hook/post-hook templates
  • add pre-hook/pos-hook template tasks
  • create missing directories at first run
  • run pre and post hook during first manual run

* Move 'stop' services to pre-hook and post-hook. This way they will also be stopped and started when renewing.

- remove service stop/start tasks
- add pre-hook/post-hook templates
- add pre-hook/pos-hook template tasks
- create missing directories at first run
- run pre and post hook during first manual run
@wvh-github
Copy link
Contributor Author

@nkakouros
Copy link

I find this really useful. I think two more tasks should be added to allow for the user to define their own hooks. For instance, I would like to copy some certificates somewhere upon renewal. This is not possible currently.

@febeling
Copy link

Would be great to get this included.

@giner
Copy link

giner commented Jan 15, 2020

Stopping a web server is not needed for renewal but for the first request of a new cert when certbot needs to listen in port 80 for the challenge. So Adding a script for reloading configurations of web servers to /etc/letsencrypt/renewal-hooks/deploy/ should be enough.

@tomasbedrich
Copy link

Its worth to say that new version of certbot supports this without a need to pass --pre/post-hook. See the documentation (search for renewal-hooks).

@geerlingguy
Copy link
Owner

geerlingguy commented Mar 10, 2020

In light of @tomasbedrich's comment is that something that we should consider in reworking this PR? (It seems like it could greatly simplify the work the Ansible role would have to do).

@tomasbedrich
Copy link

tomasbedrich commented Mar 11, 2020

This is the snippet which I use now:

- name: Create pre-renew hook to stop webservers
  copy:
    content: "#!/bin/bash\n\nsystemctl stop {{ item }}\n"
    dest: "/etc/letsencrypt/renewal-hooks/pre/stop_{{ item }}"
    mode: u+x
  loop: "{{ certbot_create_standalone_stop_services }}"

- name: Create post-renew hook to start webservers
  copy:
    content: "#!/bin/bash\n\nsystemctl start {{ item }}\n"
    dest: "/etc/letsencrypt/renewal-hooks/post/start_{{ item }}"
    mode: u+x
  loop: "{{ certbot_create_standalone_stop_services }}"

It is for systemd distors only, but feel free to use it as a base for something more universal.

@asfaltboy
Copy link

I was just bitten by this yet again, as the renewal job installed by the OS always ran exactly when new cert was available and the post-hooks of the daily cronjob setup by this role never fired 😢 .

@geerlingguy would you welcome a PR to allow users to specify some vars to modify the renewal configuration files , as an alternative to installing a second cronjob?

@funkyfuture
Copy link

fyi, i simplified @tomasbedrich's proposal for my usage, so that the renew-cron.yml looks like this:

---
- name: Add cron job for certbot renewal (if configured).
  cron:
    name: Certbot automatic renewal.
    job: "{{ certbot_script }} renew {{ certbot_auto_renew_options }}"
    minute: "{{ certbot_auto_renew_minute }}"
    hour: "{{ certbot_auto_renew_hour }}"
    user: "{{ certbot_auto_renew_user }}"
  when: ansible_service_mgr != "systemd"

- block:
  - name: Remove cron job for certbot renewal.
    cron:
      name: Certbot automatic renewal.
      state: absent
  - name: Configure renewal hooks to stop services
    copy:
      dest: /etc/letsencrypt/renewal-hooks/pre/stop_services
      content: |
        #!/bin/sh
        systemctl stop {{ certbot_create_standalone_stop_services | join(" ") }}
      mode: ug=rx,o=
  - name: Configure renewal hooks to start services
    copy:
      dest: /etc/letsencrypt/renewal-hooks/post/start_services
      content: |
        #!/bin/sh
        systemctl start {{ certbot_create_standalone_stop_services | join(" ") }}
      mode: ug=rx,o=
  when: ansible_service_mgr == "systemd"

i'd also propose to add a variable certbot_create_standalone_reload_services to point to services that don't need to be stopped but should be reloaded after the certificate was possibly renewed.

@stale
Copy link

stale bot commented Nov 26, 2020

This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution!

Please read this blog post to see the reasons why I mark pull requests as stale.

@stale stale bot added the stale label Nov 26, 2020
@funkyfuture
Copy link

@geerlingguy, i'd prefer a human decision how this pr is handled. i don't have a particular opinion on this proposed solution, but i'd appreciate some progress on the issue itself which i consider a bug.

@stale
Copy link

stale bot commented Dec 8, 2020

This issue is no longer marked for closure.

@stale stale bot removed the stale label Dec 8, 2020
@geerlingguy
Copy link
Owner

@funkyfuture - It's not a bug, but rather a missing feature. But one I do agree I'd like to support.

Copy link
Owner

@geerlingguy geerlingguy left a comment

Choose a reason for hiding this comment

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

It looks like there are also a couple new variables defined—I would prefer that we have them added in defaults (so like certbot_create_standalone_stop_services: []), and also mentioned in the parameters in the README with a brief explanation underneath.

tasks/create-cert-standalone.yml Outdated Show resolved Hide resolved
tasks/create-cert-standalone.yml Outdated Show resolved Hide resolved
{% for item in certbot_create_standalone_stop_services %}
echo "starting service {{ item }}"
{% if ansible_service_mgr == 'systemd' %}
systemctl start {{ item }}

Choose a reason for hiding this comment

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

the start subcommand can take all designated service names as arguments at once, reducing the downtime due to fewer invoked processes. the same applies to the stop_service.j2.

@funkyfuture funkyfuture mentioned this pull request Dec 18, 2020
@nierdz
Copy link

nierdz commented Dec 27, 2020

A more simple way to achieve this without modifying this role is to override certbot_create_command and add hooks to certbot_certs. Here is what I'm doing to get post-hooks but the idea is the same to get pre-hooks:

certbot_create_if_missing: true
certbot_create_standalone_stop_services: []
certbot_auto_renew: false # renew is already done by a cron inside certbot package
certbot_create_command: >-
  {{ certbot_script }} certonly
    --non-interactive
    --email "{{ cert_item.email }}"
    --agree-tos
    --dns-ovh
    --dns-ovh-credentials /infra/.ovh
    --post-hook "{{ cert_item.post_hook }}"
    --domains "{{ cert_item.domains | join(',') }}"

The cert creation process is handled here using dns but with standalone or webroot it's the same idea, the only important thing here is this line: --post-hook "{{ cert_item.post_hook }}" where I get post-hook.

And here is an example of one of my cert with containing my post_hook:

certbot_certs:
  - email: "{{ my_email }}"
    post_hook: "systemctl restart docker-compose@igln"
    domains:
      - igln.fr
      - www.igln.fr

This way I get a configuration file like this:

# cat /etc/letsencrypt/renewal/igln.fr.conf 
# renew_before_expiry = 30 days
version = 0.31.0
archive_dir = /etc/letsencrypt/archive/igln.fr
cert = /etc/letsencrypt/live/igln.fr/cert.pem
privkey = /etc/letsencrypt/live/igln.fr/privkey.pem
chain = /etc/letsencrypt/live/igln.fr/chain.pem
fullchain = /etc/letsencrypt/live/igln.fr/fullchain.pem

# Options used in the renewal process
[renewalparams]
account = 02a2c3e1ec7adda7a6d0e54a85ad3dbf
post_hook = systemctl restart docker-compose@igln
authenticator = dns-ovh
dns_ovh_credentials = /infra/.ovh
server = https://acme-v02.api.letsencrypt.org/directory

@geerlingguy geerlingguy merged commit 6bb2ed6 into geerlingguy:master May 28, 2021
geerlingguy added a commit that referenced this pull request May 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants