Ansible:如果主机无法访问,则中止执行

Zor*_*_77 6 ansible ansible-playbook

摘要:如果任何主机无法访问,则立即中止ansible playbook的更好方法.

如果任何一个主机无法访问,有没有办法中止Ansible playbook.我发现,如果它无法到达主机,它仍将继续执行并执行剧本中的所有播放/任务.

我的所有剧本我指定max_fail_percentage为0,但在这种情况下,ansible不会抱怨,因为所有可访问的主机都可以执行所有播放.

目前我有一个简单而又hacky的解决方案,但看看是否有更好的答案.

我目前的解决方案

自从作为运行剧本的一部分的第一步,ansible收集所有主机的事实.如果主机无法访问,则无法访问.我在剧本的最开始写了一个简单的剧本,它将使用一个事实.如果主机无法访问,则任务将因"未定义的变量错误"而失败.任务只是一个虚拟任务,如果所有主机都可以访问,它将始终通过.

见下面我的例子:

- name: Check Ansible connectivity to all hosts
  hosts: host_all
  user: "{{ remote_user }}"
  sudo: "{{ sudo_required }}"
  sudo_user: root
  connection: ssh # or paramiko
  max_fail_percentage: 0
  tasks:
    - name: check connectivity to hosts (Dummy task)
      shell: echo " {{ hostvars[item]['ansible_hostname'] }}"
      with_items: groups['host_all']
      register: cmd_output

    - name: debug ...
      debug: var=cmd_output
Run Code Online (Sandbox Code Playgroud)

如果主机无法访问,您将收到如下错误:

TASK: [c.. ***************************************************** 
fatal: [172.22.191.160] => One or more undefined variables: 'dict object'    has no attribute 'ansible_hostname' 
fatal: [172.22.191.162] => One or more undefined variables: 'dict object' has no attribute 'ansible_hostname'

FATAL: all hosts have already failed -- aborting
Run Code Online (Sandbox Code Playgroud)

Jes*_*sak 1

您可以对检查更明确一些:

- fail: Abort if hosts are unreachable
  when: "'ansible_hostname' not in hostvars[item]"
  with_items: groups['all']
Run Code Online (Sandbox Code Playgroud)

我认为你可以制作一个回调插件来实现这一点。就像是:

class CallbackModule(object):
    def runner_on_unreachable(self, host, res):
        raise Exception("Aborting due to unreachable host " + host)
Run Code Online (Sandbox Code Playgroud)

除了我找不到任何好方法来从该回调中中止整个剧本(异常不起作用,返回值被忽略,虽然你可能会滥用self.playbook来阻止事情,但我看不到公共 API)。