Ansible date variable
Asked Answered
M

6

64

I'm trying to learn how to use Ansible facts as variables, and I don't get it. When I run...

$ ansible localhost -m setup

...it lists all of the facts of my system. I selected one at random to try and use it, ansible_facts.ansible_date_time.date, but I can't figure out HOW to use it. When I run...

$ ansible localhost -m setup -a "filter=ansible_date_time"
localhost | success >> {
    "ansible_facts": {
        "ansible_date_time": {
            "date": "2015-07-09",
            "day": "09",
            "epoch": "1436460014",
            "hour": "10",
            "iso8601": "2015-07-09T16:40:14Z",
            "iso8601_micro": "2015-07-09T16:40:14.795637Z",
            "minute": "40",
            "month": "07",
            "second": "14",
            "time": "10:40:14",
            "tz": "MDT",
            "tz_offset": "-0600",
            "weekday": "Thursday",
            "year": "2015"
        }
    },
    "changed": false
}

So, it's CLEARLY there. But when I run...

$ ansible localhost -a "echo {{ ansible_facts.ansible_date_time.date }}"
localhost | FAILED => One or more undefined variables: 'ansible_facts' is undefined

$ ansible localhost -a "echo {{ ansible_date_time.date }}"
localhost | FAILED => One or more undefined variables: 'ansible_date_time' is undefined

$ ansible localhost -a "echo {{ date }}"
localhost | FAILED => One or more undefined variables: 'date' is undefined

What am I not getting here? How do I use Facts as variables?

Moose answered 9/7, 2015 at 16:45 Comment(0)
S
104

The command ansible localhost -m setup basically says "run the setup module against localhost", and the setup module gathers the facts that you see in the output.

When you run the echo command these facts don't exist since the setup module wasn't run. A better method to testing things like this would be to use ansible-playbook to run a playbook that looks something like this:

- hosts: localhost
  tasks:
      - debug: var=ansible_date_time

      - debug: msg="the current date is {{ ansible_date_time.date }}"

Because this runs as a playbook facts for localhost are gathered before the tasks are run. The output of the above playbook will be something like this:

PLAY [localhost] **************************************************

GATHERING FACTS ***************************************************************
ok: [localhost]

TASK: [debug var=ansible_date_time] *******************************************
ok: [localhost] => {
    "ansible_date_time": {
        "date": "2015-07-09",
        "day": "09",
        "epoch": "1436461166",
        "hour": "16",
        "iso8601": "2015-07-09T16:59:26Z",
        "iso8601_micro": "2015-07-09T16:59:26.896629Z",
        "minute": "59",
        "month": "07",
        "second": "26",
        "time": "16:59:26",
        "tz": "UTC",
        "tz_offset": "+0000",
        "weekday": "Thursday",
        "year": "2015"
    }
}

TASK: [debug msg="the current date is {{ ansible_date_time.date }}"] **********
ok: [localhost] => {
    "msg": "the current date is 2015-07-09"
}

PLAY RECAP ********************************************************************
localhost      : ok=3    changed=0    unreachable=0    failed=0
Stanwood answered 9/7, 2015 at 17:2 Comment(0)
C
25

The lookup module of ansible works fine for me. The yml is:

- hosts: test
  vars:
    time: "{{ lookup('pipe', 'date -d \"1 day ago\" +\"%Y%m%d\"') }}"

You can replace any command with date to get result of the command.

Curbstone answered 4/8, 2017 at 3:17 Comment(3)
This solution is much shorter compared to other answers especially if you want to define something in date and time format. I have used something like {{ lookup('pipe', 'date +%Y-%m-%d-%H-%M-%S')}}.sql. ThanksAubree
This is a good solution especially if you don't (or can't) gather facts from the host.Hyaena
But the downside of this method is that, vars are lazy evaluated, so if this var is accessed on the other day (maybe the playbook span over the midnight), the var will have different valueSeaborg
N
6

Note that the ansible command doesn't collect facts, but the ansible-playbook command does. When running ansible -m setup, the setup module happens to run the fact collection so you get the facts, but running ansible -m command does not. Therefore the facts aren't available. This is why the other answers include playbook YAML files and indicate the lookup works.

Name answered 13/9, 2017 at 16:44 Comment(0)
U
0

The filter option filters only the first level subkey below ansible_facts

Undistinguished answered 9/4, 2018 at 5:0 Comment(0)
D
0

I tried the lookup('pipe,'date') method and got trouble when I push the playbook to the tower. The tower is somehow using UTC timezone. All play executed as early as the + hours of my TZ will give me one day later of the actual date.

For example: if my TZ is Asia/Manila I supposed to have UTC+8. If I execute the playbook earlier than 8:00am in Ansible Tower, the date will follow to what was in UTC+0. It took me a while until I found this case. It let me use the date option '-d \"+8 hours\" +%F'. Now it gives me the exact date that I wanted.

Below is the variable I set in my playbook:

  vars:
    cur_target_wd: "{{ lookup('pipe','date -d \"+8 hours\" +%Y/%m-%b/%d-%a') }}"

That will give me the value of "cur_target_wd = 2020/05-May/28-Thu" even I run it earlier than 8:00am now.

Dropline answered 27/5, 2020 at 16:58 Comment(2)
There is other way to make sure it apply a correct date regardless of were to run the playbook. **cur_target_wd: "{{ lookup('pipe','TZ=Asia/Manila date +%Y/%m-%b/%d-%a') }}"Dropline
Thank you so much I was looking exactly for that TZ notation. In my case I used TZ=Australia/Melbourne and it worked perfectly!Coh
A
0

Since Ansible 2.8, you can use now function, which works even without gathering facts: https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_templating_now.html

For instance:

- hosts: localhost
  gather_facts: false
  tasks:

    - shell: "echo 'Current time: {{ now(utc=true,fmt='%Y-%m-%d %H:%M:%S') }}'"

Result is:

TASK [shell] ***************************************************************************************************************************************************************************************************************************
changed: [localhost] => {"changed": true, "cmd": "echo 'Current time: 2024-05-30 09:16:00'", "delta": "0:00:00.001380", "end": "2024-05-30 11:16:00.180860", "rc": 0, "start": "2024-05-30 11:16:00.179480", "stderr": "", "stderr_lines
": [], "stdout": "Current time: 2024-05-30 09:16:00", "stdout_lines": ["Current time: 2024-05-30 09:16:00"]}
Accord answered 30/5 at 9:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.