Ansible Playbook:如何将无法访问的资源清册主机名写入文件

Ansible Playbook:如何将无法访问的资源清册主机名写入文件,ansible,Ansible,我正在写一本关于以下内容的清单主机的剧本:- 如果可以访问主机,则将“connection=1”写入文件。如果无法访问主机,请写入同一文件“connection=0” 据我所知,Ansible不以可访问的方式存储无法访问的HOT的信息(当ssh失败时) 你能帮我吗? 我的剧本贴在下面。 由于无法访问主机,因此根本不执行shell任务 下面是我的剧本 你的剧本有一些问题。首先,您试图在远程主机上执行shell和setup任务,如果该主机不可用,这当然不起作用 在远程主机上运行ping任务甚至没有意

我正在写一本关于以下内容的清单主机的剧本:-

如果可以访问主机,则将“connection=1”写入文件。如果无法访问主机,请写入同一文件“connection=0”

据我所知,Ansible不以可访问的方式存储无法访问的HOT的信息(当ssh失败时)

你能帮我吗? 我的剧本贴在下面。 由于无法访问主机,因此根本不执行shell任务

下面是我的剧本
你的剧本有一些问题。首先,您试图在远程主机上执行
shell
setup
任务,如果该主机不可用,这当然不起作用

在远程主机上运行
ping
任务甚至没有意义:您希望使用委派在本地主机上运行该任务。我们可以这样做,将每个主机的可用性记录为主机变量:

---
- hosts: all
  gather_facts: false
  tasks:
    - delegate_to: localhost
      command: ping -c1 "{{ hostvars[inventory_hostname].ansible_host|default(inventory_hostname) }}"
      register: ping
      ignore_errors: true

    - set_fact:
        available: "{{ ping.rc == 0 }}"
您正试图针对远程主机运行
设置
模块,但这只有在远程主机可用时才有意义,因此我们需要根据
ping
任务的结果来设置:

- setup:
    filter: "ansible_*"
  when: ping.rc == 0
- hosts: localhost
  gather_facts: false
  tasks:
    - lineinfile:
        dest: ./available.txt
        line: "Host: {{ item }}, connection={{ hostvars[item].available }}"
        regexp: "Host: {{ item }}"
        create: true
      loop: "{{ groups.all }}"
有了它,我们就可以生成一个包含每个主机可用性信息的文件。我在这里使用的是
lineinfle
,因为这是您在示例中使用的,但如果我自己写这篇文章,我可能会使用
模板
任务:

- setup:
    filter: "ansible_*"
  when: ping.rc == 0
- hosts: localhost
  gather_facts: false
  tasks:
    - lineinfile:
        dest: ./available.txt
        line: "Host: {{ item }}, connection={{ hostvars[item].available }}"
        regexp: "Host: {{ item }}"
        create: true
      loop: "{{ groups.all }}"
当然,在您的示例中,您试图包括关于主机的各种其他事实:

        line: 'Host:{{ inventory_hostname }},OS:{{ ansible_distribution }},Kernel:{{ansible_kernel}},OSVersion:{{ansible_distribution_version}},FreeMemory:{{ansible_memfree_mb}},connection:{{ping_status.rc}}'
如果目标主机不可用,这些事实将不可用,因此您需要使用
{%if%}…{%endif%}
构造将所有这些条件化:

line: "Host:{{ item }},connection:{{ hostvars[item].available }}{% if hostvars[item].available %},OS:{{ hostvars[item].ansible_distribution }},Kernel:{{ hostvars[item].ansible_kernel }},OSVersion:{{ hostvars[item].ansible_distribution_version }},FreeMemory:{{ hostvars[item].ansible_memfree_mb }}{% endif %}"
这使最终剧本看起来像这样:

---
- hosts: all
  gather_facts: false
  tasks:
    - delegate_to: localhost
      command: ping -c1 "{{ hostvars[inventory_hostname].ansible_host|default(inventory_hostname) }}"
      register: ping
      ignore_errors: true

    - set_fact:
        available: "{{ ping.rc == 0 }}"

    - setup:
      when: ping.rc == 0

- hosts: localhost
  gather_facts: false
  tasks:
    - lineinfile:
        dest: ./available.txt
        line: "Host:{{ item }},connection:{{ hostvars[item].available }}{% if hostvars[item].available %},OS:{{ hostvars[item].ansible_distribution }},Kernel:{{ hostvars[item].ansible_kernel }},OSVersion:{{ hostvars[item].ansible_distribution_version }},FreeMemory:{{ hostvars[item].ansible_memfree_mb }}{% endif %}"
        regexp: "Host: {{ item }}"
        create: true
      loop: "{{ groups.all }}"

无法访问的主机可以访问。您可以从魔术变量间接获得它们

基本上,如果安装模块失败,很可能是因为无法访问服务器。在这种情况下,即使是我使用的“始终”块也不会捕获此错误,因为失败/无法访问的主机不被视为“活动”()

但是,获取不可访问主机的方法是循环groups['all']魔术变量。此变量包含播放的所有主机,无论它们是否可访问

因此,主要思想是为所有主机编写变量(分布、内核等),如果没有定义这些变量,则是因为安装任务失败。您可以利用这一点,使用default()过滤器将值默认为您想要的任何值(在本例中,我使用“NA”,最后一个变量使用“unreachable”)

请让我知道你对这件事的看法

- hosts: all
  gather_facts: False
  vars:
    dest: /tmp/trace
  tasks:
  - block:
    - copy:
        content: ''
        dest: "{{ dest }}"
      run_once: yes
      delegate_to: 127.0.0.1
    - setup:
       filter: ansible_*
    - set_fact: connection_status="reachable"
    always:
    - lineinfile:
        dest: "{{ dest }}"
        line: 'Host:{{ item }},OS:{{ hostvars[item][ansible_distribution] | default('NA') }},Kernel:{{ hostvars[item][ansible_kernel] | default('NA') }},OSVersion:{{ hostvars[item][ansible_distribution_version] | default('NA') }},FreeMemory:{{ hostvars[item][ansible_memfree_mb] | default('NA') }},connection:{{ hostvars[item][connection_status] | default('unreachable') }}'
      loop: "{{ groups['all'] }}"
      run_once: true
      delegate_to: 127.0.0.1

无法访问主机的原因可能很多。首先,上面的用例是什么?很高兴提供帮助!如果这个答案是有用的,考虑检查答案左边的复选标记,将其标记为“被接受”。谢谢分享好答案++ve。