Ansible中如何匹配ansible_hostname包含的城市名获取对应国家
问题根因
原Playbook无法实现需求,存在4个明确的错误:
- Jinja2语法错误:在
{% %}流程控制块内部,变量可以直接引用,不需要额外包裹{{ }}插值标记,错误嵌套后会把变量名当成普通字符串处理,完全无法读取实际变量值 - 遍历逻辑错误:
{% for city in counties %}实际遍历的是counties字典的顶层键(也就是Canada、Germany、USA三个国家名),根本没有遍历到每个国家下属的城市列表 - 判断分支无效:三个if/elif分支的判断条件完全一致,根本无法区分匹配到的城市对应的所属国家
- 结果覆盖问题:就算匹配到正确城市,循环不会终止,后续的判断分支会把正确结果覆盖为默认的
Earth
修正后代码
直接替换原有任务即可,修复了所有上述问题,同时增加了大小写兼容逻辑,避免主机名大小写差异导致匹配失败:
- 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 country by city matched in hostname set_fact: country: >- {% set result = 'Earth' %} {% for c_name, c_list in counties.items() %} {% for city in c_list %} {% if city in ansible_hostname | lower %} {% set result = c_name %} {% break %} {% endif %} {% endfor %} {% if result != 'Earth' %}{% break %}{% endif %} {% endfor %} {{ result }} - debug: var: country
逻辑说明
- 初始化匹配结果默认值为
Earth,适配无匹配城市的场景 - 第一层循环遍历
counties字典的键值对,同时拿到国家名和对应下属城市列表 - 第二层循环遍历当前国家下的所有城市,将主机名统一转为小写后判断是否包含当前城市名,规避大小写不匹配问题
- 一旦匹配到对应城市,立刻更新结果为当前国家名,通过
break终止两层循环,避免后续逻辑覆盖正确结果 - 两层循环全部执行完仍无匹配时,直接返回默认值
Earth
注:原变量中美国城市列表下的
ostin应为拼写错误,如果是指奥斯汀市,正确拼写为austin,可根据实际需求调整。
内容的提问来源于stack exchange,提问作者Disbalance
相关产品推荐
相关产品推荐

