SiliconMind
SiliconMind

Reputation: 2179

How to run command after error occurs in ansible handler

I have a simple playbook that copies some config files for nginx server and then issues service nginx reload command:

---
- hosts: mirrors
  tasks:
    - name: Installs nginx web server
      apt: pkg=nginx state=installed update_cache=true
      notify:
        - start nginx

    - name: Copy vhost file
      copy: src=vhost/test.vhost dest=/etc/nginx/sites-available/ mode=0644

    - name: Symlink vhost file to enabled sites
      file: src=/etc/nginx/sites-available/test.vhost dest=/etc/nginx/sites-enabled/test.vhost state=link
      notify:
        - reload nginx

  handlers:
    - name: start nginx
      service: name=nginx state=started

    - name: reload nginx
      service: name=nginx state=reloaded

Now, the problem is that it might happen that the test.host file contains an error and nginx won't reload properly. If it happens, I'd like to run a command systemctl status nginx.service and see it's output when ansible playbook executes. How can I add this "error handler"?

Upvotes: 2

Views: 5321

Answers (2)

Valeriy Solovyov
Valeriy Solovyov

Reputation: 5648

Why don't use Ansible modules ability to validate configuration?:

For example:

- template: src=/mine/sudoers dest=/etc/sudoers validate='visudo -cf %s'

- lineinfile: dest=/etc/sudoers state=present regexp='^%ADMIN ALL\=' line='%ADMIN ALL=(ALL) NOPASSWD:ALL' validate='visudo -cf %s'

- replace: dest=/etc/apache/ports regexp='^(NameVirtualHost|Listen)\s+80\s*$' replace='\1 127.0.0.1:8080' validate='/usr/sbin/apache2ctl -f %s -t'

Upvotes: 0

nikobelia
nikobelia

Reputation: 4887

If the handler output tells you about the failure, you can put together a nice bit of error handling with the ignore_errors and register keywords.

Set your handler not to end to fail and end the play when it gets an error code back, but to register the output as a variable:

handlers:
  - name: reload nginx
    service: name=nginx state=reloaded
    ignore_errors: True
    register: nginx_reloaded

Then back in the tasks section, call flush_handlers to execute all the queued handlers that would otherwise wait until the end of the play. Add a task in to go and ask the server about the status of Nginx when your nginx_reloaded variable has a non-zero return code, and then print the information from that with the debug module:

- name: Symlink vhost file to enabled sites
  file: src=/etc/nginx/sites-available/test.vhost dest=/etc/nginx/sites-enabled/test.vhost state=link
  notify:
    - reload nginx

- meta: flush_handlers

- name: Get the Nginx service status if it failed to failed.
  command: "systemctl status nginx.service"
  register: nginx_status
  when: nginx_reloaded.rc != 0

- debug: var=nginx_status
  when: nginx_reloaded.rc != 0

Of course, a better solution would be to fix those errors in your configuration files - and figuring them out through Ansible output has limitations compared to SSHing onto the target host to check it out.

Upvotes: 2

Related Questions