Azure Sentinel Analytics Rule ARM Template

I have got several people asking if they can develop and deploy Azure Sentinel Analytics rule in form of Azure ARM Template.

This article is simply to provide you a sample template so you can quickly deploy a rule in Azure Sentinel to test. You can also establish analytics rule template in your CICD pipeline if needed.

Use Case

You want to build a CICD environment for your security engineer to coordinate in developing detection rule and deploying to Azure Sentinel for testing without going to Azure Sentinel portal to update rule (which I don’t really like because it is slow and sometime the browser hangs at Rule setup step).

There is PowerShell module for Azure Sentinel but the rule creation isn’t really well designed as it makes the development and collaboration difficult. Moreover you are really familiar with Azure ARM template and would like to leverage the existing CICD.

ARM Template

Everyone working on Azure should be familiar with Azure undoubtedly. Given a very simple alert rule to monitor operation as follows:

let TargetKeyVaults = dynamic (
  [
    "shared-corporate-kv",
    "azsec-kv"
  ]
);
AzureDiagnostics
| where ResourceProvider =~ "MICROSOFT.KEYVAULT"
| where Resource in~ (TargetKeyVaults)
| project TimeGenerated, OperationName, KeyVaultName = Resource, ResourceGroup, CallerIPAddress, _ResourceId

Now we need to stringify the rule to support Json format:

"let TargetKeyVaults = dynamic (\n [\n \"shared-corporate-kv\",\n \"azsec-kv\"\n ]\n);\nAzureDiagnostics\n| where ResourceProvider =~ \"MICROSOFT.KEYVAULT\"\n| where Resource in~ (TargetKeyVaults)\n| project TimeGenerated, OperationName, KeyVaultName = Resource, ResourceGroup, CallerIPAddress, _ResourceId"

And now you can make an ARM template for your Azure Sentinel Analytics rule. The template below allows you to not only create a rule but also  to link to an existing Logic App workflow (the template is uploaded here)

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspaceName": {
      "type": "string",
      "defaultValue": "azsec-shared-workspace",
      "metadata": {
        "description": "The name of the Log Analytics Workspace Azure Sentinel is connected to."
      }
    },
    "analyticsRuleId": {
      "type": "string",
      "defaultValue": "[newGuid()]",
      "metadata": {
        "description": "The name (GUID) of the Azure Sentinel custom analytics rule."
      }
    },
    "analyticsRuleDisplayName": {
      "type": "string",
      "metadata": {
        "description": "The display name of the Azure Sentinel custom analytics rule."
      }
    },
    "analyticsRuleDescription": {
      "type": "string",
      "metadata": {
        "description": "The description of the Azure Sentinel custom analytics rule."
      }
    },
    "analyticsRuleSeverity": {
      "type": "string",
      "allowedValues": [
        "Informational",
        "Low",
        "Medium",
        "High"
      ],
      "metadata": {
        "description": "The severity of the Azure Sentinel custom analytics rule."
      }
    },
    "analyticsRuleQuery": {
      "type": "string",
      "metadata": {
        "description": "The query of the Azure Sentinel custom analytics rule."
      }
    },
    "alertDisplayNameFormat": {
      "type": "string",
      "metadata": {
        "description": "The display name format of the Azure Sentinel custom analytics rule. More information https://azsec.azurewebsites.net/2021/11/01/azure-sentinel-custom-alert-named-based-on-detected-resource/"
      }
    },
    "analyticsRuleTactics": {
      "type": "array",
      "allowedValues": [
        "InitialAccess",
        "PreAttack",
        "Execution",
        "Persistence",
        "PrivilegeEscalation",
        "DefenseEvasion",
        "CredentialAccess",
        "Discovery",
        "LateralMovement",
        "Collection",
        "Exfiltration",
        "CommandAndControl",
        "Impact"
      ],
      "metadata": {
        "description": "The tactic of the Azure Sentinel custom analytics rule. "
      }
    },
    "logicAppResourceId": {
      "type": "string",
      "defaultValue": "/subscriptions/67d6179d-a99d-4ccd-8c56-4d3ff2e13349/resourceGroups/azsec-corporate-rg/providers/Microsoft.Logic/workflows/alert_notification"
    },
    "automationRuleId": {
      "type": "string",
      "defaultValue": "15b9235d-46f0-49a6-910c-9d1d3a649899",
      "metadata": {
        "description": "The name (GUID) of the Azure Sentinel custom analytics rule."
      }
    }
  },
  "variables": {
    "alertRuleName": "[concat(parameters('workspaceName'), '/Microsoft.SecurityInsights/', parameters('analyticsRuleId'))]"
  },
  "resources": [
    {
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules",
      "name": "[variables('alertRuleName')]",
      "kind": "Scheduled",
      "apiVersion": "2021-09-01-preview",
      "properties": {
        "displayName": "[parameters('analyticsRuleDisplayName')]",
        "description": "[parameters('analyticsRuleDescription')]",
        "severity": "[parameters('analyticsRuleSeverity')]",
        "enabled": true,
        "query": "[parameters('analyticsRuleQuery')]",
        "queryFrequency": "PT5H",
        "queryPeriod": "PT5H",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0,
        "suppressionDuration": "PT5H",
        "suppressionEnabled": false,
        "tactics": "[parameters('analyticsRuleTactics')]",
        "alertRuleTemplateName": null,
        "incidentConfiguration": {
          "createIncident": true,
          "groupingConfiguration": {
            "enabled": false,
            "reopenClosedIncident": false,
            "lookbackDuration": "PT5H",
            "matchingMethod": "AllEntities",
            "groupByEntities": [],
            "groupByAlertDetails": [],
            "groupByCustomDetails": []
          }
        },
        "eventGroupingSettings": {
          "aggregationKind": "SingleAlert"
        },
        "alertDetailsOverride": {
          "alertDisplayNameFormat": "[parameters('alertDisplayNameFormat')]",
          "alertDescriptionFormat": "[parameters('alertDisplayNameFormat')]",
          "alertTacticsColumnName": null,
          "alertSeverityColumnName": null
        },
        "customDetails": {
          "TimeGenerated": "TimeGenerated",
          "KeyVaultName": "KeyVaultName",
          "ResourceGroup": "ResourceGroup",
          "CallerIPAddress": "CallerIPAddress",
          "OperationName": "OperationName"
        },
        "entityMappings": [
          {
            "entityType": "AzureResource",
            "fieldMappings": [
              {
                "identifier": "ResourceId",
                "columnName": "_ResourceId"
              }
            ]
          }
        ]
      }
    },
    {
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules/actions",
      "apiVersion": "2021-09-01-preview",
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspaceName'), 'Microsoft.SecurityInsights'),'/alertRules/',parameters('analyticsRuleId'),'/actions/',parameters('automationRuleId'))]",
      "name": "[concat(parameters('workspaceName'),'/Microsoft.SecurityInsights/', parameters('analyticsRuleId'), '/',parameters('automationRuleId'))]",
      "properties": {
        "logicAppResourceId": "[parameters('logicAppResourceId')]",
        "TriggerUri": "[listCallbackURL(concat(parameters('logicAppResourceId')),'2016-06-01').value]"
      }
    }
  ]
}

If you have ever worked with Azure Sentinel Analytics rule creation via Azure Portal or command line you would be able to understand this ARM template.

You need to deploy this ARM template to the same resource group of the target Log Analytics workspace that your Azure Sentinel is connected to.

This entry was posted in Security Automation and tagged . Bookmark the permalink.

1 Response to Azure Sentinel Analytics Rule ARM Template

  1. Pingback: Azure Sentinel near-real-time (NRT) Analytics Rule ARM Template -Microsoft Azure Security Randomness

Leave a Reply

Your email address will not be published. Required fields are marked *