Restarting HTTPD Service is not
idempotence in nature and also consume more resources suggest a way to rectify this challenge in Ansible playbook.
Think about the “Pay now” button the last time you bought something online. Now, let’s say you’re ready to purchase your shopping cart items, so you press “Pay now”. What happens if you press it multiple times? Will your credit card be charged for each time you hit the button?
This is where idempotence comes in: if the function in the “Pay now” button is idempotent, the user can tap the “Pay Now” button many times — yet their card is charged only once and they only make one purchase on their cart’s contents.
idempotence is the design standard for Ansible, a DevOps tool for system administrators to manage their servers. Ansible can automate the server setup process, consistently create the same servers, and automatically deploy them. There is a lot of orchestration that occurs in automating this process — and it is idempotent behaviors that ensure only one directory gets created on a server, and only an exact number of servers get created.
Now coming to main topic: Restarting HTTPD Service is not idempotence in nature and also consume more resources suggest a way to rectify this challenge in Ansible playbook.
I have a server publicly accessible through http://65.1.84.113/ which is listening by default at 80 port number. I open the test.html page at the server.

I want that server listen at port number 4444.To do this there is need to change the configuration of HTTPD program and for reflecting changes it is necessary to restart the HTTPD service.
Playbook:
- hosts: all
vars:
- port: "4444"
tasks:
- name: Copying conf file
template:
dest: "/etc/httpd/conf.d/myhttpd.conf"
src: "myhttpd.j2"
- service:
name: "httpd"
state: restarted
enabled: yes
Running playbook:

Update inbound rules:

output:

Running the same playbook:

On running the same playbook the HTTPD service restarts. According to idempotence if there is no change in the configuration then HTTPD service should not restart which states that restarting HTTPD service is not idempotence in nature.
Rectifying:
Playbook
- hosts: all
vars:
- port: "5555"
tasks:
- name: Copying conf file
template:
dest: "/etc/httpd/conf.d/myhttpd.conf"
src: "myhttpd.j2"
notify:
- changed
handlers:
- name: changed
service:
name: "httpd"
state: restarted
enabled: yes
again update inbound rules and run playbook:

Output:

Running same playbook again

This time the HTTPD service did not restart hence we have rectified the idempotence problem.
The playbook which rectified the idempotence problem uses the concept of handlers and notify.
I showed the demo using the AWS cloud ec2-instances. For local VM the playbook will be as follows:
- hosts: all
vars:
- port: "5555"
tasks:
- name: Copying conf file
template:
dest: "/etc/httpd/conf.d/myhttpd.conf"
src: "myhttpd.j2"
notify:
- changed
- name: Adding rule for http
firewalld:
port: "{{ port }}/tcp"
state: enabled
permanent: yes
immediate: yes
handlers:
- name: changed
service:
name: "httpd"
state: restarted
enabled: yes
Conclusion: The handler and notify can be more useful when it comes to avoid the execution of unnecessary tasks.