使用可重用的 playbook 列出 ansible 中无法访问的服务器

问题描述 投票:0回答:1

我可以使用下面的 ansible 剧本列出

unreachable
服务器。

---
- name: "Play 1-Find the details here {{ source_host }} & {{ dest_host }}"

  hosts: localhost
  any_errors_fatal: True
  serial: 1

  vars:
    source_host: "{{ hostvars[inventory_hostname]['serverlist_input'] }}"

  gather_facts: no
  tasks:

    - add_host:
        name: "{{ item | trim }}"
        groups: source_node
        printback_rec: "{{ hostvars[inventory_hostname]['printback_input'] }}"
      with_items:
        - "{{ source_host.split(',') }}"

    - set_fact:
        rec_group_names: 'source_node'  


- name: Check unreachable hosts
  hosts: "{{ hostvars['localhost']['rec_group_names'] }}"
  gather_facts: true
  any_errors_fatal: false
  tasks:

    - name: Print group names
      debug:
        msg: "GROUP NAME TO BE TESTED: {{ group_names }}"

    - name: Perform ping in Template
      ping:

    - block:
        - debug:
            var: ansible_play_hosts_all
        - debug:
            var: ansible_play_hosts
        - set_fact:
            down: "{{ ansible_play_hosts_all|difference(ansible_play_hosts) }}"
        - debug:
            var: down
      run_once: true

    - name: "Display unreachable hosts one at a time {{ startlogstring | default('start:') }}"
      debug:
        msg: "Unreachable Host: {{ item }}"
      loop: "{{ ansible_play_hosts_all | difference(ansible_play_hosts) }}"
      run_once: true

    - fail:
        msg: "Exiting play if target hosts are unreachable"
      when: ansible_play_hosts_all != ansible_play_hosts  
      run_once: true

- name: Play 2- Configure Source nodes
  hosts: source_node
  gather_facts: false
  any_errors_fatal: false
  debugger: never
  ignore_unreachable: yes
  vars:
    ansible_ssh_common_args: '-o ConnectTimeout=2'  

  tasks:

    # - name: Detect unreachable hosts
    #   import_playbook: "{{ playbook_dir }}/generictask_templates/logunreachablehost.yml"

    - name: Perform ping
      ping:

所需输出:

PLAY [Play 1-Find the details here {{ source_host }} & {{ dest_host }}] ********

TASK [Reset Github logs] *******************************************************
changed: [localhost] => (item=precheck.log)

TASK [add_host] ****************************************************************
ok: [localhost] => (item=remotehost4)
ok: [localhost] => (item=remotehost3)
ok: [localhost] => (item=remotehost2)
ok: [localhost] => (item=remotehost1)

TASK [set_fact] ****************************************************************
ok: [localhost]

PLAY [Check unreachable hosts] *************************************************

TASK [Gathering Facts] *********************************************************
fatal: [remotehost1]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: Could not resolve hostname remotehost1: Name or service not known", "unreachable": true}
[WARNING]: Platform sunos on host remotehost3 is using the discovered Python
interpreter at /usr/bin/python3.9, but future installation of another Python
interpreter could change the meaning of that path. See
https://docs.ansible.com/ansible-
core/2.12/reference_appendices/interpreter_discovery.html for more information.
ok: [remotehost3]
[WARNING]: Platform linux on host remotehost4 is using the discovered Python
interpreter at /usr/local/bin/python3.9, but future installation of another
Python interpreter could change the meaning of that path. See
https://docs.ansible.com/ansible-
core/2.12/reference_appendices/interpreter_discovery.html for more information.
ok: [remotehost4]
[WARNING]: Platform linux on host remotehost2 is using the discovered Python
interpreter at /usr/local/bin/python3.9, but future installation of another
Python interpreter could change the meaning of that path. See
https://docs.ansible.com/ansible-
core/2.12/reference_appendices/interpreter_discovery.html for more information.
ok: [remotehost2]

TASK [Print group names] *******************************************************
ok: [remotehost4] => {
    "msg": "GROUP NAME TO BE TESTED: ['source_node']"
}

TASK [Perform ping in Template] ************************************************
ok: [remotehost3]
ok: [remotehost4]
ok: [remotehost2]

TASK [debug] *******************************************************************
ok: [remotehost4] => {
    "ansible_play_hosts_all": [
        "remotehost4",
        "remotehost3",
        "remotehost2",
        "remotehost1"
    ]
}

TASK [debug] *******************************************************************
ok: [remotehost4] => {
    "ansible_play_hosts": [
        "remotehost4",
        "remotehost3",
        "remotehost2"
    ]
}

TASK [set_fact] ****************************************************************
ok: [remotehost4]

TASK [debug] *******************************************************************
ok: [remotehost4] => {
    "down": [
        "remotehost1"
    ]
}

TASK [Display unreachable hosts one at a time start:] ***************
ok: [remotehost4] => (item=remotehost1) => {
    "msg": "Unreachable Host: remotehost1"
}


TASK [fail] ********************************************************************
fatal: [remotehost4]: FAILED! => {"changed": false, "msg": "Exiting play if target hosts are unreachable"}

NO MORE HOSTS LEFT *************************************************************

PLAY RECAP *********************************************************************
remotehost4                : ok=11   changed=1    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   
remotehost2                : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
remotehost1            : ok=0    changed=0    unreachable=1    failed=0    skipped=0    rescued=0    ignored=0   
localhost                  : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
remotehost3               : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

这是我的要求。

我希望创建一个可重复使用的模板

include_tasks
import_playbook
,我可以将任何
<groups>
传递给
hosts: 
,它将帮助我记录该
unreachable
的所有
group_name
服务器。

目的是在其他游戏中重用此模板/剧本来记录

unreachable
服务器。

我尝试了以下方法,但它不起作用并且出现错误:

第 1 步:创建名为“{{ playbook_dir }}/templates/logunreachable.yml”的可重用剧本,并从先前成功运行中复制相同的逻辑,无需任何更改:

cat {{ playbook_dir }}/templates/logunreachable.yml

- name: Check unreachable hosts
  hosts: "{{ hostvars['localhost']['rec_group_names'] }}"
  gather_facts: true
  any_errors_fatal: false
  tasks:

    - name: Print group names
      debug:
        msg: "GROUP NAME TO BE TESTED: {{ group_names }}"
      run_once: true


    - name: Perform ping in Template
      ping:

    - block:
        - debug:
            var: ansible_play_hosts_all
        - debug:
            var: ansible_play_hosts
        - set_fact:
            down: "{{ ansible_play_hosts_all|difference(ansible_play_hosts) }}"
        - debug:
            var: down
      run_once: true

    - name: "Display unreachable hosts one at a time {{ startlogstring | default('are-inject-start:') }}"
      debug:
        msg: "Unreachable Host: {{ item }}"
      loop: "{{ ansible_play_hosts_all | difference(ansible_play_hosts) }}"
      run_once: true

    - fail:
        msg: "Exiting play if target hosts are unreachable"
      when: ansible_play_hosts_all != ansible_play_hosts  
      run_once: true

在主剧本中,我

import
上述剧本并期望与以前类似的输出:

呼叫者剧本:

---
- name: "Play 1-Find the details here {{ source_host }} & {{ dest_host }}"

  hosts: localhost
  any_errors_fatal: True
  serial: 1

  vars:
    source_host: "{{ hostvars[inventory_hostname]['serverlist_input'] }}"

  gather_facts: no
  tasks:

    - add_host:
        name: "{{ item | trim }}"
        groups: source_node
        printback_rec: "{{ hostvars[inventory_hostname]['printback_input'] }}"
      with_items:
        - "{{ source_host.split(',') }}"

    - set_fact:
        rec_group_names: 'source_node'  
- name: Play 2- Configure Source nodes
  hosts: source_node
  gather_facts: false
  any_errors_fatal: false
  debugger: never
  ignore_unreachable: yes
  vars:
    ansible_ssh_common_args: '-o ConnectTimeout=2'  

  tasks:

    - name: Detect unreachable hosts
      import_playbook: "{{ playbook_dir }}/generictask_templates/logunreachablehost.yml"

    - name: Perform ping
      ping:

但是,输出并不像以前那样:

输出:

PLAY [Play 1-Find the details here {{ source_host }} & {{ dest_host }}] ********

TASK [Reset Github logs] *******************************************************
changed: [localhost] => (item=precheck.log)

TASK [add_host] ****************************************************************
ok: [localhost] => (item=remotehost4)
ok: [localhost] => (item=remotehost3)
ok: [localhost] => (item=remotehost2)
ok: [localhost] => (item=remotehost1)

TASK [set_fact] ****************************************************************
ok: [localhost]

PLAY [Play 2- Configure Source nodes] ******************************************

TASK [Detect unreachable hosts] ************************************************
fatal: [remotehost1]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: Could not resolve hostname remotehost1: Name or service not known", "skip_reason": "Host remotehost1 is unreachable", "unreachable": true}
[WARNING]: Platform sunos on host remotehost3 is using the discovered Python
interpreter at /usr/bin/python3.9, but future installation of another Python
interpreter could change the meaning of that path. See
https://docs.ansible.com/ansible-
core/2.12/reference_appendices/interpreter_discovery.html for more information.
fatal: [remotehost3]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3.9"}, "changed": false, "module_stderr": "Shared connection to remotehost3 closed.\\r\\n", "module_stdout": "", "msg": "MODULE FAILURE\\nSee stdout/stderr for the exact error", "rc": 0}
[WARNING]: Platform linux on host remotehost2 is using the discovered Python
interpreter at /usr/local/bin/python3.9, but future installation of another
Python interpreter could change the meaning of that path. See
https://docs.ansible.com/ansible-
core/2.12/reference_appendices/interpreter_discovery.html for more information.
fatal: [remotehost2]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/local/bin/python3.9"}, "changed": false, "module_stderr": "Shared connection to remotehost2 closed.\\r\\n", "module_stdout": "", "msg": "MODULE FAILURE\\nSee stdout/stderr for the exact error", "rc": 0}
[WARNING]: Platform linux on host remotehost4 is using the discovered Python
interpreter at /usr/local/bin/python3.9, but future installation of another
Python interpreter could change the meaning of that path. See
https://docs.ansible.com/ansible-
core/2.12/reference_appendices/interpreter_discovery.html for more information.
fatal: [remotehost4]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/local/bin/python3.9"}, "changed": false, "module_stderr": "Shared connection to remotehost4 closed.\\r\\n", "module_stdout": "", "msg": "MODULE FAILURE\\nSee stdout/stderr for the exact error", "rc": 0}

TASK [Perform ping] ************************************************************
fatal: [remotehost1]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: Could not resolve hostname remotehost1: Name or service not known", "skip_reason": "Host remotehost1 is unreachable", "unreachable": true}

PLAY RECAP *********************************************************************
remotehost4                : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   
remotehost2                : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   
remotehost1            : ok=0    changed=0    unreachable=2    failed=0    skipped=2    rescued=0    ignored=0   
localhost                  : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
remotehost3               : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

您能否建议一个解决方案,让我可以通过

hosts: <groupnamme>
并且工作流程可以帮助列出所有无法访问的主机。

templates ansible runtime-error reusability connectivity
1个回答
0
投票

目的是在其他游戏中重用此模板/剧本来记录无法访问的服务器。

Ansible 已经有了

ignore_unreachable
关键字,可以自动跳过无法访问的主机并继续执行而不会失败。此外,Ansible 会在所有后续播放中自动跳过它们。无法访问的主机列表将显示在播放回顾中。

考虑以下最小的可重现示例:

# inventory.yaml
---
all:
  vars:
    ansible_python_interpreter: auto_silent
    ansible_connection: local
    printback_input: what is this? # this variable is in fact not used
  hosts:
    localhost:
      rec_group_names: source_node
source_node:
  hosts:
    remotehost1:
      ansible_connection: ssh
      ansible_host: example.com
    remotehost[2:4]:
# playbook.yaml
---
- name: Test with unreachable hosts
  gather_facts: false # you can gather facts as well, but this is faster is you don't need them
  hosts: all
  tasks:
    - name: Perform ping
      ping:

输出(为了简洁起见,我启用了 YAML 标准输出回调):

Alexanders-Mini:78050414 alexander$ ansible-playbook playbook.yaml -i inventory.yaml 

PLAY [Test with unreachable hosts 1] **********************************************************************************************************************************************************************

TASK [Perform ping 1] *************************************************************************************************************************************************************************************
ok: [remotehost2]
ok: [remotehost3]
ok: [remotehost4]
fatal: [remotehost1]: UNREACHABLE! => 
    changed: false
    msg: 'Failed to connect to the host via ssh: ssh: connect to host example.com port
        22: Operation timed out'
    unreachable: true

PLAY [Test with unreachable hosts 2] **********************************************************************************************************************************************************************

TASK [Perform ping 2] *************************************************************************************************************************************************************************************
ok: [remotehost3]
ok: [remotehost2]
ok: [remotehost4]

PLAY RECAP ************************************************************************************************************************************************************************************************
remotehost1                : ok=0    changed=0    unreachable=1    failed=0    skipped=0    rescued=0    ignored=0   
remotehost2                : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
remotehost3                : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
remotehost4                : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

现在,如果您仍然想在单独的 playbook 中将无法访问的主机列为变量,同时临时传递主机列表。实际上,在您当前的实现中存在三个错误阻止了这一点:

  1. 没有
    hostvars
    只是因为 Ansible 不知道应该在哪些主机上运行该游戏;
  2. 如果将其更改为普通变量,则只有直接通过
    --extra-vars
    ;
  3. 传递变量才会起作用
  4. 如果您没有在清单上定义任何主机(或根本没有任何清单),则只能在隐式
    localhost
    上运行此游戏。

所有这些都阻碍了剧本的可重用性。

因此,要解决所有问题,您需要将主机添加到同一剧本中的清单中,但在

localhost
上单独播放,并在
ping
主机上运行
all
(如果未定义该普通变量) 。顺便说一句,您不需要将它们添加两次,因此我正在检查它们是否已存在于库存中。我还添加了控制事实收集的能力:

# detect_and_list_unreachable_hosts.yaml
---
- name: Add the hosts to the inventory if they are missing
  hosts: localhost
  gather_facts: false
  tasks:
    - name: Add the list of hosts to the custom group
      add_host:
        name: "{{ item | trim }}"
        groups: "{{ target_group | default ('source_node') }}"
      loop: "{{ target_hosts.split(',') }}"
      when:
        - target_hosts is defined and target_hosts
        - groups['source_node'] is defined and item not in item not in groups['source_node'
          or item not in groups

- name: List the unreachable hosts
  hosts: "{{ test_hosts | default('all') }}"
  gather_facts: "{{ gather_facts_on_test_hosts | default('false') }}"
  tasks:
    - name: Ping the hosts
      ping:

    - name: Log the ping results
      debug:
        var: ansible_play_hosts_all | difference(ansible_play_hosts)

此剧本将在任何情况下工作:有或没有额外的变量,有或没有预定义清单,清单中有或没有本地主机,清单中有或没有目标主机。

您还可以添加

failed_when
条件,或者调用
assert
fail
模块来在有无法访问的主机时停止执行。

要将其与任何其他剧本一起使用,只需将其添加为第一个剧本即可:

# playbook.yaml
---
- name: Detect the unreachable hosts
  import_playbook: detect_and_list_unreachable_hosts.yaml

# subsequent plays go here

如果您不想使用额外的变量,您可以随时将

vars
添加到该导入中:

# playbook.yaml
---
- name: Detect the unreachable hosts
  import_playbook: detect_and_list_unreachable_hosts.yaml
  vars:
    target_hosts: "{{ some_other_hosts }}"
    # or simply hardcode:
    # target_hosts: remotehost5,remotehost6
© www.soinside.com 2019 - 2024. All rights reserved.