{"id":7905,"date":"2026-03-16T21:01:26","date_gmt":"2026-03-17T03:01:26","guid":{"rendered":"https:\/\/gregsowell.com\/?p=7905"},"modified":"2026-03-16T21:01:26","modified_gmt":"2026-03-17T03:01:26","slug":"servicenow-to-ansible-event-driven-automation-the-easy-way","status":"publish","type":"post","link":"https:\/\/gregsowell.com\/?p=7905","title":{"rendered":"ServiceNow to Ansible Event Driven Automation The Easy Way"},"content":{"rendered":"<p><a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/ChatGPT-Image-Mar-16-2026-09_54_12-PM.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/ChatGPT-Image-Mar-16-2026-09_54_12-PM-300x200.png\" alt=\"\" width=\"300\" height=\"200\" class=\"aligncenter size-medium wp-image-7946\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/ChatGPT-Image-Mar-16-2026-09_54_12-PM-300x200.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/ChatGPT-Image-Mar-16-2026-09_54_12-PM-768x512.png 768w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/ChatGPT-Image-Mar-16-2026-09_54_12-PM-1024x683.png 1024w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/ChatGPT-Image-Mar-16-2026-09_54_12-PM.png 1536w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><br \/>\nI first have to say that the technique pioneered here was completely engineered by my brother-from-another-mother <a href=\"https:\/\/www.linkedin.com\/in\/nick-ario\/\">Nick Arellano<\/a>.  Connect with this brilliant dude on LinkedIn NOW!<\/p>\n<h2>Introduction<\/h2>\n<p>There is a <a href=\"https:\/\/gregsowell.com\/?p=6542\">traditional method that allowed ServiceNOW(SNOW) to connect to the Ansible Automation Platform&#8217;s(AAP) API<\/a>, but while this worked, it was clunky.<br \/>\nIn short it would go from Service Catalog(SC) item => SNOW workflow => REST message => Oauth token.<br \/>\nIf you wanted to add a new SC, you would have to duplicate each one of those pieces save for the Oauth token&#8230;which becomes quite tedious.  A lot of those pieces are often controlled by the &#8220;SNOW team&#8221;, which means it could take weeks or even months to have additions or changes done.<\/p>\n<p>Imagine if there was a better way(simpler and faster) \ud83d\ude42<br \/>\nThis better way is to have SNOW call Ansible&#8217;s Event Driven Automation(EDA).<br \/>\nThe process looks like Service Catalog item => business rule => REST message.<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/1.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/1-300x151.png\" alt=\"\" width=\"300\" height=\"151\" class=\"aligncenter size-medium wp-image-7907\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/1-300x151.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/1-768x387.png 768w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/1-1024x515.png 1024w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/1.png 1480w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><br \/>\nIn this configuration the REST message and business rule is created once by the SNOW team, and you don&#8217;t have to touch it after that.<br \/>\nThe business rule will grab all of the variables from the service catalog and pass them right over to EDA which will then kickoff an Ansible workflow or job template.<br \/>\nThis means I can create\/update my SNOW service catalog items whenever I want and I will immediately see the update!<\/p>\n<h2>Demo<\/h2>\n<p><iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/qTu4IshQK34?si=PcIjp6Ow9CdqosT8\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/p>\n<h2>EDA Configuration<\/h2>\n<p>I&#8217;m starting with the EDA configuration because I have to feed part of this into SNOW&#8217;s REST message.<br \/>\nAll of my <a href=\"https:\/\/github.com\/gregsowell\/snow-eda\">files are here in my git repository<\/a>.<\/p>\n<p><strong>EDA Credential<\/strong><br \/>\nI&#8217;ll start by creating a token to be used for protection of the Event Stream(ES).  Click on Automation Decisions, then Infrastructure, Credentials, and last Create credential:<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_1.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_1-300x203.png\" alt=\"\" width=\"300\" height=\"203\" class=\"aligncenter size-medium wp-image-7908\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_1-300x203.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_1-768x519.png 768w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_1.png 872w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Configure:<br \/>\nName &#8211; something unique<br \/>\nCredential type &#8211; Token Event Stream<br \/>\nToken &#8211; create a complex password here<br \/>\nHttp Header Key &#8211; defaults to Authorization<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_2.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_2-300x241.png\" alt=\"\" width=\"300\" height=\"241\" class=\"aligncenter size-medium wp-image-7909\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_2-300x241.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_2.png 727w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p><strong>Event Streams<\/strong><br \/>\nEvent streams are what EDA uses to collect messages.  In this case we&#8217;ll stand up a webhook with a unique URL and authentication.  This is what the SNOW REST message points towards.<\/p>\n<p>Under Automation Decisions, click on Event Streams and click Create event stream:<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_3.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_3-300x147.png\" alt=\"\" width=\"300\" height=\"147\" class=\"aligncenter size-medium wp-image-7910\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_3-300x147.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_3-768x376.png 768w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_3.png 846w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Configure:<br \/>\nName &#8211; something unique<br \/>\nEvent stream type &#8211; Token Event Stream<br \/>\nCredential &#8211; the one just created<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_4.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_4-300x63.png\" alt=\"\" width=\"300\" height=\"63\" class=\"aligncenter size-medium wp-image-7911\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_4-300x63.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_4-768x160.png 768w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_4-1024x214.png 1024w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_4.png 1241w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p><strong>Create a Rulebook<\/strong><br \/>\nA rulebook is really just setting the basics for the listener and configuring a decision tree.<br \/>\nThe tree is really just a set of conditional statements (if it matches this and that, but not those things) that will run playbooks or workflows in the controller.<\/p>\n<p>You can find <a href=\"https:\/\/github.com\/gregsowell\/snow-eda\/blob\/main\/rulebooks\/snow-rulebook.yml\">my rulebook here in my repo<\/a>.  I&#8217;ve got the whole rulebook below:<\/p>\n<pre class=\"gs-code\"><code class=\"language-plaintext\">---\r\n- name: ServiceNOW Events\r\n  hosts: all\r\n  execution_strategy: parallel\r\n  sources:\r\n    - ansible.eda.webhook:\r\n        port: &quot;{{ webhook_port | default(5000) }}&quot;\r\n        token: &quot;{{ webhook_token | default(omit) }}&quot;\r\n  rules:\r\n    - name: ServiceNOW | Provision Virtual Machine\r\n      condition: |\r\n        event.payload.requester == &quot;gsowell@redhat.com&quot; and\r\n        event.payload.catalog_item == &quot;VM Provision&quot; and\r\n        event.payload.event == &quot;SERVICE_CATALOG&quot;\r\n      action:\r\n        run_workflow_template:\r\n          name: ServiceNOW | VM Provision\r\n          organization: Default\r\n          job_args:\r\n            extra_vars:\r\n              _hosts: &quot;{{ event.payload.hostname }}&quot;\r\n              snow_request_name: &quot;{{ event.payload.request_name }}&quot;\r\n              virtual_machines:\r\n                - name: &quot;{{ event.payload.hostname }}&quot;\r\n                  cluster: &quot;{{ event.payload.cluster }}&quot;\r\n                  vm_size: &quot;{{ event.payload.vm_size }}&quot;\r\n                  custom_fields:\r\n                    vmware_linked_clone: &quot;{{ event.payload.linked_clone }}&quot;\r\n                    vmware_template: &quot;{{ event.payload.template }}&quot;\r\n\r\n    - name: ServiceNOW | Deprovision Virtual Machine\r\n      condition: |\r\n        event.payload.requester == &quot;gsowell@redhat.com&quot; and\r\n        event.payload.catalog_item == &quot;VM Decomission&quot; and\r\n        event.payload.event == &quot;SERVICE_CATALOG&quot;\r\n      action:\r\n        run_workflow_template:\r\n          name: ServiceNOW | VM Deprovision\r\n          organization: Default\r\n          job_args:\r\n            extra_vars:\r\n              _hosts: &quot;{{ event.payload.virtual_machine }}&quot;\r\n              snow_request_name: &quot;{{ event.payload.request_name }}&quot;\r\n              virtual_machines:\r\n                - name: &quot;{{ event.payload.virtual_machine }}&quot;\r\n\r\n    - name: ServiceNOW | Terraform Provision VMware\r\n      condition: |\r\n        event.payload.requester == &quot;gsowell@redhat.com&quot; and\r\n        event.payload.catalog_item == &quot;GregSowell VMWare VM Terraform AAP&quot; and\r\n        event.payload.event == &quot;SERVICE_CATALOG&quot;\r\n      action:\r\n        run_workflow_template:\r\n          name: SNOW Provision VM Via Terraform\r\n          organization: Default\r\n          # job_args:\r\n            # extra_vars:\r\n            #   _hosts: &quot;{{ event.payload.virtual_machine }}&quot;\r\n            #   snow_request_name: &quot;{{ event.payload.request_name }}&quot;\r\n            #   virtual_machines:\r\n            #     - name: &quot;{{ event.payload.virtual_machine }}&quot;\r\n\r\n    - name: ServiceNOW | Terraform Remove VMware\r\n      condition: |\r\n        event.payload.requester == &quot;gsowell@redhat.com&quot; and\r\n        event.payload.catalog_item == &quot;GregSowell Remove VMWare VM Terraform AAP&quot; and\r\n        event.payload.event == &quot;SERVICE_CATALOG&quot;\r\n      action:\r\n        run_workflow_template:\r\n          name: SNOW Provision VM Via Terraform\r\n          organization: Default\r\n          job_args:\r\n            extra_vars:\r\n              remove_vm: true\r\n            #   snow_request_name: &quot;{{ event.payload.request_name }}&quot;\r\n            #   virtual_machines:\r\n            #     - name: &quot;{{ event.payload.virtual_machine }}&quot;\r\n\r\n    - name: ServiceNOW | Unhandled Events\r\n      condition: event.payload is defined\r\n      action:\r\n        debug:<\/code><\/pre>\n<p>The beginning is fairly standard, setting up EDA webhook settings.<br \/>\nExecution strategy defaults to serial which means it performs one at a time.  Here I&#8217;m overriding it to perform in parallel.<br \/>\nDown toward the bottom I&#8217;m setting up the port and token(if it&#8217;s configured).<\/p>\n<pre class=\"gs-code\"><code class=\"language-plaintext\">---\r\n- name: ServiceNOW Events\r\n  hosts: all\r\n  execution_strategy: parallel\r\n  sources:\r\n    - ansible.eda.webhook:\r\n        port: &quot;{{ webhook_port | default(5000) }}&quot;\r\n        token: &quot;{{ webhook_token | default(omit) }}&quot;<\/code><\/pre>\n<p>I&#8217;ll cover two of the rules in the rulebook section:<\/p>\n<pre class=\"gs-code\"><code class=\"language-plaintext\">  rules:\r\n    - name: ServiceNOW | Provision Virtual Machine\r\n      condition: |\r\n        event.payload.requester == &quot;gsowell@redhat.com&quot; and\r\n        event.payload.catalog_item == &quot;VM Provision&quot; and\r\n        event.payload.event == &quot;SERVICE_CATALOG&quot;\r\n      action:\r\n        run_workflow_template:\r\n          name: ServiceNOW | VM Provision\r\n          organization: Default\r\n          job_args:\r\n            extra_vars:\r\n              _hosts: &quot;{{ event.payload.hostname }}&quot;\r\n              snow_request_name: &quot;{{ event.payload.request_name }}&quot;\r\n              virtual_machines:\r\n                - name: &quot;{{ event.payload.hostname }}&quot;\r\n                  cluster: &quot;{{ event.payload.cluster }}&quot;\r\n                  vm_size: &quot;{{ event.payload.vm_size }}&quot;\r\n                  custom_fields:\r\n                    vmware_linked_clone: &quot;{{ event.payload.linked_clone }}&quot;\r\n                    vmware_template: &quot;{{ event.payload.template }}&quot;<\/code><\/pre>\n<p>Note the condition section; this is where all of the matching happens for each rule.  This is really just matching values in the variables being passed to the data stream.  Here I&#8217;m looking for who requested the SNOW item, what the name of the service catalog item is, and if it came from the service catalog.  That way you can send all of your SNOW catalog items and for each one all you have to do is add a new entry to the rulebook!<br \/>\nNext you will notice the action section, which is were I point it towards the workflow or job template.  The &#8220;name&#8221; in &#8220;run_workflow_template&#8221; should match your workflow name exactly.<br \/>\nThe job_args where I&#8217;m setting up variables is optional as all of the accepted variables will be passed over anyway.<\/p>\n<p>A tip I learned from Nick is to add the following to the end of your rulebooks.  If a message comes through and isn&#8217;t matched with anything in the list, this rule will print all of the message detail including the attached variables to the &#8220;Rule Audit&#8221; log.  It&#8217;s great when adding new catalog items as you quickly get all the information you want to utilize in your playbooks as well as things you can use in your rulebook conditionals.<\/p>\n<pre class=\"gs-code\"><code class=\"language-plaintext\">    - name: ServiceNOW | Unhandled Events\r\n      condition: event.payload is defined\r\n      action:\r\n        debug:<\/code><\/pre>\n<p><strong>Add Project<\/strong><br \/>\nAdding a project in EDA is little different than adding it in controller.  It&#8217;s simply a way to connect to a git repository to pull in rulebooks.<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_5.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_5-300x148.png\" alt=\"\" width=\"300\" height=\"148\" class=\"aligncenter size-medium wp-image-7913\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_5-300x148.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_5-768x379.png 768w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_5.png 863w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Configure the following:<br \/>\nName<br \/>\nOrganization<br \/>\nSource control type &#8211; pretty much always git<br \/>\nSource control URL<br \/>\nSource control credential &#8211; I have all my stuff in a public git repo, but you will most likely need to configure a credential to connect to your repo.<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_6.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_6-300x122.png\" alt=\"\" width=\"300\" height=\"122\" class=\"aligncenter size-medium wp-image-7914\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_6-300x122.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_6-768x311.png 768w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_6-1024x415.png 1024w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_6.png 1395w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p><strong>Adding Rulebook Activation<\/strong><br \/>\nThe rulebook activation is where you pull it all together.  Start by going to Rulebook Activations and click &#8220;Create rulebook activation&#8221;:<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_7.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_7-300x125.png\" alt=\"\" width=\"300\" height=\"125\" class=\"aligncenter size-medium wp-image-7918\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_7-300x125.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_7-768x320.png 768w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_7.png 946w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Configure it:<br \/>\nName<br \/>\nOrg<br \/>\nProject &#8211; this is the project we just added<br \/>\nRulebook &#8211; this is our newly created rulebook<br \/>\nEvent streams &#8211; this is our newly created ES.<br \/>\nCredential &#8211; this is what we use to authenticate to the controller.  Even though we have the gateway system since AAP 2.5 you still have to setup a connection to controller.<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_8.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_8-300x145.png\" alt=\"\" width=\"300\" height=\"145\" class=\"aligncenter size-medium wp-image-7919\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_8-300x145.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_8-768x370.png 768w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_8-1024x493.png 1024w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_8.png 1318w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p><strong>Verification<\/strong><br \/>\nYou know you are rocking and rolling when the status shows &#8220;Running&#8221;:<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_9.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_9-300x141.png\" alt=\"\" width=\"300\" height=\"141\" class=\"aligncenter size-medium wp-image-7920\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_9-300x141.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_9.png 656w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<h2>SNOW Configuration<\/h2>\n<p><strong>Create REST Message<\/strong><br \/>\nIn ServiceNOW, start by creating a REST message.  This only has to be done a single time, and it usually has to be done by a SNOW admin.  From the menu type &#8220;rest message&#8221; and then click it from system web services => outbound:<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_10.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_10-300x250.png\" alt=\"\" width=\"300\" height=\"250\" class=\"aligncenter size-medium wp-image-7923\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_10-300x250.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_10.png 427w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>From the top right, click New:<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_11.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_11-300x37.png\" alt=\"\" width=\"300\" height=\"37\" class=\"aligncenter size-medium wp-image-7924\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_11-300x37.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_11-768x95.png 768w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_11.png 900w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>The endpoint is the link supplied when you created the event stream in EDA.  You can always go back and reference it if you need.<br \/>\nAfter that at the bottom you need to create a POST option with method of POST, and the endpoint will be the same as listed above:<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_12.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_12-300x288.png\" alt=\"\" width=\"300\" height=\"288\" class=\"aligncenter size-medium wp-image-7925\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_12-300x288.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_12-768x736.png 768w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_12.png 893w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Next click the <strong>HTTP Request<\/strong> tab and create a header entry of Authorization and a value of the token you created in EDA:<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_13.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_13-300x218.png\" alt=\"\" width=\"300\" height=\"218\" class=\"aligncenter size-medium wp-image-7926\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_13-300x218.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_13.png 744w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p><strong>Create A Business Rule<\/strong><br \/>\nA business rule is essentially a server-side script in SNOW that is always watching what&#8217;s going on in your instance.  Below I will configure triggers that will call the REST message created above.<\/p>\n<p>In the menu type &#8220;business rules&#8221; and click new from the top right menu:<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_14.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_14-230x300.png\" alt=\"\" width=\"230\" height=\"300\" class=\"aligncenter size-medium wp-image-7928\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_14-230x300.png 230w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_14.png 339w\" sizes=\"auto, (max-width: 230px) 100vw, 230px\" \/><\/a><\/p>\n<p>Add a name, place it in the Requested Item table, activate it and make sure you have some advanced options.<\/p>\n<p>From here you want to go to the &#8220;when to run&#8221; tab and add any conditionals you like.  For me I set it to trigger on &#8220;insert&#8221; and only if it was requested by me.  I did this since this is a shared lab and I wanted to trigger my catalog items only for me.  Be sure to adjust this to meet your needs:<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_15.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_15-300x246.png\" alt=\"\" width=\"300\" height=\"246\" class=\"aligncenter size-medium wp-image-7929\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_15-300x246.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_15-768x629.png 768w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_15.png 932w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Now click the &#8220;Advanced&#8221; tab and paste in the following script:<\/p>\n<pre class=\"gs-code\"><code class=\"language-plaintext\">(function executeRule(current, previous) {\r\n  var REST_MESSAGE_NAME = &quot;Greg Sowell - SNOW EDA&quot;;\r\n  var EVENT_NAME = &quot;SERVICE_CATALOG&quot;;\r\n\r\n  var r = new sn_ws.RESTMessageV2(REST_MESSAGE_NAME, &quot;POST&quot;);\r\n\r\n  var json = { event: EVENT_NAME };\r\n\r\n  if (current.cat_item) {\r\n    json[&quot;catalog_item&quot;] = current.cat_item.getDisplayValue();\r\n  }\r\n\r\n  if (current.opened_by) {\r\n    var requester = current.opened_by.getRefRecord();\r\n    if (requester.isValidRecord()) {\r\n      json[&quot;requester&quot;] = requester.getValue(&quot;email&quot;);\r\n    }\r\n  }\r\n\r\n  if (current.request) {\r\n    json[&quot;request_name&quot;] = current.request.getValue(&quot;short_description&quot;);\r\n  }\r\n\r\n  for (var key in current.variables) {\r\n    if (current.variables.hasOwnProperty(key)) {\r\n      var variable = current.variables[key];\r\n      json[key] =\r\n        variable.getDisplayValue() != null\r\n          ? variable.getDisplayValue()\r\n          : JSON.parse(String(variable));\r\n    }\r\n  }\r\n\r\n  var jsonString = JSON.stringify(json);\r\n  r.setRequestBody(jsonString);\r\n  r.setTimeout(10000);\r\n  r.execute();\r\n})(current, previous);<\/code><\/pre>\n<p><a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_16.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_16-300x200.png\" alt=\"\" width=\"300\" height=\"200\" class=\"aligncenter size-medium wp-image-7930\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_16-300x200.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_16-768x513.png 768w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_16.png 987w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>The script points toward the name of the newly created REST message and grabs all of the variables from any triggering service catalog item and pushes it to EDA.  Nick was particularly clever with this bit!  This is what makes the whole process so simple.<\/p>\n<p><strong>Create Service Catalog Item<\/strong><br \/>\nThis is the easy part&#8230;not that any of this should have been too terribly difficult.<br \/>\nReally you create anything in the SC, save, and you are done.<\/p>\n<p>There are two options for configuring a SC item.  One is using the &#8220;catalog builder&#8221;, which will step you through to GUI build one easily:<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_17.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_17.png\" alt=\"\" width=\"269\" height=\"297\" class=\"aligncenter size-full wp-image-7932\" \/><\/a><\/p>\n<p>I prefer the manual way as I&#8217;m just faster with it since it&#8217;s familiar to me.  This is found by searching for &#8220;maintain items&#8221;:<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_18.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_18-300x294.png\" alt=\"\" width=\"300\" height=\"294\" class=\"aligncenter size-medium wp-image-7933\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_18-300x294.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_18.png 333w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>At the top of the SC item, fill out the name, catalog, and category.<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_19.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_19-300x98.png\" alt=\"\" width=\"300\" height=\"98\" class=\"aligncenter size-medium wp-image-7934\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_19-300x98.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_19-768x251.png 768w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_19.png 795w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Scroll all the way to the bottom and add any variables you&#8217;d like to collect from your clients.  Notice here I have a mixture of just single lines and multiple choice single selects.  Also note that if you want to change the order of the questions, edit their &#8220;order&#8221; number:<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_20.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_20-300x148.png\" alt=\"\" width=\"300\" height=\"148\" class=\"aligncenter size-medium wp-image-7935\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_20-300x148.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_20-768x379.png 768w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_20-1024x505.png 1024w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_20.png 1111w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>For a variable you set the type, then fill out the question and the variable name.  Remember that the variable name used here will be passed to EDA and ultimately your playbook as an extra-var:<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_21.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_21-300x202.png\" alt=\"\" width=\"300\" height=\"202\" class=\"aligncenter size-medium wp-image-7936\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_21-300x202.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_21.png 758w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Don&#8217;t forget to set a default value whenever you can(helps users make the right selection and also serves as an example:<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_22.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_22-300x118.png\" alt=\"\" width=\"300\" height=\"118\" class=\"aligncenter size-medium wp-image-7937\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_22-300x118.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_22.png 451w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<h2>Operation<\/h2>\n<p>Now users can go to the service catalog, and order your item.<br \/>\nOnce they do it will be grabbed by the business rule, and sent to EDA via the SNOW rest message.<br \/>\nEDA will then pass it over to controller via the specified playbook.<br \/>\nThe playbook will then complete your automation.<\/p>\n<p>To view the EDA logs from a SNOW message you go to Rule Audit and click the event:<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_24.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_24-300x138.png\" alt=\"\" width=\"300\" height=\"138\" class=\"aligncenter size-medium wp-image-7940\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_24-300x138.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_24-768x352.png 768w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_24.png 791w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>You then click the Events tab and click the listener name:<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_25.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_25-300x190.png\" alt=\"\" width=\"300\" height=\"190\" class=\"aligncenter size-medium wp-image-7941\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_25-300x190.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_25.png 499w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>This will then show you all of the variables that came from the SNOW SC item:<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_23.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_23-281x300.png\" alt=\"\" width=\"281\" height=\"300\" class=\"aligncenter size-medium wp-image-7939\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_23-281x300.png 281w, https:\/\/gregsowell.com\/wp-content\/uploads\/2026\/03\/Screenshot_23.png 615w\" sizes=\"auto, (max-width: 281px) 100vw, 281px\" \/><\/a><\/p>\n<h2>Conclusion<\/h2>\n<p>To add a new connection we add a new catalog item, update the EDA rulebook, and you are done!<\/p>\n<p>I hope you found this useful and if you give it a go, let me know how it all comes out.  If you make changes to the process or come up with something better, please let me know that too!<\/p>\n<p>Good luck and happy automating!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I first have to say that the technique pioneered here was completely engineered by my brother-from-another-mother Nick Arellano. Connect with this brilliant dude on\u2026<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[49],"tags":[],"class_list":["post-7905","post","type-post","status-publish","format-standard","hentry","category-ansible"],"_links":{"self":[{"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/posts\/7905","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/gregsowell.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=7905"}],"version-history":[{"count":12,"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/posts\/7905\/revisions"}],"predecessor-version":[{"id":7947,"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/posts\/7905\/revisions\/7947"}],"wp:attachment":[{"href":"https:\/\/gregsowell.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7905"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gregsowell.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7905"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gregsowell.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7905"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}