首页 文章

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

提问于
浏览
5

摘要:如果任何主机无法访问,则立即中止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

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

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

3 回答

  • 1

    你可以对这个检查更明确一些:

    - fail: Abort if hosts are unreachable
      when: "'ansible_hostname' not in hostvars[item]"
      with_items: groups['all']
    

    我以为你可以做一个callback plugin来实现这个目标 . 就像是:

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

    除非我能够工作,否则返回值会被忽略,虽然您可能会滥用 self.playbook 来阻止事情,但我没有看到公共API .

  • 1

    您可以将 any_errors_fatal: true or max_fail_percentage: 0gather_facts: false 组合,然后运行在主机脱机时将失败的任务 . 在剧本顶部的这样的东西应该做你需要的:

    - hosts: all
      gather_facts: false
      max_fail_percentage: 0
      tasks:
        - action: ping
    

    奖励是,这也适用于限制匹配主机的 -l SUBSET 选项 .

  • 1

    我发现一种方法可以在gather_facts完成后立即使用回调来中止播放 .

    通过将_play_hosts设置为空集,没有主机可以继续播放 .

    class CallbackModule(object):
    
        def runner_on_unreachable(self, host, res):
            # Truncate the play_hosts to an empty set to fail quickly
            self.play._play_hosts = []
    

    结果如下:

    PLAY [test] *******************************************************************
    
    GATHERING FACTS ***************************************************************
    fatal: [haderp] => SSH Error: ssh: Could not resolve hostname haderp: nodename nor servname provided, or not known
    It is sometimes useful to re-run the command using -vvvv, which prints SSH debug output to help diagnose the issue.
    ok: [derp]
    
    TASK: [set a fact] ************************************************************
    FATAL: no hosts matched or all hosts have already failed -- aborting
    
    
    PLAY RECAP ********************************************************************
           to retry, use: --limit @/Users/jkeating/foo.yaml.retry
    
    derp                       : ok=1    changed=0    unreachable=0    failed=0
    haderp                     : ok=0    changed=0    unreachable=1    failed=0
    

相关问题