ServiceNow SaltStack Integration OpenVPN REST Part 2

Part 2 of 2 (

Following up on my previous post I will be covering the SaltStack side of the Integration.

The first thing to do was figure out a way to capture the username from the end user in Snow and send that to SaltStack.

I used a REST API to do this.

I installed Salt-API and put in the following settings into the master config file.

port: pick a port number
host: hostname
ssl_crt: /etc/ssl/private/cert.pem #path to ssl key
ssl_key: /etc/ssl/private/key.pem
webhook_disable_auth: True #set this to false if you want auth enabled
webhook_url: /hook . # allows a webhook

Then the next step is to create a reactor file. This tells salt what to do when something is sent to webhook via a REST api.
Place the following config at this path /etc/salt/master.d/reactor.conf

It will look something like this:


– salt/netapi/hook/open_vpn_reset:
– /srv/reactor/open_vpn_phone_reset.sls

When something is sent to link of ipofsaltserver:portnumber/webhooklink it will render the sls of open_vpn_reset.sls

Now you need to create the open vpn rest sls file. The one I created is below.

{% set postdata = data.get(‘post’,{}) %} # This allows you to receive the data sent to salt api and use it
– tgt: ‘connect’
– args:
– cmd: ./sacli –user {{postdata.username}} –lock 0 GoogleAuthLock
– cwd: /usr/local/openvpn_as/scripts

The trick to this sls is that when the data is sent to the webhook you pass a var called user with username. Salt will take this var and place it in postdata.username and the it will render.

This will allow end users to run this script without contacting operations to run the script for them.

ServiceNow SaltStack Integration with OpenVPN with REST

This part 1 of 2 articles to view the second article click the following link (

We use SaltStack to manage various things on our servers. Also use OpenVpn with Google Authenticator for two factor on login. We use ServiceNow for our ticketing system.

This works pretty well. Until someone gets a new phone and they need a new QR code. We have quick script that resets this.

The old workflow was end user submits a ticket asking for the account to be reset. I run the script and then tell them to re join the phone.

This is fine but do I really need to run the script myself? This gave me the idea of using self service in ServiceNow to automate this task.

The first thing I did was to create a very simple record producer that has the caller’s name and a username variable.  For caller it is a reference variable to sys_user table. If you put the following default value in it will auto sync the caller with the user who is viewing the record.


More info regarding record producers can be found at the link below:

So once I decided that I wanted to do this, I need to figure out how to build it.

Both ServiceNow and SaltStack have REST API’s. This is how I will integrate both services.

ServiceNow Rest API documentation:!/rest_api_doc?v=kingston&id=c_TableAPI

SaltStack REST API documentation:!/rest_api_doc?v=kingston&id=c_TableAPI

After that I needed a way to get ServiceNow which is hosted in AWS to talk with the SaltStack server that is hosted behind firewalls in our VMware stack.

For this ServiceNow provides a MID server to help with this. Refer to my other blog post link below regarding the MID server.

ServiceNow MID Server in Docker

The I had to create a scripted REST API in ServiceNow. I set the URL endpoint to webhook url I created in SaltStack. (I will show the SaltStack side of things in my next post). Then set the HTTP headers and query parameters using the outbound rest message in ServiceNow.

Once this is created I need to add the code to my record producer to send out the username variable to SaltStack via the REST API.

The Record Producer code  is below. Feel free to use or edit to your liking.

var username1 = producer.username + ” “;

try {

var r = new sn_ws.RESTMessageV2(‘Salt Open VPN’, ‘OpenVPn’);
r.setStringParameterNoEscape(‘var’, ”);
var body = {‘username’: username1};
var bodyText = JSON.stringify(body);
//override authentication profile
//authentication type =’basic’/ ‘oauth2’
//r.setAuthentication(authentication type, profile name);

//set a MID server name if one wants to run the message on MID
r.setMIDServer(‘dev mid’);

//if the message is configured to communicate through ECC queue, either
//by setting a MID server or calling executeAsync, one needs to set skip_sensor
//to true. Otherwise, one may get an intermittent error that the response body is null
//r.setEccParameter(‘skip_sensor’, true);

var response = r.execute();
var httpStatus = response.getStatusCode();
catch(ex) {
var message = ex.getMessage();

Hello welcome to my blog.

This is just a place for me to put random things I am working on.

My name is James and I work as a System Administrators.

I like to mess around with ServiceNow and automation at work.

When I get home I like to cook, make beer and do other random things. When I am not having fun I am usually fixing my new to me old house or working on my girlfriends car.