用于处理 Linux 和 Windows 主机的 Ansible playbook

Pat*_*ick 5 ansible ansible-2.x

尝试编写一个剧本来检查一组文件是否存在于一组服务器(Linux 和 Windows 主机)上,如果存在,则替换这些文件。

这是我到目前为止所拥有的:

---
- hosts: "{{hosts}}"
  vars:
    scripts:
      - check_blackout.pl
      - check_empty.pl
  tasks:
    - name: windows stat
      with_items: "{{scripts}}"
      win_stat: path=D:\scripts\{{item}}
      register: windows_stat
      when: "'windows' in group_names"
    - name: other stat
      with_items: "{{scripts}}"
      stat: path=/usr/local/bin/{{item}}
      register: other_stat
      remote_user: "{{script_owner | default(ansible_user)}}"
      when: "'windows' not in group_names"
    - name: windows debug
      with_items: "{{windows_stat.results}}"
      debug: var={{item.item}}
      when: "{{item.stat.exists}}"
    - name: other debug
      with_items: "{{other_stat.results}}"
      debug: var={{item.item}}
      when: "{{item.stat.exists}}"
...
Run Code Online (Sandbox Code Playgroud)

当我在 Windows 和 Linux 主机上运行此程序进行测试时,我得到以下信息:

[ansible@vmhklftpscdv1 ~]$ ansible-playbook test.yml -e "hosts=vmhkge1jasdev01,jdeesbkup" --ask-vault-pass
Vault password: 

PLAY [vmhkge1jasdev01,jdeesbkup] ************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************
ok: [vmhkge1jasdev01]
ok: [jdeesbkup]

TASK [windows stat] *************************************************************************************************************************************************************
skipping: [jdeesbkup] => (item=check_blackout.pl) 
skipping: [jdeesbkup] => (item=check_empty.pl) 
ok: [vmhkge1jasdev01] => (item=check_blackout.pl)
ok: [vmhkge1jasdev01] => (item=check_empty.pl)

TASK [other stat] ***************************************************************************************************************************************************************
skipping: [vmhkge1jasdev01] => (item=check_empty.pl) 
skipping: [vmhkge1jasdev01] => (item=check_blackout.pl) 
ok: [jdeesbkup] => (item=check_blackout.pl)
ok: [jdeesbkup] => (item=check_empty.pl)

TASK [windows debug] ************************************************************************************************************************************************************
skipping: [vmhkge1jasdev01] => (item={'_ansible_parsed': True, u'stat': {u'exists': False}, '_ansible_item_result': True, '_ansible_no_log': False, u'changed': False, 'item': u'check_empty.pl', 'invocation': {'module_name': u'win_stat'}}) 
skipping: [vmhkge1jasdev01] => (item={'_ansible_parsed': True, u'stat': {u'exists': False}, '_ansible_item_result': True, '_ansible_no_log': False, u'changed': False, 'item': u'check_blackout.pl', 'invocation': {'module_name': u'win_stat'}}) 
fatal: [jdeesbkup]: FAILED! => {"failed": true, "msg": "The conditional check '{{item.stat.exists}}' failed. The error was: error while evaluating conditional ({{item.stat.exists}}): 'dict object' has no attribute 'stat'\n\nThe error appears to have been in '/home/ansible/test.yml': line 19, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n      when: \"'windows' not in group_names\"\n    - name: windows debug\n      ^ here\n"}

TASK [other debug] **************************************************************************************************************************************************************
fatal: [vmhkge1jasdev01]: FAILED! => {"failed": true, "msg": "The conditional check '{{item.stat.exists}}' failed. The error was: error while evaluating conditional ({{item.stat.exists}}): 'dict object' has no attribute 'stat'\n\nThe error appears to have been in '/home/ansible/test.yml': line 23, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n      when: \"{{item.stat.exists}}\"\n    - name: other debug\n      ^ here\n"}
        to retry, use: --limit @/home/ansible/test.retry

PLAY RECAP **********************************************************************************************************************************************************************
jdeesbkup                  : ok=2    changed=0    unreachable=0    failed=1   
vmhkge1jasdev01            : ok=2    changed=0    unreachable=0    failed=1   

[ansible@vmhklftpscdv1 ~]$ 
Run Code Online (Sandbox Code Playgroud)

我有什么想法可以让它发挥作用吗?
我尝试了各种组合,包括在检查结果之前检查组成员身份:

  when: "'windows' in group_names and {{item.stat.exists}}"
Run Code Online (Sandbox Code Playgroud)

item.stat然而,即使条件的第一部分为假,Ansible 似乎仍然会检查该字段。

或者我的基本方法是错误的,我应该将这些任务分成不同的剧本吗?

tec*_*raf 1

是的你是对的。with_items之前评估过when。您可以添加默认的空列表以避免错误:

- name: other debug
  with_items: "{{other_stat.results | default([]) }}"
  debug: var={{item}}
  when: "{{item.stat.exists | default(false)}}"
Run Code Online (Sandbox Code Playgroud)