Q:

What is the best practice for ensuring idempotency for downloading a binary with Ansible?

I am writing an ansible playbook to install the Elastic stack with each component of the stack broken out into a separate role.  During the playbook execution I use the unarchive module to fetch the binary from the vendor and untar it.
Something like:
- name: Install | Get binary
  unarchive:
    src: "{{ elasticsearch_download_url }}"
    dest: "{{ base_dir }}"
    remote_src: yes

The problem I'm running into is idempotence in the downloading of the binary.  To my knowledge, true idempotence during the playbook run would be a bunch of "ok" responses and no "changed" responses.
Is there a best practice when it comes to ensuring idempotence with downloading binaries?  I was thinking maybe a check for an existing install using a when: key, but I'm not 100% on that.
Thanks for the help!

A:

There are several possible solution to your overall question (depending on e.g. the role being able to manage upgrades, decoupling downloading and unarchiving, etc.).
In your particular case and taking for granted that your elasticsearch_download_url does not change, you could achieve this easily using the creates option of the unarchive module:
- name: Install | Get binary
  unarchive:
    src: "{{ elasticsearch_download_url }}"
    dest: "{{ base_dir }}"
    remote_src: yes
    creates: "{{ base_dir }}/elasticsearch-x.y.z"

The dir in my example is totally made up for the occasion and should match the exact name of the created directory.
If you are interested in a slightly more complex example which handles version detection and upgrades for nexus, I happen to maintain a role which implemented all this as features: https://github.com/ansible-ThoTeam/nexus3-oss/blob/master/tasks/nexus_install.yml

