我需要检查国家变量列表中的所有城市,看看它们是否包含Ansible主机名变量中的城市名称。
表示正在运行的主机可以在自己的主机名中包含城市名称。
- name: Find city
gather_facts: true
hosts: 10.72.45.12
vars:
counties:
Canada: ["ontario", "toronto", "montreal"]
Germany: ["berlin", "munich", "hamburg"]
USA: ["chicago", "ostin", "seattle"]
tasks:
- name: Getting counties by city
set_fact:
country: >-
{% for city in counties %}
{% if '{{ city }}' in '{{ ansible_hostname }}' %}
Canada
{% elif '{{ city }}' in '{{ ansible_hostname }}' %}
Germany
{% elif '{{ city }}' in '{{ ansible_hostname }}' %}
USA
{% else %}
Earth
{% endif %}
{% endfor %}
- debug:
var: country
代码中的一些错误
- Jinja分隔符不嵌套。如果您在语句分隔符
{% ... %}
中,则不需要表达式分隔符{{ ... }}
:{% if city in ansible_hostname %}
- 你将需要一个嵌套循环,因为城市是在你的
countries
字典列表 - 在字典上循环的语法与在列表上循环的语法略有不同:
{% for key, value in my_dict.items() %}
有了这些,您可以构造两个任务:
- set_fact:
country: >-
{% for country, cities in countries.items() -%}
{% for city in cities if city in ansible_hostname -%}
{{ country }}
{%- endfor %}
{%- endfor %}
vars:
countries:
Canada: ["ontario", "toronto", "montreal"]
Germany: ["berlin", "munich", "hamburg"]
USA: ["chicago", "austin", "seattle"]
- debug:
var: country | default('Earth', true)
可以产生如下内容:
ok: [foo_ontario_bar] =>
country | default('Earth', true): Canada
ok: [foo_berlin_bar] =>
country | default('Earth', true): Germany
ok: [foo_seattle_bar] =>
country | default('Earth', true): USA
ok: [foo_brussels_bar] =>
country | default('Earth', true): Earth
创建字典城市
- set_fact:
cities: "{{ cities|d({})|combine(dict(item.value|product([item.key]))) }}"
loop: "{{ countries|dict2items }}"
为
cities:
austin: USA
berlin: Germany
chicago: USA
hamburg: Germany
montreal: Canada
munich: Germany
ontario: Canada
seattle: USA
toronto: Canada
然后选择城市
- hosts: foo_ontario_bar,foo_berlin_bar,foo_seattle_bar,foo_brussels_bar
vars:
countries:
Canada: [ontario, toronto, montreal]
Germany: [berlin, munich, hamburg]
USA: [chicago, austin, seattle]
tasks:
- set_fact:
cities: "{{ cities|d({})|combine(dict(item.value|product([item.key]))) }}"
loop: "{{ countries|dict2items }}"
run_once: true
- debug:
msg: >-
{{ inventory_hostname }} match
{{ _cities|zip(_countries)|map('join', '/')|list }}
vars:
_cities: "{{ cities|select('in', inventory_hostname) }}"
_countries: "{{ _cities|map('extract', cities)|list }}"
给(简略)
msg: foo_ontario_bar match ['ontario/Canada']
msg: foo_berlin_bar match ['berlin/Germany']
msg: foo_seattle_bar match ['seattle/USA']
msg: foo_brussels_bar match []