我有一个剧本,其中的任务是使用delegate_to将模板文件复制到特定服务器:named" grover"
这里带有服务器结果的库存清单是:bigbird,grover,oscar
这些模板文件必须具有与每个服务器的主机名匹配的名称,并且委托服务器grover也必须拥有它自己的所述文件实例。仅当文件尚不存在时,才应执行此模板复制操作。 / tmp / grover预先存在于服务器grover上,并且它需要保持不变的playbook运行。
最后除了服务器grover上的/ tmp / grover之外,在运行之后还应该存在:/ tmp / bigbird和/ tmp / oscar也在服务器grover上。
我遇到的问题是,当剧本在没有任何条件的情况下运行时,它确实起作用,但随后它也会破坏/覆盖/ tmp / grover,这是不可接受的。
但是,如果我在之前的播放中添加任务来预先检查这些文件,然后在模板上播放条件,如果文件已经存在则跳过grover,它不仅会跳过grover,而且会跳过其他所有服务器也将在grover上运行该游戏。如果我尝试将其设置为在每个其他服务器BUT上运行,它仍将失败,因为委托服务器是grover并且将被跳过。
以下是实际的示例代码片段,由于主机模式,playbook正在所有3台服务器上运行:
- hosts: bigbird:grover:oscar
- name: File clobber check.
stat:
path: /tmp/{{ansible_hostname}}
register: clobber_check
delegate_to: "{{ item }}"
with_items:
- "{{ grover }}"
- name: Copy templates to grover.
template:
backup: yes
src: /opt/template
dest: /tmp/{{ansible_hostname}}
group: root
mode: "u=rw,g=rw"
owner: root
delegate_to: "{{ item }}"
with_items:
- "{{ grover }}"
when: ( not clobber_check.stat.exists ) and ( clobber_check is defined )
如果我运行它,并且/ tmp / grover存在于grover上,那么它将简单地跳过整个复制播放,因为条件在grover上失败了。因此,其他服务器永远不会将其/ tmp / bigbird和/ tmp / oscar模板复制到grover中。
最后,我想避免使用ghetto解决方案,比如保存grover原始配置文件的备份,允许使用clobber,然后将保存的文件作为最后一个任务复制回来。
我必须在这里遗漏一些东西,我不能成为遇到这种情况的唯一人。任何人都知道如何为此编码?
答案 0 :(得分:0)
这个问题的答案是删除代码中不必要的with_items。虽然使用with_items确实允许您委托给主机模式组,但它也可以使变量无法正确定义/分配给该组内的主机。
为delegate_to定义单个主机实体可修复此问题,然后在定义的所有主机上按预期执行任务。
康斯坦丁·苏沃洛夫应该得到这一点,因为他是最初的答案者。此外,我很惊讶Ansible不允许轻松委派给一组主机。他们必须有理由不允许这样做。