Ansible多主机条件判断异常:标准Cron任务未按预期排除指定主机
问题:Ansible多主机排除条件下Cron任务判断失效
我正尝试配置两种不同的cron任务:部分主机需执行标准cron任务,其余主机执行故障转移cron任务,同时要将somescript.sh复制到所有主机。
主机清单片段
[zaspare] host01.example.com host02.example.com host03.example.com host04.example.com host05.example.com host06.example.com host07.example.com host08.example.com
原Playbook(存在问题)
--- - name: Updating somescript hosts: zaspare become: yes tasks: - name: Copy somescript.sh script to /usr/local/bin copy: src: somescript.sh dest: /usr/local/bin/ owner: root group: root mode: 0755 - name: Setup standard crontab for somescript cron: name: Run somescript.sh job: /usr/local/bin/somescript.sh {{ inventory_hostname }} false cron_file: somescript user: root minute: "10" hour: "22" when: inventory_hostname != "host01.example.com" or inventory_hostname != "host02.example.com" or inventory_hostname != "host03.example.com" or inventory_hostname != "host04.example.com" or inventory_hostname != "host05.example.com" - name: Setup failover crontab for somescript cron: name: Run somescript.sh job: /usr/local/bin/somescript.sh {{ inventory_hostname }} true cron_file: somescript user: root minute: "10" hour: "22" when: inventory_hostname == "host01.example.com" or inventory_hostname == "host02.example.com" or inventory_hostname == "host03.example.com" or inventory_hostname == "host04.example.com" or inventory_hostname == "host05.example.com"
执行结果异常
TASK [Setup standard crontab for somescript]****************************** changed: [host06.example.com] changed: [host07.example.com] changed: [host01.example.com] changed: [host08.example.com] changed: [host02.example.com] changed: [host04.example.com] changed: [host03.example.com] changed: [host05.example.com] TASK [Setup failover crontab for somescript]****************************** skipping: [host06.example.com] skipping: [host07.example.com] skipping: [host08.example.com] changed: [host01.example.com] changed: [host02.example.com] changed: [host03.example.com] changed: [host04.example.com] changed: [host05.example.com]
单主机排除时Playbook可正常工作,但多主机排除时标准Cron任务在所有主机上都执行了。
解答
问题出在逻辑运算符使用错误:
你在标准Cron任务的when条件里用了or,但实际需要的是and。举个例子,对于host01.example.com,inventory_hostname != "host02.example.com"这个条件是成立的,所以整个or组合的结果为真,导致任务执行。
正确的逻辑应该是:仅当主机名不是host01到host05中的任何一个时,才执行标准Cron任务,也就是所有的!=条件必须同时满足,所以要用and连接。
另外,更简洁且易维护的写法是把需要排除的主机放到一个列表里,用not in来判断:
修正后的Playbook
--- - name: Updating somescript hosts: zaspare become: yes vars: failover_hosts: - host01.example.com - host02.example.com - host03.example.com - host04.example.com - host05.example.com tasks: - name: Copy somescript.sh script to /usr/local/bin copy: src: somescript.sh dest: /usr/local/bin/ owner: root group: root mode: 0755 - name: Setup standard crontab for somescript cron: name: Run somescript.sh job: /usr/local/bin/somescript.sh {{ inventory_hostname }} false cron_file: somescript user: root minute: "10" hour: "22" when: inventory_hostname not in failover_hosts - name: Setup failover crontab for somescript cron: name: Run somescript.sh job: /usr/local/bin/somescript.sh {{ inventory_hostname }} true cron_file: somescript user: root minute: "10" hour: "22" when: inventory_hostname in failover_hosts
这种写法不仅逻辑清晰,后续要添加或移除故障转移主机时,只需要修改failover_hosts变量即可,不需要调整条件判断语句。
内容的提问来源于stack exchange,提问作者Bianca_K
相关产品推荐
相关产品推荐

