我在一个库存主机列表上写了一本剧本: -
如果主机可访问,则写入“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
你的剧本有一些问题。第一个是您尝试在远程主机上执行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 }}"
您正在尝试针对远程主机运行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 }}"