Ansible Service Module: Manage Services
The service module in Ansible comes in handy for managing services across a variety of platforms.
The service module in Ansible provides an easy way to manage system services across different environments. It interacts with the service management tools available on the target system.
These tools are usually different, for example, Linux/Unix init systems such as systemd, BSD init, launchd on macOS, Solaris SMF, and upstart.
However, the service module abstracts the differences between various service management tools, thus providing a unified way to manage services.
Service module parameters
The service module has several different parameters, the most common of which are:
- name: the name of the service
- enabled: defined if the service must start when the machine boots
- pattern: if the status command does not work, this parameter allows you to define whether a service is operational or not
- sleep: during the action
restarted
defines the tempo betweenstop
andstart
- state: action on the service:
started
,stopped
,restarted
orreloaded
(in case of modification to a configuration file)
Service module use cases
Service module can be used to run, stop, restart, or reload services as required, helping to automate and standardize the management of your infrastructure. Following is a simple playbook for starting nginx:
---
- name: Manage Nginx service
hosts: webservers
tasks:
- name: Ensure Nginx is running and enabled at boot
ansible.builtin.service:
name: nginx
state: started
enabled: yes
Similarly, by changing the state parameter, you can stop and restart services. However, use of the service module is not limited to starting and stopping services. Following is an example playbook for installing and configuring nginx (simplified):
---
- name: manage services
hosts: all
become: true
tasks:
- name: Installing nginx
package:
- name:
- nginx
- name: nginx configuration
template:
src:nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner:root
group:root
mode: 0644
- name: Reloading the conf
service:
name: nginx
state: reloaded
- name: Verification nginx is started
service:
name: nginx
state:started
enabled: true
This is a simple example to use the service module but it has certain limitations. One such limit is that our playbook will always reload the nginx service, even if the configuration has not changed. One way to avoid this is to use handlers.
Using handlers to refine Service
Handlers allow you to launch an action if a task has made a modification to the system (status changed). Ansible allows you to trigger events after a task has passed handlers status. Additionally, although multiple tasks may require the same action, the action in question will only be launched after all task blocks have been executed.
Our playbook, therefore becomes:
---
- name: manage services
hosts: all
become: true
tasks:
- name: nginx configuration
template:
src:nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner:root
group:root
mode: 0644
notify:
- reload nginx
- name: Verification nginx is started
service:
name: nginx
state:started
enabled: true
handlers:
- name: reload nginx
service:
name: nginx
state: reloaded
As with the package module, there are modules specific to each type of initialization system that have more options: systemd and sysvinit.
Get information about a service: service_facts
Ansible provides a module service_facts
allowing you to obtain lots of information about a service.
This module does not take any parameters. On the other hand, it requires that gather_facts
are not disabled.
For example, I would like to open ports 80 and 443 only if the firewall service is active. Our playbook becomes:
---
- name: manage services
hosts: all
become: true
tasks:
- name: nginx configuration
template:
src:nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner:root
group:root
mode: 0644
notify:
- reload nginx
- name: Gets information about a service
service_facts:
- name:debug
debug:
var: ansible_facts.services["firewalld.service"]
handlers:
- name: reload nginx
service:
name: nginx
state: reloaded
Services is added to the variable ansible_facts
and contains the list of all services installed on the machine. So if you want to access the firewalld service, you will have to indicate ansible_facts.services["firewalld.service"]
.
TASK [debug] *********************************************************************************************
ok: [host1] => {
"firewalld.service":
{ "name": "firewalld.service",
"source": "systemd",
"state": "running",
"status": "enabled"
}
}
For example, I could add a task which is only launched if the firewalld service is in its status enabled
:
---
- name: manage services
hosts: all
become: true
tasks:
- name: nginx configuration
template:
src:nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner:root
group:root
mode: 0644
notify:
- reload nginx
- name: Gets information about a service
service_facts:
- name: authorizes the https flow
ansible.posix.firewalld:
service: https
permanent: yes
state:enabled
when: ansible_facts.services["firewalld.service"].status == "enabled"
handlers:
- name: reload nginx
service:
name: nginx
state: reloaded
Final Words
The service module in Ansible is a powerful tool for managing system services, when used with other modules it provides a high level of control and automation while ensuring consistency across different environments.
If you are new to Ansible and want to learn it from scratch, our Ansible tutorial series will be of great help. It's written for RHCE exam but it helps you the same whether you are preparing for the exam or not.
LHB Community is made of readers like you who share their expertise by writing helpful tutorials. Contact us if you would like to contribute.