条件Ansible角色在执行后失败

时间:2017-01-16 18:43:57

标签: ansible ansible-role

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

这是一个main.yml:

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

以下是来自'测试'的主要内容。角色(roles/test/tasks/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'正如预期的那样,但是即使我设置了do something with the files,也会为b执行when: False任务。

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

1 个答案:

答案 0 :(得分:2)

您可能想了解when如何与包含角色一起使用。

在您的情况下,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

跳过第1和第2个任务(参见输出),并在第3个任务中when语句应用于每次迭代,但......首先Ansible尝试评估with_items: "{{ files.stdout_lines }}"并失败这样做,因为跳过列表文件任务,所以没有files.stdout_lines

如果要解决此问题,请使用default for loop参数,例如:

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

但我建议您重构代码并且不要使用"条件符号"有角色。