条件 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
如何与 includes 和 roles 一起工作。
在您的情况下,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" 与角色一起使用。
我有一个角色,我想执行多次,每次执行都有不同的变量。但是,我也希望其中一些执行是有条件的。
这是一个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
如何与 includes 和 roles 一起工作。
在您的情况下,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" 与角色一起使用。