In this tutorial we will learn how create a service file to run a script as a service using systemd, and write an ansible role to automate the process.
Hint This tutorial assumes you are familiar with ansible.
Systemd Introduction and Service files
Here we will introduce you only to the very basics of systemd, to learn more about systemd follow the lnks bellow.
Systemd is a suite of basic building blocks for a Linux system, it runs as PID 1 and is used to bootstrap all other services after boot and manage the life cycle of Linux services.
Systemd services files can be found in one of these two locations
/etc/systemd/system where the second location takes precedence over the first one.
You can override a systemd service file by creating a directory called after the service
name and ends with
.d e.g: if a service is called
test.service the directory
must be called
test.service.d, inside this directory we put files that end with
and contain options that override the same options defined in the service file.
The basic structure of a service file is as follows:
[Unit] Description=A test unit [Service] ExecStart=/usr/local/bin/test Type=simple StandardOutput=syslog StandardError=syslog SyslogIdentifier=test
The previous file in an INI file and contains the very basic structure of a systemd unit file.
The first section
[Unit] defines general information about the systemd unit.
Description option describes the unit in general using few words.
[Service] section defines the service it self and is very important for the
ExecStart defines the absolute path to the binary ised to run the service.
Type defines the type of the service, here we care about only two types,
which means that the script’s execution binary will run in foreground, the other type
forking which means the script’s execution binary will fork in background and
probably write the PID of the child process to a file that must be identified using
PIDFile option to enable systemd to control the service.
StandardError defines where to send the program’s standard output
and error here it is sent to
SyslogIdentifier is used to identify the service in syslog files, this will
be used later to direct output to a separate file for the service.
When this file is saved as
/etc/systemd/system and started using
sudo systemctl start test.service the script found at
is executed as a background process and can be stopped using
sudo systemctl stop test.service,
we can query its status using
sudo systemctl status test.service.
Send syslog output to a separate file
In the previous section we sent the output of our service to
syslog which writes to
a the log file
/var/log/syslog and writes the value of
SyslogIdentifier to the log
line to identify that this output line came from this service.
We can tell syslog daemon to send the output from this service to a different file
by creating a new file called
test.conf in this directory
and put the following line in it.
if $programname == 'test' then /var/log/test.log
Here the programname
test is taken from
SyslogIdentifier which is defined in the
Restart syslog for changes to take effect
sudo systemctl restart syslog
Now the ouyput of the service called
test is redirected to
Use an ansible role to automate the previous tasks
Now we will use ansible to create a role that creates some service files, starts them and possibly send their output to different files using syslog.
We will use variables to define the services we want to create and the files we want to redirect logs to them.
Here is a sample ansible playbook to install the previous service on a server, setup syslog for it and start it.
--- - hosts: server1 become: true gather_facts: true vars: - systemd_services: - src: test dst: /usr/local/bin/test name: test upload: true type: simple description: test service log_file: /var/log/test.log started: True - dst: /usr/local/bin/dst name: dst type: forking pid_file: /var/run/dst.pid roles: - moshensy.systemd_service
In the previous playbook we are deploying the test service to a server called
We used the
systemd_services variable, which is an array of dictionaries and each
one defines a service, the service has the following options
src defines the location of the program file on the machine which is running ansible.
dst defines where the program will be saved on the server.
upload is a boolean variable which specifies if the file will be uploaded to the server.
name defines the name of the service.
type defines the service’s type either
forking, if the type of the
forking you must define the
pid_file option to tell systemd about
the file that will contain the PID of the child process to monitor.
description defines the service’s description.
log_file defines the log file to be used for sending standard output and error to it.
started is a boolean which specifies if the service must be started or not.
In this tutorial we learned how to create a service file in systemd, send its output to syslog and then use syslog to send each service’s output to a different file.
Finally we learned how to use an ansible role to automate all of the previous tasks.
I hope you enjoyed it, any feedback will be highly appreciated you can use the comment section below or the ChatBot or email me directly at email@example.com.