John Joyner's Guide: Manual Step-by-Step¶
This page follows John Joyner's original 14-step guide as closely as possible, mapping each step to the automation scripts.
Use this page if you want to understand exactly what the automation does, or if you prefer a manual walkthrough before trusting the orchestrator.
Prefer automation?
If you just want to deploy, use one of the automated method pages. Come back here when you want to understand why each step exists.
Step 1: Create User-Assigned Managed Identity¶
John's guide step 1. The ITSM-MI identity is used for all Azure-side auth — no service principal, no client secrets stored anywhere.
Manual (Azure Portal / CLI):
az identity create \
--name ITSM-MI \
--resource-group rg-azure-monitor-itsm \
--location eastus
# Assign Reader + Monitoring Contributor at subscription scope
IDENTITY_ID=$(az identity show --name ITSM-MI --resource-group rg-azure-monitor-itsm --query principalId -o tsv)
az role assignment create --assignee $IDENTITY_ID --role Reader --scope /subscriptions/<subscription-id>
az role assignment create --assignee $IDENTITY_ID --role "Monitoring Contributor" --scope /subscriptions/<subscription-id>
Automation script:
Step 2: Create Resource Group¶
Manual:
This is included automatically in New-Prerequisites.ps1.
Steps 3–4: Create Key Vault and Store Secrets¶
John's guide steps 3–4. The Key Vault holds the three SNOW credentials. It is created with RBAC authorization (not vault access policies).
Manual:
az keyvault create \
--name itsm-kv \
--resource-group rg-azure-monitor-itsm \
--location eastus \
--enable-rbac-authorization true
# Grant the managed identity Key Vault Secrets User
az role assignment create \
--assignee $IDENTITY_ID \
--role "Key Vault Secrets User" \
--scope $(az keyvault show --name itsm-kv --query id -o tsv)
# Store the three secrets
az keyvault secret set --vault-name itsm-kv --name ItsmApiIntegrationCode --value https://dev123456.service-now.com
az keyvault secret set --vault-name itsm-kv --name ItsmApiUserName --value azure_monitor_svc
az keyvault secret set --vault-name itsm-kv --name ItsmApiSecret --value <snow-password>
Automation script:
.\deploy\scripts\Set-KeyVaultSecrets.ps1 `
-ResourceGroupName rg-azure-monitor-itsm `
-SnowInstanceUrl https://dev123456.service-now.com `
-SnowUsername azure_monitor_svc
# (prompted for SNOW password)
Stores three secrets:
| Secret Name | Value |
|---|---|
ItsmApiIntegrationCode |
SNOW instance URL |
ItsmApiUserName |
SNOW service account username |
ItsmApiSecret |
SNOW service account password |
Step 5: Create Key Vault API Connection¶
John's guide step 5. Creates the API connection itsm-keyvault-connection-mi that the Logic Apps use to read Key Vault secrets at runtime.
Name is hard-coded
The connection name itsm-keyvault-connection-mi is referenced by name inside the Logic App ARM templates. Do not change this name, or the Logic Apps will fail to deploy correctly.
This connection uses oauthMI (Managed Identity auth) — no service principal required.
This step runs automatically as part of New-Prerequisites.ps1.
Steps 6–9: Deploy Logic Apps and Customize SNOW Fields¶
John's guide steps 6–9. Deploy the two Logic Apps, then update the SNOW-specific field values for your environment.
Both Logic Apps deploy in Disabled state by design (John's zero-trust approach — they cannot fire until you deliberately enable them in Step 14).
Manual (Bicep example):
az deployment group create \
--resource-group rg-azure-monitor-itsm \
--template-file deploy/bicep/main.bicep \
--parameters deploy/bicep/main.bicepparam
After deploying, customize the Logic App for your SNOW environment:
- In the Azure portal, open
Azure-Monitor-Alert-ITSM-HTTP-API - Click Edit to open the Logic App Designer
- Find the HTTP action named Create_SNOW_Incident
- Update the JSON body with your SNOW environment values:
| Field | Description | How to find it |
|---|---|---|
company |
Your SNOW company sys_id |
GET /api/now/table/core_company |
assignment_group |
SNOW group sys_id for ticket routing |
GET /api/now/table/sys_user_group?sysparm_query=name=Service Desk |
caller_id |
Default caller sys_id |
Usually the integration service account's sys_id |
category / subcategory |
Ticket category | e.g., software, hardware, network |
- For the target table (John defaults to
incident): incident— IT incidents (default, recommended)em_event— Event Management events (requires ITOM)change_request— Change requestsproblem— Problem records
Update the HTTP action URL from .../table/incident to .../table/{your-table} and adjust field names to match that table's schema.
- Save the Logic App.
Tip: Use
New-SnowPdiSetup.ps1output to findsys_idvalues for your PDI.
Step 7: Restrict Key Vault Firewall¶
John's guide step 7. After the Logic Apps are deployed, lock down Key Vault to only accept connections from the Logic App outbound IPs.
You will lose local access
After running this script, your local machine IP will no longer have direct access to Key Vault unless you add it manually. The script outputs the IPs it added so you can reverse if needed.
Automation script:
Step 10: Create Action Group¶
John's guide step 10. Creates the Action Group ag-azure-monitor-itsm that points to the Alert Logic App webhook.
Automation script:
Returns the Action Group resource ID. Associate it with your Azure Monitor alert rules:
$agId = (Get-AzActionGroup -ResourceGroupName rg-azure-monitor-itsm -Name ag-azure-monitor-itsm).Id
# Example: CPU alert on a VM
Add-AzMetricAlertRuleV2 `
-ResourceGroupName rg-my-workload `
-Name 'High CPU - ITSM' `
-TargetResourceScope '/subscriptions/.../resourceGroups/rg-my-workload' `
-TargetResourceType 'Microsoft.Compute/virtualMachines' `
-TargetResourceRegion eastus `
-ActionGroupId $agId `
-WindowSize ([TimeSpan]::FromMinutes(5)) `
-EvaluationFrequency ([TimeSpan]::FromMinutes(1)) `
-Severity 2 `
-Condition (New-AzMetricAlertRuleV2Criteria -MetricName 'Percentage CPU' `
-Operator GreaterThan -Threshold 90 -TimeAggregation Average)
Steps 11–12: Trigger Test Alert and Validate¶
John's guide steps 11–12. Validate the integration fires correctly before full rollout.
Automated end-to-end test:
For manual validation, trigger a real Azure Monitor alert (e.g., temporarily lower a threshold on an existing metric alert rule), then confirm:
- SNOW incident is created with the correct severity mapping
-
correlation_idon the SNOW record matches the Azure MonitoralertId - Alert state in Azure Monitor changes to
Acknowledged - Resolving the alert in Azure Monitor closes the SNOW incident (Resolved state)
- Closing the SNOW incident fires the Business Rule → Close Logic App → Azure Monitor alert closed
Step 13: Configure SNOW Business Rule¶
Manual step — cannot be automated
This is the one step that cannot be automated from outside SNOW. It requires SNOW admin access in a browser. No PowerShell or API call can create a Business Rule remotely on a standard PDI.
New-SnowPdiSetup.ps1 can automate this on a developer PDI using the SNOW REST API with admin credentials — but not on production instances.
-
Get the Close Logic App webhook URL:
-
In SNOW → System Definition → Business Rules, create a new rule:
- Table:
incident - When:
after - On:
update -
Condition:
state changes to Closed -
Paste the script from
src/servicenow/snow-automation-rule-script.js -
Replace
<CLOSE-LOGIC-APP-WEBHOOK-URL>with the URL from step 1
Automation (PDI only):
.\deploy\scripts\New-SnowPdiSetup.ps1 `
-SnowInstanceUrl https://dev123456.service-now.com `
-AdminUsername admin `
-CloseLogicAppWebhookUrl <url-from-step-1>
See ServiceNow PDI Setup for full instructions.
Step 14: Enable Logic Apps + Secure Inputs/Outputs + Access Control¶
John's guide step 14. Enable both Logic Apps and apply security hardening.
Enable both Logic Apps:
Secure Inputs/Outputs (prevents SNOW credentials from appearing in Logic App run history — must be done manually in the portal):
- In the Azure portal, open
Azure-Monitor-Alert-ITSM-HTTP-API→ Edit - For each action that reads a Key Vault secret, click
...→ Settings - Toggle Secure Inputs and Secure Outputs → On
- Repeat for
Azure-Monitor-Close-ITSM-HTTP-API - Save both Logic Apps
Logic App Access Control (restricts inbound calls to Azure Monitor IPs only):
- In the Azure portal, open each Logic App → Settings → Workflow settings
- Under Access control configuration → Trigger, add the Azure Monitor service tag:
AzureMonitor - This prevents anyone other than Azure Monitor from calling the Logic App trigger URL