一个ansible-sensu-插件安装已创建角色,以便使用以下方式安装 sensu-plugins此代码:
- name: be sure sensu-plugins-{{ item.name }} is installed
command: sensu-install -p {{ item.name }}:{{ item.version }}
when: "'sensu-plugins-{{ item.name }} ({{ item.version }})' not in installed_plugins.stdout"
with_items: "{{ sensu_plugin_install }}"
还有另外两个角色需要 sensu-plugins。第一个角色需要邮件插件:
sensu_plugin_install:
- name: mailer
version: 1.0.0
sensu_plugin_install:
- name: cpu-checks
version: 1.0.0
- name: disk-checks
version: 2.0.1
- name: http
version: 1.0.0
- name: memory-checks
version: 1.0.2
- name: ntp
version: 1.0.0
角色一和角色二已包含在一本剧本中。
目前的结果
要么安装mailer
角色一中定义的插件,要么安装角色二中定义的插件。注释掉其中一个sensu_plugin_install
声明将安装与角色一或角色二相关的插件,例如,只会安装邮件程序插件:
TASK [030.sensu-plugin-install : be sure sensu-plugins-{{ item.name }} is
installed] ***
changed: [host.example.com] => (item={u'version': u'1.0.0', u'name':
u'mailer'}) => {"changed": true,
如果sensu_plugin_install
第二个角色的已经被注释掉。
预期结果
预期的结果是安装所有插件,在本例中是六个,而不是一个,即mailer
五个。
讨论
看起来数组不会被合并,因为将安装一个或五个插件而不是六个插件,并且需要注释掉其中一个插件才能强制安装插件。
解决这个问题的一个选项是合并这些数组,即sensu_plugin_install + sensu_plugin_install
。例如,在 Puppet 中,可以使用以下方法合并数组hiera_array
。在 Ansible 中如何实现这一点?
使用两个不同的变量为了解决这个问题不是一个选择,因为一个角色的功能被使用,并且如果另一个角色想要安装 sensu 插件,则不建议向该角色添加另一个变量。
答案1
首先,我必须定义两个不同的变量,而不是使用同一个变量,例如sensu_plugin_install
。在为第二个字典赋予不同的名称(如)后sensu_plugin_install_other
,两个数组就可以合并了:
with_items: "{{ sensu_plugin_install }} + {{ sensu_plugin_install_other }}"
答案2
尝试使用 ansible galaxy 中的这个角色https://galaxy.ansible.com/eugene0707/merge_custom_vars/
出于同样的原因,我前段时间也这么做过。它可以深度合并来自多个 vars 文件的字典,并设置自定义合并优先级。
此角色可以在 Ansible 2.0+ 下工作