运行 处于检查模式时跳过 Ansible 任务?

Skip Ansible task when running in check mode?

我正在编写一个 Ansible 剧本并且有一个任务在检查模式下总是会失败:

hosts: ...
tasks:
    - set_fact: filename="{{ansible_date_time.iso8601}}"
    - file: state=touch name={{filename}}
    - file: state=link src={{filename}} dest=latest

在检查模式下,将不会创建文件,因此 link 任务将始终失败。在检查模式下 运行 时,有没有办法标记要跳过的任务?类似于:

- file: state=link src={{filename}} dest=latest
  when: not check_mode

您可能只需为所有任务设置一个 when: filename is defined。缺点是,如果 filename 没有被定义,你不能在正常模式下失败。

hosts: ...
tasks:
    - set_fact: filename="{{ansible_date_time.iso_8601}}"
    - file: state=present name={{filename}}
      when: filename is defined
    - file: state=link src={{filename}} dest=latest
      when: filename is defined

我和unarchive有同样的情况:

unarchive 如果存档不存在且目标目录不存在(均在 unarchive 之前的步骤中完成),则检查模式失败。 我通过将 always_run: true 设置为准备步骤来解决这个问题,以便它们也以检查模式执行:

---

- name: create artifact directory
  file: {{ artifact_dest_dir }} state=directory
  always_run: true

- name: download artifact on the remote host
  get_url:
    url={{ artifact_url }}
    dest={{ artifact_dest_dir }}/{{ artifact_filename }}
    force=yes
  always_run: true

- name: unpack build artifact
  unarchive: src={{ artifact_dest_dir }}/{{ artifact_filename }}
             dest={{ artifact_dest_dir }}
             copy=no

它适用于我的情况,但对于依赖于时间的目录,这可能不是一个好的解决方案。

这里有一个 hacky 解决方案:

hosts: ...
tasks:
  - command: /bin/true
    register: noop_result
  - set_fact: check_mode={{ noop_result|skipped }}

  - set_fact: filename="{{ansible_date_time.iso_8601}}"
  - file: state=touch name={{filename}}
  - file: state=link src={{filename}} dest=latest
    when: not check_mode

在检查模式下,将跳过 command 任务,因此 check_mode 将设置为 true。当不处于检查模式时,任务应始终成功并且 check_mode 将设置为 false.

尽管有一个 already, I wanted to mention that the solution mentioned by augurar 对我不起作用,因为我不断收到以下错误:skipped expects a dictionary

最终为我工作的是一个稍微不那么棘手的解决方案,通过使用 -e 标志传递额外变量,如下所示:

# On the terminal
ansible-playbook [...] --check -e '{"check_mode":true}'

# In the playbook or role
when: [...] and not check_mode

# In the proper `group_vars/` file
check_mode: false

让我知道你们的想法!

其他需要注意的选项是标签或 --step 选项。

标签

tasks:
    - set_fact: filename="{{ansible_date_time.iso8601}}"
    - file: state=touch name={{filename}}
    - file: state=link src={{filename}} dest=latest
      tags:
        - test

那么要使用的 Ansible 命令是:

ansible-playbook example.yml --skip-tags "test" --check

还有其他示例 skipping/specifying 您想要 运行 使用 Ansible tags documentation 中的标签的任务。

开始和步骤

Ansible 还通过 --step 选项提供了一个很好的逐步调试模式。

运行 ansible-playbook example.yml --step --check 将以交互方式引导您完成剧本中的每个任务

来自 Ansible documentation 的“开始和步骤”部分:

This will cause ansible to stop on each task, and ask if it should execute that task. Say you had a task called “configure ssh”, the playbook run will stop and ask:

Perform task: configure ssh (y/n/c):

Answering “y” will execute the task, answering “n” will skip the task, and answering “c” will continue executing all the remaining tasks without asking.

Ansible 2.1 支持 ansible_check_mode 魔术变量,在检查模式下设置为 True (official docs)。这意味着您将能够做到这一点:

- file:
    state: link
    src: '{{ filename }}'
    dest: latest
  when: not ansible_check_mode

- file:
    state: link
    src: '{{ filename }}'
    dest: latest
  ignore_errors: '{{ ansible_check_mode }}'

你更喜欢哪个。