【问题标题】:Ansible Playbook: How to write unreachable inventory host names to a fileAnsible Playbook:如何将无法访问的清单主机名写入文件
【发布时间】:2019-09-19 23:31:16
【问题描述】:

我正在为清单主机列表编写剧本:-

如果主机可访问,则将“connection=1”写入文件。如果主机不可达,写入同一个文件“connection=0”

据我了解,Ansible 不会以可访问的方式存储无法访问的热点信息(当 ssh 失败时)。

你能帮我吗? 我的剧本粘贴在下面。 由于主机不可达,shell任务根本没有执行

下面是我的剧本

- hosts: '{{ host }}'
  gather_facts: False
  vars:
    dest: /tmp/trace
  tasks:
    - copy:
        content: ''
        dest: "{{ dest }}"
      run_once: yes
      delegate_to: 127.0.0.1
    - shell: ping {{ inventory_hostname }}  -c 1
      register: ping_status
      ignore_errors:  yes
    - setup:
       filter: ansible_*
    - lineinfile:
        dest: "{{ dest }}"
        line: 'Host:{{ inventory_hostname }},OS:{{ ansible_distribution }},Kernel:{{ansible_kernel}},OSVersion:{{ansible_distribution_version}},FreeMemory:{{ansible_memfree_mb}},connection:{{ping_status.rc}}'
      ignore_errors: true
      delegate_to: 127.0.0.1

【问题讨论】:

  • 不可能没有。主机无法访问的原因。首先上面的用例是什么?

标签: ansible


【解决方案1】:

您的剧本存在一些问题。首先是您尝试在远程主机上同时执行shellsetup 任务,如果该主机不可用,这当然不会工作。

在远程主机上运行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 }}"

您正在尝试针对您的远程主机运行 setup 模块,但这仅在远程主机可用时才有意义,因此我们需要以 ping 任务的结果为条件:

- setup:
    filter: "ansible_*"
  when: ping.rc == 0

有了这些,我们就可以生成一个文件,其中包含有关每个主机的可用性信息。我在这里使用lineinfile,因为这就是您在示例中使用的,但如果我自己写这个,我可能会使用template 任务:

- 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 <condition> %}...{% 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 }}"

【讨论】:

  • 很高兴为您提供帮助!如果此答案有帮助,请考虑选中答案左侧的复选标记以将其标记为“已接受”。
【解决方案2】:

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

基本上,如果设置模块失败,很可能是因为服务器无法访问。在这种情况下,甚至我使用的“始终”块都不会捕获此错误,因为失败/无法访问的主机不被视为“活动”(https://docs.ansible.com/ansible/latest/reference_appendices/special_variables.html)。

但是,我用来获取无法访问的主机的方法是循环 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

【讨论】:

    猜你喜欢
    • 2020-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-27
    • 1970-01-01
    • 2018-06-07
    • 2021-01-17
    • 1970-01-01
    相关资源
    最近更新 更多