top of page

Ansible Service Module

Ansible service module allow us to control and manage services on remote server.

Mostly common use service task such as starting/stopping/disabling-enabling at start up/capturing service output etc....


So lets try to understand all of this tasks one by one by considering different scenario.


Scenario 1 : Start a service.

In this scenario we'll see how to start service on remote server.

[root@siddhesh ~]# cat service.yml
- hosts: dbserver
  tasks:
  - name: start redis service on remote server
    systemd:
      name: redis
      state: started
[root@siddhesh ~]#

Here :

- hosts: dbserver ==> Host Inventory Group On which this action needs to be performed. - name: start redis service on remote server ==> Task description

systemd: ==> Load systemd module to manage services on Centos7/Rhel7

name: redis ==> Name of service to perform action

state: started ==> type of action to perform. Started send signal to start a service.

So with the help of this playbook I want to start service called redis on remote server.

[root@siddhesh ~]# ansible-playbook service.yml -v
Using /etc/ansible/ansible.cfg as config file

PLAY [dbserver] *****************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************
ok: [node1.tecgeek.info]

TASK [start redis service on remote server] *************************************************************************************************************************
changed: [node1.tecgeek.info] => {"changed": true, "name": "redis", "state": "started", "status": {"ActiveEnterTimestamp": "Wed 2020-04-29 10:02:46 IST", "ActiveEnterTimestampMonotonic": "15570740", "ActiveExitTimestamp": "Tue 2020-05-05 16:56:20 IST", "ActiveExitTimestampMonotonic": "543230046229", "ActiveState": "inactive", "After": "network.target systemd-journald.socket basic.target system.slice", "AllowIsolate": "no", "AssertResult": "yes", "AssertTimestamp": "Wed 2020-04-29 10:02:46 IST", "AssertTimestampMonotonic": "15570242", "Before": "shutdown.target multi-user.target", "BlockIOAccounting": "no", "BlockIOWeight": "18446744073709551615", "CPUAccounting": "no", "CPUQuotaPerSecUSec": "infinity", "CPUSchedulingPolicy": "0", "CPUSchedulingPriority": "0", "CPUSchedulingResetOnFork": "no", "CPUShares": "18446744073709551615", "CanIsolate": "no", "CanReload": "no", "CanStart": "yes", "CanStop": "yes", "CapabilityBoundingSet": "18446744073709551615", "ConditionResult": "yes", "ConditionTimestamp": "Wed 2020-04-29 10:02:46 IST", "ConditionTimestampMonotonic": "15570242", "Conflicts": "shutdown.target", "ControlPID": "0", "DefaultDependencies": "yes", "Delegate": "no", "Description": "Redis persistent key-value database", "DevicePolicy": "auto", "DropInPaths": "/etc/systemd/system/redis.service.d/limit.conf", "ExecMainCode": "1", "ExecMainExitTimestamp": "Tue 2020-05-05 16:56:20 IST", "ExecMainExitTimestampMonotonic": "543230225122", "ExecMainPID": "1103", "ExecMainStartTimestamp": "Wed 2020-04-29 10:02:46 IST", "ExecMainStartTimestampMonotonic": "15570691", "ExecMainStatus": "0", "ExecStart": "{ path=/usr/bin/redis-server ; argv[]=/usr/bin/redis-server /etc/redis.conf --daemonize no ; ignore_errors=no ; start_time=[Wed 2020-04-29 10:02:46 IST] ; stop_time=[Tue 2020-05-05 16:56:20 IST] ; pid=1103 ; code=exited ; status=0 }", "ExecStop": "{ path=/usr/bin/redis-shutdown ; argv[]=/usr/bin/redis-shutdown ; ignore_errors=no ; start_time=[Tue 2020-05-05 16:56:20 IST] ; stop_time=[Tue 2020-05-05 16:56:20 IST] ; pid=17008 ; code=exited ; status=0 }", "FailureAction": "none", "FileDescriptorStoreMax": "0", "FragmentPath": "/usr/lib/systemd/system/redis.service", "Group": "redis", "GuessMainPID": "yes", "IOScheduling": "0", "Id": "redis.service", "IgnoreOnIsolate": "no", "IgnoreOnSnapshot": "no", "IgnoreSIGPIPE": "yes", "InactiveEnterTimestamp": "Tue 2020-05-05 16:56:20 IST", "InactiveEnterTimestampMonotonic": "543230226269", "InactiveExitTimestamp": "Wed 2020-04-29 10:02:46 IST", "InactiveExitTimestampMonotonic": "15570740", "JobTimeoutAction": "none", "JobTimeoutUSec": "0", "KillMode": "control-group", "KillSignal": "15", "LimitAS": "18446744073709551615", "LimitCORE": "18446744073709551615", "LimitCPU": "18446744073709551615", "LimitDATA": "18446744073709551615", "LimitFSIZE": "18446744073709551615", "LimitLOCKS": "18446744073709551615", "LimitMEMLOCK": "65536", "LimitMSGQUEUE": "819200", "LimitNICE": "0", "LimitNOFILE": "10240", "LimitNPROC": "3827", "LimitRSS": "18446744073709551615", "LimitRTPRIO": "0", "LimitRTTIME": "18446744073709551615", "LimitSIGPENDING": "3827", "LimitSTACK": "18446744073709551615", "LoadState": "loaded", "MainPID": "0", "MemoryAccounting": "no", "MemoryCurrent": "18446744073709551615", "MemoryLimit": "18446744073709551615", "MountFlags": "0", "Names": "redis.service", "NeedDaemonReload": "no", "Nice": "0", "NoNewPrivileges": "no", "NonBlocking": "no", "NotifyAccess": "none", "OOMScoreAdjust": "0", "OnFailureJobMode": "replace", "PermissionsStartOnly": "no", "PrivateDevices": "no", "PrivateNetwork": "no", "PrivateTmp": "no", "ProtectHome": "no", "ProtectSystem": "no", "RefuseManualStart": "no", "RefuseManualStop": "no", "RemainAfterExit": "no", "Requires": "basic.target", "Restart": "no", "RestartUSec": "100ms", "Result": "success", "RootDirectoryStartOnly": "no", "RuntimeDirectoryMode": "0755", "SameProcessGroup": "no", "SecureBits": "0", "SendSIGHUP": "no", "SendSIGKILL": "yes", "Slice": "system.slice", "StandardError": "inherit", "StandardInput": "null", "StandardOutput": "journal", "StartLimitAction": "none", "StartLimitBurst": "5", "StartLimitInterval": "10000000", "StartupBlockIOWeight": "18446744073709551615", "StartupCPUShares": "18446744073709551615", "StatusErrno": "0", "StopWhenUnneeded": "no", "SubState": "dead", "SyslogLevelPrefix": "yes", "SyslogPriority": "30", "SystemCallErrorNumber": "0", "TTYReset": "no", "TTYVHangup": "no", "TTYVTDisallocate": "no", "TimeoutStartUSec": "1min 30s", "TimeoutStopUSec": "1min 30s", "TimerSlackNSec": "50000", "Transient": "no", "Type": "simple", "UMask": "0022", "UnitFilePreset": "disabled", "UnitFileState": "enabled", "User": "redis", "WantedBy": "multi-user.target", "Wants": "system.slice", "WatchdogTimestampMonotonic": "0", "WatchdogUSec": "0"}}

PLAY RECAP **********************************************************************************************************************************************************
node1.tecgeek.info         : ok=2    changed=1    unreachable=0    failed=0
[root@siddhesh ~]#


Scenario 2 : Stop a service. In this scenario will cover a method to stop a service on remote server.

[root@siddhesh ~]# cat service.yml
- hosts: dbserver
  tasks:
  - name: stop redis service on remote server
    systemd:
      name: redis
      state: stopped
[root@siddhesh ~]#

Here :

- hosts: dbserver ==> Host Inventory Group On which this action needs to be performed. - name: start redis service on remote server ==> Task description

systemd: ==> Load systemd module to manage services on Centos7/Rhel7

name: redis ==> Name of service to perform action

state: stopped ==> type of action to perform. Stopped send signal to stop a service.

Output of playbook will similar like previous so I am not pasting it back again.

Scenario 3 : Managing multiple services using playbook

There might be a scenario when you need to perform a start/stop/restart actions on number of services at a same time after making any changes to its configuration or deploying any changes to its codebase. So in such case you can use with_items parameter to control multiple services in single task. So lets see how this can be handled more efficiently.

[root@siddhesh ~]# cat service.yml
- hosts: dbserver
  tasks:
  - name: restart multiple services on remote server.
    systemd:
      name: "{{ item }}"
      state: restarted
      daemon_reload: yes
    with_items:
      - 'redis'
      - 'slapd'
      - 'mariadb'
[root@siddhesh ~]#

Here : name: "{{ item }}" ==> Item loop execution. with_items: ==> statement to define list for loop execution.

[root@siddhesh ~]# ansible-playbook service.yml

PLAY [dbserver] *****************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************
ok: [node1.tecgeek.info]

TASK [restart multiple services on remote server.] ******************************************************************************************************************
changed: [node1.tecgeek.info] => (item=redis)
changed: [node1.tecgeek.info] => (item=slapd)
changed: [node1.tecgeek.info] => (item=mariadb)

PLAY RECAP **********************************************************************************************************************************************************
node1.tecgeek.info         : ok=2    changed=1    unreachable=0    failed=0
[root@siddhesh ~]# 

Scenario 4 : Start a service on boot.

After setting up any new application, One of important task is to enable newly installed service on boot so that if in case of server reboot all your service resources should come online without causing any delay.

[root@siddhesh ~]# cat service.yml
- hosts: dbserver
  tasks:
  - name: enable service on boot
    systemd:
      name: nginx
      enabled: true
[root@siddhesh ~]#

Here : enabled: true ==> Whether the service should start on boot. Lets run this playbook and verify this on remote server.

[root@siddhesh ~]# ansible-playbook service.yml

PLAY [dbserver] *****************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************
ok: [node1.tecgeek.info]

TASK [enable service on boot] ***************************************************************************************************************************************
changed: [node1.tecgeek.info]

PLAY RECAP **********************************************************************************************************************************************************
node1.tecgeek.info         : ok=2    changed=1    unreachable=0    failed=0
[root@siddhesh ~]#

Remote Server :

[root@node1 ~]# systemctl is-enabled nginx
enabled
[root@node1 ~]#

Scenario 5 : Capture service module output.

Sometime we need to know the exit/current status of the service after performing any one of the action like start/stop/restart. So in such scenario you can use register keywork to capture the output.

[root@siddhesh ~]# cat service.yml
- hosts: dbserver
  tasks:
  - name: enable service on boot
    systemd:
      name: nginx
      state: restarted
    register: sid_test
  - debug: var=sid_test
[root@siddhesh ~]#

Here :

register: sid_test ==> Register variable to store its debug output,Here I have used sid_test you can use any name here.

- debug: var=sid_test ==> Debug/Print an output of service state which was stored in previous task.

So lets run this playbook and see what additional information does it display on screen.

[root@siddhesh ~]# ansible-playbook service.yml

PLAY [dbserver] *****************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************
ok: [node1.tecgeek.info]

TASK [enable service on boot] ***************************************************************************************************************************************
changed: [node1.tecgeek.info]

TASK [debug] ********************************************************************************************************************************************************
ok: [node1.tecgeek.info] => {
    "sid_test": {
        "changed": true,
        "name": "nginx",
        "state": "started",
    }
}

PLAY RECAP **********************************************************************************************************************************************************
node1.tecgeek.info         : ok=3    changed=1    unreachable=0    failed=0
[root@siddhesh ~]#




bottom of page