ANSIBLE – IN AND OUT | Handlers | PART 10

This is in continuation to the articles of Ansible. In the previous article, we have seen how we can set up the local NTP configuration file and how we can deploy it to the servers to get the benefit of setting up the configuration at one place and not doing this again and again in case we have 100s of servers.

But If we look closely at the playbook that we wrote we can see that if we again run the same playbook then the NTP service will again get restarted, and this should not happen as we have already deployed the NTP config file and if we have not done any change in that config then the NTP service should not get restarted.

So, we should devise a way such that NTP service will only get restarted if we have made some change in NTP configuration files. To resolve this, we can make use of handlers in Ansible. Thus, in this article we will be covering Handlers in Ansible.

Handlers

Handlers are just like regular tasks in an Ansible playbook (see Tasks) but are only run if the Task contains a “notify” directive and also indicates that it changed something. For example, if a config file is changed then the task referencing the config file templating operation may notify a service restart handler.

Handlers are the same as tasks, but they get executed only when they are notified but tasks get executed every time we run the playbook. Handlers should be in the same line as that of tasks inside the playbook.

So below is the updated version of the playbook that we wrote in the previous article

---                                                                                                                                                                                                                   
                                                                                                                                                                                                                      
- name: Deploying NTP Service                                                                                                                                                                                         
  hosts: all                                                                                                                                                                                                          
  become: yes                                                                                                                                                                                                         
  tasks:                                                                                                                                                                                                              
          - name: Install packages on RedHat OS                                                                                                                                                                       
            yum:                                                                                                                                                                                                      
              name: "{{item}}"                                                                                                                                                                                        
              state: present                                                                                                                                                                                          
            loop:                                                                                                                                                                                                     
              - ntp                                                                                                                                                                                                   
              - unzip                                                                                                                                                                                                 
              - git                                                                                                                                                                                                   
              - wget                                                                                                                                                                                                  
              - zip                                                                                                                                                                                                   
            when: ansible_os_family == "RedHat"                                                                                                                                                                       
                                                                                                                                                                                                                      
          - name: Install packages on Debian OS                                                                                                                                                                       
            apt:                                                                                                                                                                                                      
              name: "{{item}}"                                                                                                                                                                                        
              state: present                                                                                                                                                                                          
            loop:                                                                                                                                                                                                     
              - ntp                                                                                                                                                                                                   
              - unzip                                                                                                                                                                                                 
              - git                                                                                                                                                                                                   
              - wget                                                                                                                                                                                                  
              - zip                                                                                                                                                                                                   
            when: ansible_os_family == "Debian"                                                                                                                                                                       
                                                                                                                                                                                                                      
          - name: Start and Enable NTP service in RedHat OS                                                                                                                                                           
            service:                                                                                                                                                                                                  
              name: ntpd                                                                                                                                                                                              
              state: started                                                                                                                                                                                          
              enabled: yes                                                                                                                                                                                            
            when: ansible_os_family == "RedHat"                                                                                                                                                                       
                                                                                                                                                                                                                      
          - name: Start and Enable NTP service in Debian OS                                                                                                                                                           
            service:                                                                                                                                                                                                  
              name: ntp                                                                                                                                                                                               
              state: started                                                                                                                                                                                          
              enabled: yes                                                                                                                                                                                            
            when: ansible_os_family == "Debian"                                                                                                                                                                       
                                                                                                                                                                                                                      
          - name: Deploy the NTP configuration file for Debian OS                                                                                                                                                     
            copy:                                                                                                                                                                                                     
              src: files/ntp_debian.conf                                                                                                                                                                              
              dest: /etc/ntp.conf                                                                                                                                                                                     
              backup: yes                                                                                                                                                                                             
            when: ansible_os_family == "Debian"                                                                                                                                                                       
            notify:                                                                                                                                                                                                   
                - Restart NTP service in Debian OS                                                                                                                                                                    
                                                                                                                                                                                                                      
          - name: Deploy the NTP configuration file for RedHat OS                                                                                                                                                     
            copy:                                                                                                                                                                                                     
              src: files/ntp_redhat.conf                                                                                                                                                                              
              dest: /etc/ntp.conf                                                                                                                                                                                     
              backup: yes                                                                                                                                                                                             
            when: ansible_os_family == "RedHat"                                                                                                                                                                       
            notify:                                                                                                                                                                                                   
                - Restart NTP service in RedHat OS                                                                                                                                                                    
                                                                                                                                                                                                                      
  handlers:                                                                                                                                                                                                           
          - name: Restart NTP service in RedHat OS                                                                                                                                                                    
            service:                                                                                                                                                                                                  
              name: ntpd                                                                                                                                                                                              
              state: restarted                                                                                                                                                                                        
            when: ansible_os_family == "RedHat"                                                                                                                                                                       
                                                                                                                                                                                                                      
          - name: Restart NTP service in Debian OS                                                                                                                                                                    
            service:                                                                                                                                                                                                  
              name: ntp                                                                                                                                                                                               
              state: restarted                                                                                                                                                                                        
            when: ansible_os_family == "Debian"  
 

We can syntax check our playbook with the below command.

ansible-playbook ntp_playbook.yml --syntax-check

Let’s run the playbook

Here we can see that as we have not changed anything inside the RedHat and Debian NTP configuration files, our handlers didn’t execute.

Now let’s try to add some dummy values inside the RedHat(ntp_redhat.conf) configuration files and see if our handlers get executed or not.

Now ansible knows that the source NTP configuration files and the destination NTP configuration files are different so will execute the tasks and will notify the handlers. 

We can clearly see that handlers get executed for the redhat OS and not for debian system.

Handlers are lists of tasks, not really any different from regular tasks, that are referenced by a globally unique name, and are notified by notifiers. If nothing notifies a handler, it will not run. Regardless of how many tasks notify a handler, it will run only once, after all of the tasks complete in a particular play. 

IMPORTANT NOTE 

Handlers gets executed in the end of the playbook, so if you want to execute some task immediately as soon as the configuration gets changes then handlers won’t help and that can be handled via Conditions.

About the author

Deepak Sood

Deepak Sood is Lead Consultant in an IT firm holding expertise in Devops and QA Architecture with 8 years of experience.

His expertise is in building highly scalable frameworks. His skills include Java, Configuration Management, Containers, and Kubernetes.

Reach out to him using contact form.

View all posts