58

我正在尝试学习如何将 Ansible 事实用作变量,但我不明白。当我跑...

$ ansible localhost -m setup

...它列出了我系统的所有事实。我随机选择了一个尝试使用它,ansible_facts.ansible_date_time.date,但我不知道如何使用它。当我跑...

$ 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
}

所以,它很明显就在那里。但是当我跑...

$ 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

我没有得到什么?如何使用 Facts 作为变量?

4

5 回答 5

95

该命令ansible localhost -m setup基本上说“针对本地主机运行设置模块”,设置模块收集您在输出中看到的事实。

当您运行echo命令时,这些事实不存在,因为设置模块没有运行。测试这样的事情的更好方法是使用 ansible-playbook 运行一个看起来像这样的剧本:

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

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

因为这是作为剧本运行的,所以在运行任务之前收集了 localhost 的事实。上述剧本的输出将是这样的:

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
于 2015-07-09T17:02:03.223 回答
21

ansible 的查找模块对我来说很好用。yml 是:

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

您可以用日期替换任何命令以获取命令的结果。

于 2017-08-04T03:17:19.240 回答
5

请注意,该ansible命令不会收集事实,但该ansible-playbook命令会。运行ansible -m setup时,设置模块碰巧运行事实集合,以便您获得事实,但运行ansible -m command没有。因此无法获得事实。这就是为什么其他答案包括剧本 YAML 文件并指示查找有效的原因。

于 2017-09-13T16:44:42.127 回答
0

filter 选项只过滤 ansible_facts 下面的第一级子键

于 2018-04-09T05:00:05.120 回答
0

我尝试了 lookup('pipe,'date') 方法,当我将剧本推到塔上时遇到了麻烦。该塔以某种方式使用UTC时区。早在我 TZ 的 + 小时执行的所有游戏都会在实际日期后一天给我。

例如:如果我的 TZ 是亚洲/马尼拉,我应该有 UTC+8。如果我早于上午 8:00 在 Ansible Tower 中执行剧本,则日期将遵循 UTC+0 中的日期。我花了一段时间才找到这个案子。它让我可以使用日期选项 '-d \"+8 hours\" +%F'。现在它给了我想要的确切日期。

以下是我在剧本中设置的变量:

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

即使我现在在早上 8:00 之前运行它,这也会给我“cur_target_wd = 2020/05-May/28-Thu”的值。

于 2020-05-27T16:58:51.490 回答