Automating ServiceNow with Red Hat Ansible Automation Platform
Sysadmins are asked regularly to quickly complete service requests to better serve business and user needs, with more and more admins relying on Ansible to do so. How can we, as sysadmins, respond faster when these requests come up?
IT service management (ITSM) is a collection of policies and processes for the management and support of IT services. The main focus of ITSM is increasing the value of the customers’ service chain. But without the proper automation support, providing IT services can quickly become a major time-sink for administrators.
[ You might also like: Quick start guide to Ansible for Linux sysadmins ]
This is where the Red Hat Ansible Automation Platform and the Red Hat Ansible Certified Content Collection for ServiceNow come into play. Ansible Automation (with some help from existing Ansible content) can automate just about any task, while the modules from this Certified Collection allow you to keep the ServiceNow information up to date.
This Collection was designed and developed by the XLAB Steampunk team in close collaboration with Red Hat Ansible, specifically keeping end-users in mind. ServiceNow modules have an intuitive user interface backed by a robust implementation, offering support for things Ansible users expect (e.g., check mode and change detection).
In this post, I demonstrate a few sample Ansible Playbooks that take care of essential admin tasks such as:
- Updating incidents, problems, and change requests
- Updating the ServiceNow configuration management database (CMDB)
- Using the CMDB as an inventory source
Installing the Certified Content Collection for ServiceNow
You can download the servicenow.itsm Collection from automation hub or Ansible Galaxy. Before you can access content in the automation hub, you must first configure your credentials in the Ansible configuration file. For details, please refer to the "Hands On With Ansible Collections" blog post.
Once you have your credentials, you can install the ServiceNow Collection by running the following command:
$ ansible-galaxy collection install servicenow.itsm
If everything goes according to plan, you now have access to the following modules:
- servicenow.itsm.incident for managing incident tickets
- servicenow.itsm.problem for interacting with problems
- servicenow.itsm.change_request for handling changes
- servicenow.itsm.configuration_item for managing the CMDB
Each of the modules also has a counterpart that gives you read-only access to ServiceNow records.
The Certified Content Collection for ServiceNow also contains an inventory plugin called servicenow.itsm.now that allows you to use CMDB as an inventory source.
To verify nothing went awry, display the documentation for one of the modules by executing the following command:
$ ansible-doc servicenow.itsm.incident
If Ansible did not yell at us, you're all set.
Managing incidents, the Ansible way
Creating a new incident ticket using Ansible is reasonably straightforward, but before you can do that, you need to tell Ansible where your ServiceNow instance lives and what credentials to use. Do that by setting three environment variables:
$ export SN_HOST='https://dev12345.service-now.com'
$ export SN_USERNAME='user'
$ export SN_PASSWORD='pass'
Now that you have your credentials ready, you can create a new incident. The minimal Ansible playbook would look something like this:
---
- hosts: localhost
gather_facts: false
tasks:
- name: Create new incident
servicenow.itsm.incident:
state: new
short_description: Demo incident
Once the previous playbook finishes executing, you'll find a new incident listed in ServiceNow.
You can update an existing incident by providing either a ticket number or system id of the incident record. Ansible will compare the current and the desired states of the incident and make necessary changes to get them in sync.
---
- hosts: localhost
gather_facts: false
tasks:
- name: Update incident
servicenow.itsm.incident:
number: INC0010022
state: in_progress
If you run Ansible with the --diff
switch, it will report what changes it implemented to the incident record:
TASK [Update incident with a problem information] ***************************
--- before
+++ after
@@ -50,7 +50,7 @@
"parent": "",
"parent_incident": "",
"priority": "5",
- "state": "new",
+ "state": "in_progress",
"reassignment_count": "0",
"reopen_count": "0",
"reopened_by": "",
@@ -71,10 +71,10 @@
"sys_domain": "global",
"sys_domain_path": "/",
"sys_id": "2396e496074f2010d4a1fa9e7c1ed01c",
- "sys_mod_count": "0",
+ "sys_mod_count": "1",
"sys_tags": "",
"sys_updated_by": "admin",
You can also delete an existing incident by setting the state parameter to absent
.
---
- hosts: localhost
gather_facts: false
tasks:
- name: Delete incident
servicenow.itsm.incident:
number: INC0010022
state: absent
You can interact with problems and change requests in the same manner. However, managing configuration items is a bit different, so let’s focus on this area next.
Updating the CMDB
Because the ServiceNow CMDB has more than one configuration item type, you need to specify the sys_class_name parameter when adding new items. By default, the servicenow.itsm.configuration_item module will use the cmdb_ci system class name, but you can change it to any other cmdb_ci-derived class.
---
- name: Demonstrate CMDB management
hosts: localhost
gather_facts: false
tasks:
- name: Simulate VM creation
ansible.builtin.set_fact:
instance:
name: some-name
id: vm1234567890
public_ip_address: 1.2.3.4
- name: Register the newly-created VM instance
servicenow.itsm.configuration_item:
name: "{{ instance.name }}"
sys_class_name: cmdb_ci_vm_instance
ip_address: "{{ instance.public_ip_address }}"
other:
vm_inst_id: "{{ instance.id }}"
You used the generic other parameter that can contain arbitrary key-value pairs in the last task. Because ServiceNow tables are extensible, all modules have this parameter. You can use the other parameter to set column values that modules do not expose as top-level parameters. All ServiceNow Ansible modules have this parameter.
When updating or deleting an existing item, you don't have to specify the system class name because the module will automatically retrieve the name from the current record. But, you do have to provide a sys_id
parameter value.
---
- name: Demonstrate CMDB item update and deletion
hosts: localhost
gather_facts: false
tasks:
- name: Update the VM state
servicenow.itsm.configuration_item:
sys_id: b0ccabf1c0a80009001f14fd151d8df0
install_status: in_maintenance
- name: Remove item from CMDB
servicenow.itsm.configuration_item:
sys_id: b0ccabf1c0a80009001f14fd151d8df0
state: absent
Dynamic inventory
The CMDB can also serve as an inventory source. Because configuration items that represent servers and virtual machines (VMs) usually contain IP addresses, you can use them as an inventory source.
The minimal configuration for the inventory plugin looks like this:
---
plugin: servicenow.itsm.now
When used as an inventory source, the plugin will list all servers from the cmdb_ci_server table. You can automatically group and filter inventory hosts based on the conditions specified in the group_by configuration option:
---
plugin: servicenow.itsm.now
group_by:
os:
includes:
- Linux Red Hat
- Windows XP
In the previous example, Ansible created two groups: one for Windows XP and one for Linux computers. The inventory plugin performs as much filtering as possible on the backend, minimizing the amount of downloaded data.
You can also configure which column values the inventory plugin adds as host variables:
---
plugin: servicenow.itsm.now
columns:
- name
- classification
- cpu_type
group_by:
os:
includes:
- Linux Red Hat
- Windows XP
To test the configuration, execute the following command:
$ ansible-inventory -i inventory.now.yaml --graph --vars
Assuming that you stored the inventory configuration in the inventory.now.yaml
file. The output should look something like this:
@all:
|--@Linux_Red_Hat:
| |--P1000019
| | |--{ansible_host = my1.server.com}
| | |--{classification = Production}
| | |--{cpu_type = Intel}
| | |--{name = SAP-SD-01}
|--@Windows_XP:
| |--P1000020
| | |--{ansible_host = my2.server.com}
| | |--{classification = Production}
| | |--{cpu_type = Intel}
| | |--{name = SAP-SD-02}
|--@ungrouped:
And now that you know how to use individual modules and the inventory plugin, it is time for the grand finale.
Automatic resolution of a standard change request
Standard change requests are pre-approved procedures with minimal risks, and these properties make them prime candidates for automation.
So without any further ado, here is the playbook that will:
- Look up the change request by its number
- Mark the change request as being worked on
- Retrieve the affected configuration item from the change request
- Perform requested operations on said configuration item, and finally
- Close the change request
---
- hosts: localhost
gather_facts: false
tasks:
- name: Mark change request as in progress
servicenow.itsm.change_request:
number: "{{ change_number }}"
state: implement
register: change
- name: Fetch configuration item we will update
servicenow.itsm.configuration_item_info:
sys_id: "{{ change.record.cmdb_ci }}"
register: citem
- name: Create an in-memory inventory with the item
ansible.builtin.add_host:
name: host_to_update
ansible_host: "{{ citem.record.ip_address }}"
- hosts: host_to_update
tasks:
- name: Simulate some work
ansible.builtin.debug:
msg: Doing real work here
- hosts: localhost
gather_facts: false
tasks:
- name: Mark change request as done
servicenow.itsm.change_request:
number: "{{ change_number }}"
state: closed
Who could have thought that one can stuff this much awesomeness into a single playbook?
[ Looking for more on system automation? Get started with The Automated Enterprise, a free book from Red Hat. ]
The future is automatic
I covered quite a lot yet still only managed to scratch the surface of what is possible. So head over to automation hub or Ansible Galaxy, download the ServiceNow ITSM Ansible Collection, and start exploring. You can also see this new solution in action in this webinar.
If you need help with your ServiceNow process automation and integration with the Red Hat Ansible Automation Platform, reach out to our team at XLAB Steampunk who can help you get up and running in no time.
![Introduction to Ansible Tower](/sysadmin/sites/default/files/styles/card/public/2019-09/Kids_climbing_stack.jpg?itok=KUpIYr8c)
![Factory](/sysadmin/sites/default/files/styles/card/public/2019-07/factory-conveyor-belt.jpg?itok=ACSE4z2d)
![Easing into automation with Ansible](/sysadmin/sites/default/files/styles/card/public/2019-09/DippingToes_0.jpg?itok=W4PY3_GV)
![Author’s photo](/sysadmin/sites/default/files/styles/user_picture_square/public/pictures/2021-05/Tadej%20XLAB%20Steampunk_photo.jpg?itok=DZTfaY4l)
Tadej Borovšak
Tadej Borovšak is an Ansible Evangelist at XLAB Steampunk, where he works on tools that make the lives of fellow programmers and system administrators easier. More about me