Avoid the Changing Ansible Timestamp Gotcha

Tagged:

Ansible variables are evaluated each time they're used. This means the following playbook vars declaration will always return the current time where ever it's used in the playbook!:

vars:
  timestamp: "{{ lookup('pipe', 'date +%Y-%m-%d-%H%M') }}"

This is not the desired situation if the timestamp is used as part of a filename. For example: filename: "backup-{{timestamp}}.sql".

Fortunately, there's an easy solution.

Host fact variables, created with set_fact module, are evaluated once and persistent. To create a timestamp that does not change:

- set_fact:
    timestamp: "{{ lookup('pipe', 'date +%Y-%m-%d-%H%M') }}"

The follow playbook demonstrates the difference between playbook variables and host fact variables:

- hosts: example.com
  gather_facts: no

  vars:
    timestamp_var: "{{ lookup('pipe', 'date +%H:%M:%S') }}"

  tasks:
    - name: Set the playbook timestamp (so it doesn't change)
      set_fact:
        timestamp_host_fact: "{{ lookup('pipe', 'date +%H:%M:%S') }}"

    - debug:
        msg: "timestamp_var: {{ timestamp_var }} / timestamp_host_fact: {{ timestamp_host_fact }}"

    - pause:
        seconds: 3

    - debug:
        msg: "timestamp_var: {{ timestamp_var }} / timestamp_host_fact: {{ timestamp_host_fact }}"

Playbook run:

Playbook output