Search code examples
ansibleidempotent

How to make information retrieval idempotent in Ansible?


I'm trying to get information about a certificate on a server so that I can take an action if the certificate is close to expiring. The steps I'm taking are:

# Does the certificate already exist?
- name: certbot | does cert already exist
  stat:
    path: "/etc/letsencrypt/live/{{certbot_domain}}//cert.pem"
  register: certbot_certificate

# Get the expiration date for the certificate in ISO format.
- name: certbot | get cert expiration date
  shell: "date --date=\"$(openssl x509 -in /etc/letsencrypt/live/{{certbot_domain}}/cert.pem -noout -enddate | cut -d= -f 2)\" --iso-8601"
  register: certbot_expiration_date
  when: certbot_certificate.stat.exists == True

# Convert the expiration date into the number of seconds from today.
- name: certbot | calculating expiration in seconds
  shell: "echo $(($(date --date={{certbot_expiration_date.stdout}} +%s) - $(date +%s)))"
  register: certbot_expires_in
  when: certbot_certificate.stat.exists == True

My problem is that both of the shell commands are always being marked as "Changed" in Ansible, meaning that this playbook cannot be idempotent.

I understand why that is the case, because Ansible has no way of actually understanding what the shell command has done, so it is playing safe by saying "Changed", but I'm wondering if there is an idempotent way of achieving the same result?

Short of writing an extension, that is ... :)

Thanks.


Solution

  • The answer, as it turns out, is to add a changed_when statement to the task, e.g.:

    - name: certbot | get cert expiration date
      shell: "date --date=\"$(openssl x509 -in /etc/letsencrypt/live/{{certbot_domain}}/cert.pem -noout -enddate | cut -d= -f 2)\" --iso-8601"
      register: certbot_expiration_date
      changed_when: False
      when: certbot_certificate.stat.exists == True
    

    Since I know that the shell commands are not changing anything, I can safely set changed_when to false and this ensures that the final tally shows Changed=0, thus making the playbook idempotent.