Managing Instance-Specific System Properties for Dev/Test/Prod in ServiceNow

While watching this video by the venerable Jace Benson, I was inspired by an idea presented around the 4-minute mark, which he picked up from Maik Skoddow's article, here: a more effective way to manage instance-specific System Properties. So inspired was I, that I decided to not only adopt his suggestion, but to write a little tool to handle it for me as well! I call this tool "Local Properties". 'Local', here meaning "instance-specific"; properties which should have one value in one instance (such as your dev environment), and a different value in a different instance (such as production).

As many developers will know all too well, this is a problem that we face often: How do you use one property value in one instance and another value in another instance, without risking poisoning the data in the higher instance just by modifying the value in a lower instance (and perhaps not even realizing that it's been captured in your update set)?

In this article, we're going to discuss the idea that Jace presented to solve this problem in a robust and elegant way, as well as a free tool that I've built to handle this for you!

The idea presented in Jace's video is to use a specific naming convention for "local" System Properties wherein you prefix your instance-specific (“local”) system properties with the exact name of the instance to which they belong.
For example, if you have a system property like “my_rest_endpoint”, you would actually create a separate version of that property for each of your ServiceNow instances. Say you have three instances: Dev (acme-dev), Test (acme-test), and Prod (acme). In this case, you would create three separate versions of this system property like so:

  • acme-dev.my_rest_endpoint
  • acme-test.my_rest_endpoint
  • acme.my_rest_endpoint


This sounds simple enough -- but it still requires your code to "know" which instance it's in, in order to retrieve the correct property. Luckily, there's another system property in every ServiceNow instance called instance_name which we can use to make our code fancy and dynamic; and that's what I leveraged in order to build a little Script Include to handle this for us automatically!

All you have to do to use this functionality is copy the below code into a new Script Include in your instance. The Script Include should have the name LocalProperty, and should be accessible from all scopes.

View Script Include code (expand)


This above Script Include exposes two 'methods' (functions): .getProperty() and .setProperty(). These behave effectively identically to ServiceNow's own gs.getProperty() and gs.setProperty() APIs, except that it will prepend the system property name you specify with the instance name!

The Script Include above makes heavy use of JSDoc to document the methods - arguments that they accept, what they return, and example usage - but if you're having trouble picturing what I'm talking about, here are some examples of how you might interact with these methods in your own code:

Get the value of a local system property
Retrieve the value of the local system property named “my_instance.my_http_endpoint (where my_instance is the name of whatever instance the code is executing in, such as acme-dev)”.

var propName = 'my_http_endpoint';  
var localProp = new LocalProperty();  
var propVal = localProp.getProperty(propName);

Get local system property value (with default value if it doesn't exist)
Retrieve the value of the “my_instance.my_http_endpoint” system property, but specify a default value of “http://localhost:8080” to be returned if the property doesn't exist.

var propName = 'my_http_endpoint';  
var defaultVal = 'http://localhost:8080';  
var localProp = new LocalProperty();  
var propVal = localProp.getProperty(propName, defaultVal);

Get the value for a given system property, in a different instance ('my_other_instance')
Retrieve the value of the "my_http_endpoint" system property, as if you were in another instance (in this case, the "my_other_instance" instance).

var propName = 'my_http_endpoint';  
var defaultVal = 'http://localhost:8080';  
var instanceNameOverride = 'my_other_instance';  
var localProp = new LocalProperty(instanceNameOverride);  
var propVal = localProp.getProperty(propName, defaultVal);

Set the value of a local system property

var propName = 'my_http_endpoint';
var newPropVal = 'http://localhost:8080';
var localProp = new LocalProperty();
localProp.setProperty(propName, newPropVal);

Set the value of the local system property for a specific instance
Set the value of a given system property for a specific instance; not necessarily the instance in which the code is running.

var propName = 'my_http_endpoint';
var newPropVal = 'http://localhost:8080';
var instanceNameOverride = 'my_other_instance';
var localProp = new LocalProperty(instanceNameOverride);
localProp.setProperty(propName, defaultVal);

That's all there is to it!

After adding this Script Include to your instance, you should be able to get and set local (instance-specific) System Properties using the pattern new LocalProperty().getProperty('my_prop', 'default value here'); or new LocalProperty().setProperty('my_prop', 'new_val');.

Thanks for reading! If you find my content useful, please consider checking out my latest book: The ServiceNow Development Handbook, check out some of my other articles below, subscribe to this blog and if you like, connect with me on LinkedIn.
If you like Jace's content as much as I do, consider checking out his website and YouTube channel!