条件 Ansible 角色在已经执行时失败

Conditional Ansible roles fail when already executed

我有一个角色,我想执行多次,每次执行都有不同的变量。但是,我也希望其中一些执行是有条件的。

这是一个main.yml:

- hosts: localhost
  roles:
    - { role: test, test_files_group: 'a'}
    - { role: test, test_files_group: 'b', when: False}

这是来自 'test' 角色 (roles/test/tasks/main.yml) 的 main.yml:

- name: List files
  command: "find . ! -path . -type f"
  args:
    chdir: "{{ role_path }}/files/{{ test_files_group }}"
  register: files
- debug: var=files.stdout_lines

- name: do something with the files
  shell: "echo {{ item }}"
  with_items: "{{ files.stdout_lines }}"

这里是 ansible-playbook 命令输出的一部分:

TASK [test : List files] 

*******************************************************
changed: [localhost]

TASK [test : debug] ************************************************************
ok: [localhost] => {
    "files.stdout_lines": [
        "./testfile-a"
    ]
}

TASK [test : do something with the files] **************************************
changed: [localhost] => (item=./testfile-a)

TASK [test : List files] *******************************************************
skipping: [localhost]

TASK [test : debug] ************************************************************
skipping: [localhost]

TASK [test : do something with the files] **************************************
fatal: [localhost]: FAILED! => {"failed": true, "msg": "'dict object' has no attribute 'stdout_lines'"}

'a' 的一切都按预期工作,但是随后为 b 执行了 do something with the files 任务,即使我设置了 when: False.

我觉得我遗漏了什么 - 我想要的是 roles/test/tasks/main.yml 中的所有内容都使用 test_files_group 相应设置的 var 执行,或者根本不执行。我究竟做错了什么? :)

您可能想阅读 when 如何与 includesroles 一起工作。

在您的情况下,when: false 附加到第二个 运行 中的每个任务,因此您有:

- name: List files
  command: "find . ! -path . -type f"
  args:
    chdir: "{{ role_path }}/files/{{ test_files_group }}"
  register: files
  when: false

- debug: var=files.stdout_lines
  when: false

- name: do something with the files
  shell: "echo {{ item }}"
  with_items: "{{ files.stdout_lines }}"
  when: false

第一个和第二个任务被跳过(查看你的输出),并且在第三个任务中 when 语句应用于每次迭代,但是......首先 Ansible 尝试评估 with_items: "{{ files.stdout_lines }}"并且没有这样做,因为 List files 任务被跳过,所以没有 files.stdout_lines.

如果你想解决这个问题,请使用默认的 for 循环参数,例如:

with_items: "{{ files.stdout_lines | default([]) }}"

但我建议重构您的代码并且不要将 "conditionals" 与角色一起使用。