Ansible变量传递与任务执行目标问题:文件内容不符预期排查
问题分析与解答
清单文件
[app:children] CL #BA #EA #EB #EI [BA] TEST-cl1 ansible_user=ec2-user modulename=BA [CL] TEST-cl1 ansible_user=ec2-user modulename=CL TEST-cl1 ansible_user=ec2-user modulename=CL TEST-cl1 ansible_user=ec2-user modulename=CL [EA] TEST-cl1 ansible_user=ec2-user modulename=EA [EB] TEST-cl1 ansible_user=ec2-user modulename=EB [EI] TEST-cl1 ansible_user=ec2-user modulename=EI
Playbook文件
--- - name: RUNNING DEPLOYMENT TASKS hosts: app connection: ssh gather_facts: no remote_user: ec2-user tasks: - name: print visit particulars shell: echo {{ modulename }} >> f
问题1:文件f的实际内容
默认情况下,文件f中只会出现一行EI。
问题2:出现EI而非预期CL的原因
- 主机变量覆盖规则:
TEST-cl1同时存在于多个组中,Ansible对同一主机的组变量会按清单中组定义的先后顺序覆盖——后面定义的组的变量会覆盖前面的。EI组是清单最后定义的,因此modulename最终被设为EI,哪怕主机是通过app的子组CL选中的,变量取值依然遵循这个覆盖规则。 - 重复主机去重:
CL组里重复定义了三次TEST-cl1,但Ansible默认会对重复主机条目去重(可通过inventory_ignore_hosts_duplicates=False关闭此行为),所以任务只会执行一次,不会输出三次CL。
问题3:hosts: app的选中逻辑
hosts: app确实选中了app子组CL下的TEST-cl1,但Ansible的hosts参数选中的是主机而非组——只要主机属于目标组(或其子组)就会被选中,不管它还属于其他哪些组。你看到的EI不是因为选中了EI组的主机,而是该主机的变量被EI组的定义覆盖了。
解决方案:控制任务执行目标与变量取值
方式1:调整组定义顺序
把CL组放在清单最后,让它的modulename覆盖其他组的定义:
[BA] TEST-cl1 ansible_user=ec2-user modulename=BA [EA] TEST-cl1 ansible_user=ec2-user modulename=EA [EB] TEST-cl1 ansible_user=ec2-user modulename=EB [EI] TEST-cl1 ansible_user=ec2-user modulename=EI [CL] TEST-cl1 ansible_user=ec2-user modulename=CL TEST-cl1 ansible_user=ec2-user modulename=CL TEST-cl1 ansible_user=ec2-user modulename=CL [app:children] CL #BA #EA #EB #EI
方式2:强制指定变量值
在Playbook中直接定义modulename,它的优先级高于组变量:
--- - name: RUNNING DEPLOYMENT TASKS hosts: app connection: ssh gather_facts: no remote_user: ec2-user vars: modulename: CL tasks: - name: print visit particulars shell: echo {{ modulename }} >> f
方式3:通过组判断限制执行
仅当主机属于CL组时执行任务,同时锁定变量值:
--- - name: RUNNING DEPLOYMENT TASKS hosts: app connection: ssh gather_facts: no remote_user: ec2-user tasks: - name: print visit particulars shell: echo {{ modulename }} >> f when: "'CL' in group_names" vars: modulename: CL
方式4:设置组优先级
给CL组设置更高优先级,让它的变量不会被其他组覆盖:
[CL:vars] ansible_group_priority=10 # 数值越高优先级越高 [EI:vars] ansible_group_priority=1 # 其他组和主机定义不变
内容的提问来源于stack exchange,提问作者gk_2000
相关产品推荐
相关产品推荐

