我建立了以下列表,但我没有成功迭代它。 我应该使用with_items吗? with_elements?或其他什么?
我的目标是遍历广告资源中的所有主机,获取其名称和IP,最后打印出来。
- set_fact:
list_of_hosts: |
{% set myList = [] %}
{% for host in groups['all'] %}
{% set ignored = myList.extend([{'server_name': host, 'server_ip': hostvars[host].ansible_eth0.ipv4.address }]) %}
{% endfor %}
{{ myList }}
- debug: msg="{{ item.server_name }}"
with_items: "{{ list_of_hosts }}"
我调试时的列表如下:
TASK [common : debug] ************************************************************************************************
ok: [my1stServer] => {
"msg": " [{'server_ip': u'192.168.0.1', 'server_name': u'my1stServer'}, {'server_ip': u'192.168.0.2', 'server_name': u'my2ndServer'}]\n"
}
这是错误,但它并不真正相关:
fatal: [my1stServer]: FAILED! => {"failed": true, "msg": "the field 'args' has an invalid value, which appears to include a variable that is undefined. The error was: 'ansible.vars.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'server_name'\n\nThe error appears to have been in 'hosts.yml': line 19, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- debug: msg=\"{{ item.server_name }}\"\n ^ here\nWe could be wrong, but this one looks like it might be an issue with\nmissing quotes. Always quote template expression brackets when they\nstart a value. For instance:\n\n with_items:\n - {{ foo }}\n\nShould be written as:\n\n with_items:\n - \"{{ foo }}\"\n"}
答案 0 :(得分:0)
请原谅我的直言不讳,但是提议的实施使得我们努力了解这个想法究竟是什么。这很简单:打印hostvars[host]
中存在的一些变量,以获取按各种标准选择的主机列表。
如果我们保持实现接近这个想法,那么实现就更简单了。
那么我要做的是创建一个由组成员资格选择的主机列表,或者可能是“亲自挑选”,实际上就是我刚才写的:)。 考虑这个任务列表:
# this task creates an empty list
- name: create my_cool_list
set_fact:
my_cool_list: []
# this task adds to the list all hosts in groups we're iterating over
- name: update my cool list with whole groups
set_fact: '{{my_cool_list + groups[curr_grp]}}'
with_items:
- grp1
- grp2
loop_control:
loop_var: curr_grp
# this task adds to the list all hosts we're iterating over
- name: update my cool list with specific hosts
set_fact: '{{my_cool_list + [curr_node]}}'
with_items:
- node001
- node101
loop_control:
loop_var: curr_node
# now we can iterate over the list, accessing specific fields on each host
- name: go over my cool list and print ansible_init_mgr
debug:
msg: 'hostvars["{{curr_host}}"].ansible_init_mgr: {{hostvars[curr_host].ansible_init_mgr}}'
with_items: '{{my_cool_list|default([], true)|list}}'
此外,您可以通过验证您正在访问的密钥来定义安全when:
。
并且,要打印关于每个主机的一系列变量,您应该使用jinja过滤器map('extract',...)
:
- name: print some vars from each host
debug:
msg: {'server_name': '{{hostvars[curr_node]|selectattr("ansible_hostname")}}', 'ip_address': '{{hostvars[curr_node]|selectattr("ansible_eth0.ipv4.address")}}'}
with_items: '{{my_cool_list|default([], true)|list}}'
loop_control:
loop_var: curr_node
如果你想提高可读性,你最好编写一个过滤插件,它会做上面的事情,并以可读的方式隐藏迭代丑陋,所以你可以:
要么(对于通用方法,即没有重命名属性)
- name: print some vars from each host
debug:
msg: '{{my_cool_list|multi_select_in_dict(["ansible_hostname", "ansible_eth0.ipv4.address")}}'
或特定方法(以便您使用特定的硬编码重新映射属性...)
- name: print some vars from each host
debug:
msg: '{{my_cool_list|my_cool_filter}}'