'ansible_date_time' is undefined
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
ansible_date_time is a built-in Ansible fact that provides date and time information from the target host. The error 'ansible_date_time' is undefined means Ansible facts were not collected before the task that references this variable. This happens when gather_facts: false is set in the play, when the task runs on a host that was not included in fact gathering, or when fact caching is misconfigured.
What ansible_date_time Contains
ansible_date_time is a dictionary populated during fact gathering with keys like date, time, iso8601, epoch, year, month, day, hour, minute, and second.
Cause 1: gather_facts: false
The most common cause. When you disable fact gathering, no ansible_* variables are available.
Fix: Enable fact gathering
Fix: Gather facts manually with setup module
If you need gather_facts: false for performance but still need date/time:
The filter parameter limits fact collection to matching keys, which is faster than gathering all facts.
Cause 2: Using ansible_date_time in a Role or Include Before Facts Are Gathered
Fix by ensuring fact gathering runs first, or by placing the setup task in pre_tasks:
Cause 3: Delegated Tasks
When you delegate a task to a different host, the facts available are from the delegated host, not the original. If the delegated host has not had facts gathered, ansible_date_time is undefined.
Fix with delegate_facts or gather facts on localhost separately:
Alternative: Use Jinja2 now() Filter
Ansible 2.8+ provides the now() function, which does not depend on fact gathering:
now() runs on the controller, not the target host. If you need the target host's time, you must use ansible_date_time with fact gathering enabled.
Cause 4: Fact Caching Issues
If you use fact caching (fact_caching = jsonfile or redis in ansible.cfg) and the cache is stale or empty, facts may be missing.
Common Pitfalls
- Assuming facts are always available:
gather_facts: falsedisables allansible_*variables, not just hardware facts. If your playbook setsgather_facts: falsefor speed, you must explicitly gather the facts you need with thesetupmodule. - Using
ansible_date_timefor the controller's time:ansible_date_timereflects the target host's clock, which may differ from the Ansible controller. Usenow()for controller time oransible_date_timefor target time. - Time zone differences:
ansible_date_timeuses the target host's configured timezone. Two hosts in different timezones will return different values. Useansible_date_time.iso8601(UTC) for consistency. - Stale cached facts: With fact caching enabled,
ansible_date_timemay return the cached time from a previous run, not the current time. Disable caching or force refresh for time-sensitive tasks. now()vsansible_date_time:now()is evaluated at template render time on the controller.ansible_date_timeis collected during fact gathering on the target. They serve different purposes and return different times if the controller and target clocks differ.
Summary
ansible_date_timerequires fact gathering — setgather_facts: trueor run thesetupmodule manually- Use
setup: filter=ansible_date_timeto gather only date/time facts for better performance - For controller-side time without fact gathering, use the
now()Jinja2 function (Ansible 2.8+) - Delegated tasks use the delegated host's facts — gather facts on that host first or use
hostvars ansible_date_timereflects the target host's timezone; use.iso8601for UTC consistency

