运行 处于检查模式时跳过 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 }}'
你更喜欢哪个。
我正在编写一个 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
.
尽管有一个 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 }}'
你更喜欢哪个。