I am creating this thread to catalog my trials, errors and triumphs as I work through my Ansible collection.
Today I came across an issue while testing. I use Vagrant to test a variety of operating systems. I take a snapshot of the VMs just after I initialize them so I can return them to a clean state for testing. Unfortunately, in some operating systems, this means that the system clock is stuck at the time of the snapshot after a restore. This becomes an issue when I go to install anything with a package manager because the repository certificates appear to be coming from the future which causes the installation or cache update to fail. This is even more problematic on OS’s that don’t come with Python installed since that limits me to using only the script
and raw
modules to configure the host.
So, this is my time sync task file. It only relies on the raw
module to configure the host and assumes that time on localhost is correct. It does handle disparate time zones by configuring everything in GMT/UTC (but without actually changing the timezone of localhost or target host). And it is check_mode compliant.
- name: Get platform
ansible.builtin.raw: uname
register: uname_reg
changed_when: false
- name: Get time from the host
ansible.builtin.raw: date -u '+%Y-%m-%d %H:%M:%S'
register: remote_date_reg
changed_when: false
- name: Calculate difference in dates
ansible.builtin.set_fact:
date_diff: "{{ (( local_date_var | to_datetime
- remote_date_var | to_datetime ).total_seconds() / 60)
| int
| abs }}"
vars:
local_date_var: "{{ now(true, '%Y-%m-%d %H:%M:%S') }}"
remote_date_var: "{{remote_date_reg['stdout_lines'][0]}}"
- name: Sync time between remote host and localhost
block:
- name: Times are in sync within 5 minutes
ansible.builtin.assert:
that: date_diff | int < 5
quiet: true
rescue:
- name: Use date format mmddHHMMccyy.ss
ansible.builtin.set_fact:
date_format: '%m%d%H%M%Y.%S'
when: uname_reg['stdout_lines'][0] | lower in ['linux', 'darwin']
- name: Use date format ccyymmddHHMM.ss
ansible.builtin.set_fact:
date_format: '%Y%m%d%H%M.%S'
when: uname_reg['stdout_lines'][0] | lower in ['freebsd', 'openbsd']
- name: Set date
ansible.builtin.raw: >
TZ=GMT {{ ansible_become_method | default('') }} date {{local_date_var}}
vars:
local_date_var: "{{ now(true, date_format) }}"
when: not ansible_check_mode