How to make restarting httpd service idempotent in nature.

Mohd Sabir
4 min readFeb 17, 2021

--

In this article we gonna to discuss “ how to make restarting httpd service in idempotent “

What is Idempotent ?

An idempotent operation is one that can be applied multiple times without changing the result beyond the initial application.

Let’s configure the webserver using Ansible Playbook :-

- hosts: all
tasks:
- name: Install the webserver
package:
name: httpd
state: present
register: httpd_status
- name: Copy the content in document root
copy:
dest: /var/www/html/task.html
content: "It works."
when: httpd_status.failed == false

- name: Start the httpd service
service:
name: httpd
state: started
- name: Enable the httpd Service
service:
name: httpd
enabled: yes

When you run this playbook first time then the output will be like this

In above playbook I have write the module “package , copy & service” , these all module use by default the concept of idempotent. If I run this playbook again there will no change in playbook

Let’s run the playbook again and see the output :-

no change

Playbook run successfully but there is no change because which you want that is already available there , but we know If I want to change something in webserver config file then we have to restart the service , In our playbook the state of our service is “started” if I change something in config file that will change but my service will not be restart, Let’s check it ,

- hosts: all
tasks:
- name: Install the webserver
package:
name: httpd
state: present
register: httpd_status
- name: Copy the content in document root
copy:
dest: /var/www/html/task.html
content: "It works."
when: httpd_status.failed == false
- name: Change the port no of webserver
copy:
src: /root/ws_ansible/port.conf
dest: /etc/httpd/conf.d/
- name: Start the httpd service
service:
name: httpd
state: started
- name: Enable the httpd Service
service:
name: httpd
enabled: yes

here I want to change the port number of my webserver , by default webserver works on port no 80 I want my webserver work on port 81 , So there is two option to change port , One is you can go to httpd conf file and change but it is not good to change the config file directly , Another way is create one another file with the extension .conf and copy this in a folder /etc/httpd/conf.d/

# create conf file in your workspace
vim port.conf
Listen 81

Save this file and run the playbook

ansible-playbook webserver.yml

Now the output will be like this

Playbook run successfully port no change but service not restarted , my webserver will not work on port no 81 , So here we have to write task for restarted the service.

- hosts: all
tasks:
- name: Install the webserver
package:
name: httpd
state: present
register: httpd_status
- name: Copy the content in document root
copy:
dest: /var/www/html/task.html
content: "It works."
when: httpd_status.failed == false
- name: Change the port no of webserver
copy:
src: /root/ws_ansible/port.conf
dest: /etc/httpd/conf.d/
- name: Start the httpd service
service:
name: httpd
state: started
- name: Enable the httpd Service
service:
name: httpd
enabled: yes
- name: Restart the service
service:
name: httpd
state: restarted

Save it and run the playbook

ansible-playbook webserver.yml 
service restart

Playbook run successfully , service restart now my webserver works on port no 81 , but here we have a challenge that restart service is idempotent , As I run my playbook , httpd service will restart everytime but this is not good , it will impact on server performance, to overcome this problem we can use handlers , handlers run if something change, not everytime

- hosts: all
tasks:
- name: Install the webserver
package:
name: httpd
state: present
register: httpd_status
- name: Copy the content in document root
copy:
dest: /var/www/html/task.html
content: "It works."
when: httpd_status.failed == false
- name: Change the port no of webserver
copy:
src: /root/ws_ansible/port.conf
dest: /etc/httpd/conf.d/
notify:
- Restart service
- name: Start the httpd service
service:
name: httpd
state: started
- name: Enable the httpd Service
service:
name: httpd
enabled: yes
handlers:
- name: Restart service
service:
name: httpd
state: restarted

Now if you run the playbook , if you change something in your conf then only service will restart , other it will not restart.

I already change the port no of webserver , here now I am not changing anything in my conf file so service not restart now.

Let’s run the playbook :-

Now our restart service is idempotent in nature.
Thanks for reading..

--

--

Mohd Sabir
Mohd Sabir

Written by Mohd Sabir

DevOps Enthusiastic || Kubernetes || GCP || Terraform || Jenkins || Scripting || Linux ,, Don’t hesitate to contact on : https://www.linkedin.com/in/mohdsabir

No responses yet