jms*_*rra 8 ansible ansible-playbook
我有这样的vars定义:
sites:
- site: mysite1.com
exec_init:
- "command1 to exec"
- "command2 to exec"
- site: mysite2.com
Run Code Online (Sandbox Code Playgroud)
然后我玩了以下任务
- name: Execute init scripts for all sites
shell: "{{item.1}}"
with_subelements:
- sites
- exec_init
when: item.0.exec_init is defined
Run Code Online (Sandbox Code Playgroud)
这里的想法是我将在我的vars中有多个"Site"定义和许多其他属性,然后我想为那些定义了"exec_init"的站点执行多个Shell脚本命令
这样做它只是总是跳过执行任务,我已经尝试了所有我能想象的组合,但我无法让它工作......
这是正确的做法吗?也许我正在努力实现一些没有意义的事情?
谢谢你的帮助
小智 17
还有另一种方法,尝试:
- debug: "var=item"
with_subelements:
- "{{ sites | selectattr('exec_init', 'defined') | list }}"
- exec_init
Run Code Online (Sandbox Code Playgroud)
感谢:https://github.com/PublicaMundi/ansible-plugins/blob/master/lookup_plugins/subelements_if_exist.py
嗯,看起来像元素的非均匀结构sites是with_subelements不喜欢的东西.而且item它不包含您在with_subelements列表中指定的子元素.你可以做几件事:
确保有一个exec_init列表,即使它是空的.with_subelements将跳过包含空子元素的项目.我认为这是最好的选择,虽然在编写剧本时有点不方便.
不要with_subelements自己使用和批量执行(有点难看):
- name: Execute init scripts for all sites
shell: "echo '{{item.exec_init | join(';')}}' | bash"
when: item.exec_init is defined
with_items: sites
Run Code Online (Sandbox Code Playgroud)自定义,with_subelements以便具有缺少的子元素的项目.您可以复制原件(我的/usr/local/lib/python2.7/dist-packages/ansible/runner/lookup_plugins/with_subelements.py)并将其放在lookup_plugins您的剧本旁边的目录中,使用不同的名称(例如subelements_missingok.py).然后改变第59行:
raise errors.AnsibleError("could not find '%s' key in iterated item '%s'" % (subelement, item0))
Run Code Online (Sandbox Code Playgroud)
至:
continue
Run Code Online (Sandbox Code Playgroud)
然后你的任务看起来像这样:
- name: Execute init scripts for all sites
debug: "msg={{item.1}}"
with_subelements_missingok:
- sites
- exec_init
Run Code Online (Sandbox Code Playgroud)还有另外一种方法,使用skip_missing标志(Ansible 2.0+):
- name: nested loop skip missing elements
with_subelements:
- sites
- exec_init
- flags:
skip_missing: true
Run Code Online (Sandbox Code Playgroud)
此处的有效解决方案(考虑 ansible 2.7+)是使用loop而不是with_subelements. 与循环一样,您可以应用subelements过滤器,它有skip_missing选项(即@hkariti 在选项 3 中建议的但以正确的方式)。
因此,代码应如下所示:
- name: Execute init scripts for all sites
shell: "{{ item.1 }}"
loop: "{{ sites | subelements('exec_init', skip_missing=True) }}"
Run Code Online (Sandbox Code Playgroud)