{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "location": {
            "type": "string",
            "defaultValue": "[resourceGroup().location]",
            "metadata": {
                "description": "The Azure region to deploy the resources to."
            }
        },
        "logAnalyticsWorkspaceName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 63,
            "metadata": {
                "description": "The name of an existing Log Analytics workspace."
            }
        },
        "logAnalyticsWorkspaceResourceGroup": {
            "type": "string",
            "defaultValue": "",
            "metadata": {
                "description": "The resource group containing the Log Analytics workspace."
            }
        },
        "newTableName": {
            "type": "string",
            "defaultValue": "SpectraDetectLogs",
            "minLength": 3,
            "maxLength": 50,
            "metadata": {
                "description": "The name of the new table to create in the Log Analytics workspace."
            }
        },
        "useExistingStorageAccount": {
            "type": "bool",
            "defaultValue": false,
            "metadata": {
                "description": "Specify 'true' to use an existing storage account containing Spectra Detect reports, or 'false' to create a new dedicated storage account."
            }
        },
        "existingStorageAccountResourceGroup": {
            "type": "string",
            "defaultValue": "",
            "metadata": {
                "description": "The resource group containing the existing storage account. Required only if useExistingStorageAccount is true."
            }
        },
        "reportsStorageAccountName": {
            "type": "string",
            "defaultValue": "stspectradetectlogs",
            "maxLength": 24,
            "metadata": {
                "description": "The name of the storage account that holds the Spectra Detect reports."
            }
        },
        "reportsContainerName": {
            "type": "string",
            "defaultValue": "reports",
            "maxLength": 24,
            "metadata": {
                "description": "The name of the blob container that holds the Spectra Detect reports."
            }
        },
        "appServicePlanName": {
            "type": "string",
            "defaultValue": "asp-spectradetectlogs",
            "metadata": {
                "description": "The name of the App Service Plan for hosting the function app."
            }
        },
        "functionAppName": {
            "type": "string",
            "defaultValue": "funcspectradetectlogs",
            "metadata": {
                "description": "The name of the function app."
            }
        },
        "dataCollectionEndpointName": {
            "type": "string",
            "defaultValue": "dce-spectradetectlogs",
            "metadata": {
                "description": "The name of the data collection endpoint."
            }
        },
        "dataCollectionRuleName": {
            "type": "string",
            "defaultValue": "dcr-spectradetectlogs",
            "metadata": {
                "description": "The name of the data collection rule."
            }
        },
        "eventGridSystemTopicName": {
            "type": "string",
            "defaultValue": "egstspectradetectlogs",
            "metadata": {
                "description": "The name of the Event Grid system topic."
            }
        },
        "workbookDisplayName": {
            "type": "string",
            "defaultValue": "ReversingLabs-SpectraDetect",
            "metadata": {
                "description": "The friendly name for the workbook that is used in the Gallery or Saved List.  This name must be unique within a resource group."
            }
        },
        "workbookResourceName": {
            "type": "string",
            "defaultValue": "[newGuid()]",
            "metadata": {
                "description": "The name of the workbook resource."
            }
        },
        "rule1Guid": {
            "type": "string",
            "defaultValue": "[newGuid()]",
            "metadata": {
                "description": "The GUID for the analytics rule."
            }
        },
        "functionPackageUrl": {
            "type": "string",
            "metadata": {
                "description": "The URL for the function deployment package in Azure Storage"
            }
        }
    },
    "variables": {
        "logAnalyticsWorkspaceResourceId": "[if(empty(parameters('logAnalyticsWorkspaceResourceGroup')), resourceId('Microsoft.OperationalInsights/workspaces', parameters('logAnalyticsWorkspaceName')), resourceId(parameters('logAnalyticsWorkspaceResourceGroup'), 'Microsoft.OperationalInsights/workspaces', parameters('logAnalyticsWorkspaceName')))]",
        "functionAppStorageAccountName": "[reversinglabs.uniqueName('stfnspectradetect')]",
        "reportsStorageAccountName": "[if(parameters('useExistingStorageAccount'), parameters('reportsStorageAccountName'), reversinglabs.uniqueName(parameters('reportsStorageAccountName')))]",
        "functionAppName": "[reversinglabs.uniqueName(parameters('functionAppName'))]",
        "appInsightsName": "[reversinglabs.uniqueName('aispectradetectlogs')]",
        "dataCollectionEndpointName": "[reversinglabs.uniqueName(parameters('dataCollectionEndpointName'))]",
        "dataCollectionRuleName": "[reversinglabs.uniqueName(parameters('dataCollectionRuleName'))]",
        "storageBlobDataContributorRoleGuid": "2a2b9908-6ea1-4ae2-8e65-a410df84e7d1",
        "monitoringMetricsPublisherRoleGuid": "3913510d-42f4-4e42-8a64-420c390055eb",
        "eventGridSystemTopicName": "[reversinglabs.uniqueName(parameters('eventGridSystemTopicName'))]",
        "appServicePlanName": "[reversinglabs.uniqueName(parameters('appServicePlanName'))]",
        "reportsStorageAccountResourceId": "[if(parameters('useExistingStorageAccount'), resourceId(parameters('existingStorageAccountResourceGroup'), 'Microsoft.Storage/storageAccounts', parameters('reportsStorageAccountName')), resourceId('Microsoft.Storage/storageAccounts', variables('reportsStorageAccountName')))]"
    },
    "functions": [
        {
            "namespace": "reversinglabs",
            "members": {
                "uniqueName": {
                    "parameters": [
                        {
                            "name": "namePrefix",
                            "type": "string"
                        }
                    ],
                    "output": {
                        "type": "string",
                        "value": "[concat(toLower(parameters('namePrefix')), take(uniqueString(deployment().name), 5))]"
                    }
                }
            }
        }
    ],
    "resources": [
        {
            "type": "Microsoft.Storage/storageAccounts",
            "comments": "Storage account for the function app",
            "apiVersion": "2023-05-01",
            "name": "[variables('functionAppStorageAccountName')]",
            "location": "[parameters('location')]",
            "sku": {
                "name": "Standard_LRS",
                "tier": "Standard"
            },
            "kind": "StorageV2"
        },
        {
            "type": "Microsoft.Storage/storageAccounts",
            "location": "[parameters('location')]",
            "comments": "ADLS Gen2 storage account for Spectra Detect reports",
            "apiVersion": "2023-05-01",
            "condition": "[not(parameters('useExistingStorageAccount'))]",
            "name": "[variables('reportsStorageAccountName')]",
            "sku": {
                "name": "Standard_LRS",
                "tier": "Standard"
            },
            "kind": "StorageV2",
            "properties": {
                "largeFileSharesState": "Enabled",
                "isHnsEnabled": true
            },
            "resources": [
                {
                    "type": "Microsoft.Storage/storageAccounts/blobServices",
                    "apiVersion": "2023-05-01",
                    "condition": "[not(parameters('useExistingStorageAccount'))]",
                    "name": "[concat(variables('reportsStorageAccountName'), '/default')]",
                    "properties": {
                        "enableVersioning": true
                    },
                    "dependsOn": [
                        "[resourceId('Microsoft.Storage/storageAccounts', variables('reportsStorageAccountName'))]"
                    ]
                },
                {
                    "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
                    "apiVersion": "2023-05-01",
                    "condition": "[not(parameters('useExistingStorageAccount'))]",
                    "name": "[concat(variables('reportsStorageAccountName'), '/default/', parameters('reportsContainerName'))]",
                    "dependsOn": [
                        "[resourceId('Microsoft.Storage/storageAccounts', variables('reportsStorageAccountName'))]",
                        "[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('reportsStorageAccountName'), 'default')]"
                    ],
                    "properties": {
                        "publicAccess": "None"
                    }
                }
            ]
        },
        {
            "type": "Microsoft.Web/serverfarms",
            "comments": "App Service Plan for hosting the function app",
            "apiVersion": "2024-04-01",
            "name": "[variables('appServicePlanName')]",
            "location": "[parameters('location')]",
            "sku": {
                "name": "B1",
                "tier": "Basic"
            },
            "properties": {
                "perSiteScaling": false,
                "reserved": true
            }
        },
        {
            "type": "Microsoft.Web/sites",
            "comments": "Function app to process Spectra Detect reports",
            "apiVersion": "2024-04-01",
            "name": "[variables('functionAppName')]",
            "location": "[parameters('location')]",
            "kind": "functionapp,linux",
            "identity": {
                "type": "SystemAssigned"
            },
            "properties": {
                "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]",
                "siteConfig": {
                    "linuxFxVersion": "Python|3.10",
                    "netFrameworkVersion": "v4.0",
                    "alwaysOn": true,
                    "appSettings": [
                        {
                            "name": "APPINSIGHTS_INSTRUMENTATIONKEY",
                            "value": "[reference(resourceId('Microsoft.Insights/components', variables('appInsightsName'))).InstrumentationKey]"
                        },
                        {
                            "name": "APPINSIGHTS_PROFILERFEATURE_VERSION",
                            "value": "1.0.0"
                        },
                        {
                            "name": "AzureWebJobsFeatureFlags",
                            "value": "EnableWorkerIndexing"
                        },
                        {
                            "name": "WEBSITE_RUN_FROM_PACKAGE",
                            "value": "[parameters('functionPackageUrl')]"
                        },
                        {
                            "name": "FUNCTIONS_WORKER_RUNTIME",
                            "value": "python"
                        },
                        {
                            "name": "FUNCTIONS_EXTENSION_VERSION",
                            "value": "~4"
                        },
                        {
                            "name": "ENABLE_ORYX_BUILD",
                            "value": "true"
                        },
                        {
                            "name": "SCM_DO_BUILD_DURING_DEPLOYMENT",
                            "value": "true"
                        },
                        {
                            "name": "AzureWebJobsStorage",
                            "value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('functionAppStorageAccountName'), ';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('functionAppStorageAccountName')), '2023-05-01').keys[0].value, ';EndpointSuffix=core.windows.net')]"
                        },
                        {
                            "name": "REPORTS_STORAGE_CONNECTION_STRING",
                            "value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('reportsStorageAccountName'), ';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('reportsStorageAccountName')), '2023-05-01').keys[0].value, ';EndpointSuffix=core.windows.net')]"
                        },
                        {
                            "name": "REPORT_CONTAINER_NAME",
                            "value": "[parameters('reportsContainerName')]"
                        },
                        {
                            "name": "DCE_URL",
                            "value": "[reference(resourceId('Microsoft.Insights/dataCollectionEndpoints', variables('dataCollectionEndpointName')), '2023-03-11', 'Full').properties.logsIngestion.endpoint]"
                        },
                        {
                            "name": "DCR_ID",
                            "value": "[reference(resourceId('Microsoft.Insights/dataCollectionRules', variables('dataCollectionRuleName')), '2023-03-11', 'Full').properties.immutableId]"
                        },
                        {
                            "name": "DCR_STREAM_NAME",
                            "value": "[concat('Custom-', parameters('newTableName'), '_CL')]"
                        },
                        {
                            "name": "WEBSITE_CONTENTSHARE",
                            "value": "[concat(variables('functionAppName'), '-content')]"
                        },
                        {
                            "name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
                            "value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('functionAppStorageAccountName'), ';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('functionAppStorageAccountName')), '2023-05-01').keys[0].value, ';EndpointSuffix=core.windows.net')]"
                        }
                    ],
                    "httpsOnly": true,
                    "http20Enabled": true,
                    "minTlsVersion": "1.2",
                    "ftpsState": "Disabled",
                    "scmType": "None"
                }
            },
            "dependsOn": [
                "[resourceId('Microsoft.Storage/storageAccounts', variables('functionAppStorageAccountName'))]",
                "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]",
                "[resourceId('Microsoft.Insights/dataCollectionEndpoints', variables('dataCollectionEndpointName'))]",
                "[resourceId('Microsoft.Insights/dataCollectionRules', variables('dataCollectionRuleName'))]",
                "[resourceId('Microsoft.Insights/components', variables('appInsightsName'))]"
            ]
        },
        {
            "type": "Microsoft.Insights/components",
            "apiVersion": "2020-02-02",
            "name": "[variables('appInsightsName')]",
            "location": "[parameters('location')]",
            "kind": "web",
            "properties": {
                "Application_Type": "web",
                "publicNetworkAccessForIngestion": "Enabled",
                "publicNetworkAccessForQuery": "Enabled",
                "IngestionMode": "LogAnalytics",
                "WorkspaceResourceId": "[variables('logAnalyticsWorkspaceResourceId')]"
            }
        },
        {
            "type": "Microsoft.Resources/deployments",
            "apiVersion": "2021-04-01",
            "name": "[concat('deploy-rule-', parameters('rule1Guid'))]",
            "resourceGroup": "[if(empty(parameters('logAnalyticsWorkspaceResourceGroup')), resourceGroup().name, parameters('logAnalyticsWorkspaceResourceGroup'))]",
            "dependsOn": [
                "[extensionResourceId(if(empty(parameters('logAnalyticsWorkspaceResourceGroup')), resourceGroup().id, concat(subscription().id, '/resourceGroups/', parameters('logAnalyticsWorkspaceResourceGroup'))), 'Microsoft.Resources/deployments', concat('deploy-table-', parameters('newTableName')))]"
            ],
            "properties": {
                "mode": "Incremental",
                "template": {
                    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
                    "contentVersion": "1.0.0.0",
                    "resources": [
                                                {
                            "name": "[concat(parameters('logAnalyticsWorkspaceName'),'/Microsoft.SecurityInsights/', parameters('rule1Guid'))]",
                            "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules",
                            "kind": "Scheduled",
                            "apiVersion": "2023-12-01-preview",
                            "properties": {
                                "displayName": "Spectra Detect New Malicious File",
                                "description": "This query identifies Spectra Detect file analysis reports with a classification of 'malicious'.",
                                "severity": "High",
                                "enabled": true,
                                "query": "SpectraDetectLogs_CL\r\n| extend reportClassification = tostring(classification.classification)\r\n| extend Classification = case(reportClassification == 1, \"goodware\", reportClassification == 2, \"suspicious\", reportClassification == 3, \"malicious\", \"unknown\")\r\n| where Classification == \"malicious\"\r\n| extend sha1 = tostring(parse_json(tostring(parse_json(tostring(info.file)).hashes)).sha1)\r\n| extend hash_algorithm = \"SHA1\"\r\n| extend filename = tostring(parse_json(tostring(info.file)).file_name)\r\n\r\n",
                                "triggerOperator": "GreaterThan",
                                "triggerThreshold": 0,
                                "queryFrequency": "PT30M",
                                "queryPeriod": "PT30M",
                                "suppressionDuration": "PT5H",
                                "startTimeUtc": null,
                                "suppressionEnabled": false,
                                "tactics": [],
                                "techniques": [],
                                "subTechniques": [],
                                "alertRuleTemplateName": null,
                                "incidentConfiguration": {
                                    "createIncident": true,
                                    "groupingConfiguration": {
                                        "enabled": false,
                                        "reopenClosedIncident": false,
                                        "lookbackDuration": "PT5H",
                                        "matchingMethod": "AllEntities",
                                        "groupByEntities": [],
                                        "groupByAlertDetails": [],
                                        "groupByCustomDetails": []
                                    }
                                },
                                "eventGroupingSettings": {
                                    "aggregationKind": "SingleAlert"
                                },
                                "alertDetailsOverride": null,
                                "customDetails": null,
                                "entityMappings": [
                                    {
                                        "entityType": "FileHash",
                                        "fieldMappings": [
                                            {
                                                "identifier": "Algorithm",
                                                "columnName": "hash_algorithm"
                                            },
                                            {
                                                "identifier": "Value",
                                                "columnName": "sha1"
                                            }
                                        ]
                                    },
                                    {
                                        "entityType": "File",
                                        "fieldMappings": [
                                            {
                                                "identifier": "Name",
                                                "columnName": "filename"
                                            }
                                        ]
                                    }
                                ],
                                "sentinelEntitiesMappings": null,
                                "templateVersion": null
                            }
                        }
                    ]
                }
            }
        },
        {
            "type": "Microsoft.Resources/deployments",
            "apiVersion": "2021-04-01",
            "name": "[concat('deploy-table-', parameters('newTableName'))]",
            "resourceGroup": "[if(empty(parameters('logAnalyticsWorkspaceResourceGroup')), resourceGroup().name, parameters('logAnalyticsWorkspaceResourceGroup'))]",
            "properties": {
                "mode": "Incremental",
                "template": {
                    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
                    "contentVersion": "1.0.0.0",
                    "resources": [
                        {
                            "type": "Microsoft.OperationalInsights/workspaces/tables",
                            "apiVersion": "2023-09-01",
                            "name": "[concat(split(variables('logAnalyticsWorkspaceResourceId'), '/')[8], '/', parameters('newTableName'), '_CL')]",
                            "properties": {
                                "schema": {
                                    "name": "[concat(parameters('newTableName'), '_CL')]",
                                    "columns": [
                                        {
                                            "name": "TimeGenerated",
                                            "type": "datetime"
                                        },
                                        {
                                            "name": "task_id",
                                            "type": "int",
                                            "description": "The ID of the analysis task"
                                        },
                                        {
                                            "name": "submitted",
                                            "type": "int",
                                            "description": "Unix timestamp in seconds indicating the time when the file was submitted for analysis."
                                        },
                                        {
                                            "name": "forwarded_for",
                                            "type": "dynamic",
                                            "description": "List of IP addresses that were part of the forwarding chain for that request, including the original sender."
                                        },
                                        {
                                            "name": "processed",
                                            "type": "int",
                                            "description": "The number of seconds since the Unix epoch when the analysis task was processed"
                                        },
                                        {
                                            "name": "process_duration",
                                            "type": "int",
                                            "description": "The duration of the analysis task processing in seconds"
                                        },
                                        {
                                            "name": "direct_sender",
                                            "type": "string",
                                            "description": "IP address of the machine that sent the file to Spectra Detect. This is the immediate sender, the last hop in the forwarding chain (if the request was forwarded)."
                                        },
                                        {
                                            "name": "worker_hostname",
                                            "type": "string",
                                            "description": "Hostname of the Spectra Detect Worker that processed the file."
                                        },
                                        {
                                            "name": "worker_ip",
                                            "type": "dynamic",
                                            "description": "List of IP addresses associated with the Spectra DetectWorker that processed the file."
                                        },
                                        {
                                            "name": "worker_address",
                                            "type": "dynamic",
                                            "description": "List of DNS records associated with the Spectra Detect Worker that processed the file."
                                        },
                                        {
                                            "name": "info",
                                            "type": "dynamic",
                                            "description": "Information about the file, identification, and unpacking"
                                        },
                                        {
                                            "name": "classification",
                                            "type": "dynamic",
                                            "description": "Contains detailed file metadata including entropy, filename, file path, type, subtype, multiple hash values (MD5, SHA1, SHA256), file size, format identification details, and unpacking status."
                                        },
                                        {
                                            "name": "story",
                                            "type": "dynamic",
                                            "description": "The analysis story"
                                        },
                                        {
                                            "name": "tags",
                                            "type": "dynamic",
                                            "description": "The tags associated with the analysis"
                                        },
                                        {
                                            "name": "interesting_strings",
                                            "type": "dynamic",
                                            "description": "Interesting strings found during analysis with categories and occurrences"
                                        },
                                        {
                                            "name": "parent",
                                            "type": "int",
                                            "description": "The analysis task index number of the file this was extracted from."
                                        },
                                        {
                                            "name": "index",
                                            "type": "int",
                                            "description": "Index number of the extracted file"
                                        },
                                        {
                                            "name": "custom_data",
                                            "type": "dynamic",
                                            "description": "Custom data about the upload."
                                        }
                                    ]
                                }
                            }
                        },
                        {
                            "name": "[parameters('workbookResourceName')]",
                            "type": "microsoft.insights/workbooks",
                            "location": "[resourceGroup().location]",
                            "apiVersion": "2022-04-01",
                            "dependsOn": [],
                            "kind": "shared",
                            "properties": {
                                "displayName": "[parameters('workbookDisplayName')]",
                                "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":1,\"content\":{\"json\":\"<svg x=\\\"0px\\\" y=\\\"0px\\\"\\r\\n\\t viewBox=\\\"0 150 1541.9 295.3\\\" style=\\\"enable-background:new 0 0 1241.9 295.3; background:white\\\" xml:space=\\\"preserve\\\">\\r\\n<g>\\r\\n\\t<g>\\r\\n\\t\\t<path class=\\\"st0\\\" style=\\\"fill:#F6143F\\\" d=\\\"M279.3,303.1h-30.8l-27.9,92.2H173v-92.2h-20.6v109.6h84l9.7-30.7h35.2l9.4,30.7h22.5L279.3,303.1z M250,365\\r\\n\\t\\t\\tl9.3-30.2c1.6-5.5,2.7-11.4,3.8-17.3h1.3c1,5.9,2.2,11.8,3.8,17.3l9.1,30.2H250z\\\"/>\\r\\n\\t\\t<path class=\\\"st0\\\" style=\\\"fill:#F6143F\\\" d=\\\"M349.8,413.5c-12.5,0-17.8-0.3-31.7-0.9V303.1c14.5-0.6,19.8-0.9,32.3-0.9c29.3,0,47.5,5.2,47.5,29.8v1.3\\r\\n\\t\\t\\tc0,9.4-4.1,18.6-13.9,23c10.3,4.3,14.5,13.7,14.5,23.1v1.5C398.5,408.3,378.1,413.5,349.8,413.5 M377.8,332.7\\r\\n\\t\\t\\tc0-12.5-9.9-13.6-27.4-13.6h-12.2v29.7h18.6c17,0,21.1-5.6,21.1-14.7V332.7z M378.3,379.3c-0.1-9.6-4.6-15.6-21.4-15.6h-18.7v32.9\\r\\n\\t\\t\\th5.6c22.4,0,34.5-0.1,34.5-15.6V379.3z\\\"/>\\r\\n\\t\\t<path class=\\\"st0\\\" style=\\\"fill:#F6143F\\\" d=\\\"M446,415c-14.3,0-29.1-1.9-34.5-3.4v-15.8c9,0.9,19.2,1.8,32.9,1.8c13.3,0,19.6-3.7,19.6-13.6\\r\\n\\t\\t\\tc0-7.1-2.8-11.1-13.7-15.6l-16.5-6.8c-16.2-6.6-24.9-15.9-24.9-31.9c0-21.2,13.3-28.9,39.2-28.9c13.8,0,26.8,2.2,32,3.5V320\\r\\n\\t\\t\\tc-8.4-0.7-19.6-1.9-31.1-1.9c-12.8,0-19.8,2.2-19.8,11.1c0,6.6,3.1,10,14,14.5l14.9,6.1c19.2,7.8,26.8,15.6,26.8,34.2\\r\\n\\t\\t\\tC484.9,403.8,470.6,415,446,415\\\"/>\\r\\n\\t</g>\\r\\n\\t<g>\\r\\n\\t\\t<path class=\\\"st1\\\" style=\\\"fill:#231F20\\\" d=\\\"M52.9,292.1l25.8-44.7c-11.7-5-18.9-13.7-18.9-30.4v-1c0-28.9,21.8-34.2,48.2-34.2c11.1,0,21,0.3,30.7,0.7\\r\\n\\t\\t\\tv109.6h-20.1v-40.4h-10.2c-3.4,0-6.6,0-9.6-0.1l-24.2,40.6H52.9z M80,217.2c0,14.2,8.4,18.1,27.3,18.1c3.8,0,7.5,0,11.4-0.2v-36\\r\\n\\t\\t\\tc-26.8,0-38.6,0.2-38.6,17.1V217.2z\\\"/>\\r\\n\\t\\t<path class=\\\"st1\\\" style=\\\"fill:#231F20\\\" d=\\\"M291.5,182.5l-22.6,75.9c-1.9,6.4-3.2,13.7-4.4,19.6h-0.3c-1.5-5.8-2.5-13.3-4.4-19.6l-22.6-75.9h-84.9v109.6\\r\\n\\t\\t\\th69.8v-16.9H173V244h46v-16.5h-46v-27.9h48.1l27.9,92.5h30.1l33.2-109.6H291.5z\\\"/>\\r\\n\\t\\t<polygon class=\\\"st1\\\" style=\\\"fill:#231F20\\\" points=\\\"318,292.1 318,182.5 387.7,182.5 387.7,199.6 338.6,199.6 338.6,227.5 384.6,227.5 384.6,244 \\r\\n\\t\\t\\t338.6,244 338.6,275.1 387.7,275.1 387.7,292.1 \\t\\t\\\"/>\\r\\n\\t\\t<path class=\\\"st1\\\" style=\\\"fill:#231F20\\\" d=\\\"M463.7,292.1l-24.2-40.5c-2.9,0.1-6.2,0.1-9.6,0.1h-10.2v40.4h-20.1V182.5c9.7-0.4,19.6-0.7,30.7-0.7\\r\\n\\t\\t\\tc26.4,0,48.2,5.3,48.2,34.2v1c0,16.7-7.2,25.4-18.9,30.4l25.8,44.7H463.7z M458.4,216.3c0-17-11.8-17.1-38.6-17.1v36\\r\\n\\t\\t\\tc3.8,0.2,7.5,0.2,11.4,0.2c18.9,0,27.3-4,27.3-18.1V216.3z\\\"/>\\r\\n\\t\\t<path class=\\\"st1\\\" style=\\\"fill:#231F20\\\" d=\\\"M525.1,294.5c-14.3,0-29.1-1.9-34.5-3.4v-15.8c9,0.9,19.2,1.8,32.9,1.8c13.3,0,19.6-3.7,19.6-13.6\\r\\n\\t\\t\\tc0-7.1-2.8-11.1-13.7-15.6l-16.5-6.8c-16.2-6.6-24.9-15.9-24.9-31.9c0-21.2,13.3-28.9,39.2-28.9c13.9,0,26.8,2.2,32,3.5v15.6\\r\\n\\t\\t\\tc-8.4-0.7-19.6-1.9-31.1-1.9c-12.8,0-19.8,2.2-19.8,11.1c0,6.6,3.1,10,14,14.5l14.9,6c19.2,7.8,26.8,15.6,26.8,34.2\\r\\n\\t\\t\\tC564,283.2,549.7,294.5,525.1,294.5\\\"/>\\r\\n\\t\\t<rect x=\\\"573\\\" y=\\\"182.5\\\" class=\\\"st1\\\" style=\\\"fill:#231F20\\\" width=\\\"20.6\\\" height=\\\"109.6\\\"/>\\r\\n\\t\\t<path class=\\\"st1\\\" style=\\\"fill:#231F20\\\" d=\\\"M671.5,292.1l-35.1-65c-2.7-5-5.8-10.9-8.3-16.4h-0.3c0.3,6.2,0.6,13,0.6,19.6v61.8h-18.9V182.5h23.9l35,63.7\\r\\n\\t\\t\\tc2.6,5,6,11.4,8.4,16.7h0.3c-0.5-6.5-0.6-14.2-0.6-20.8v-59.6h19v109.6H671.5z\\\"/>\\r\\n\\t\\t<path class=\\\"st1\\\" style=\\\"fill:#231F20\\\" d=\\\"M753.2,294.5c-25.1,0-45.9-9.7-45.9-49.4v-15.5c0-41.9,23.6-49.3,46.3-49.3c16.1,0,31.9,2.7,35.2,3.7v15.8\\r\\n\\t\\t\\tc-7.1-0.6-24.2-1.5-31.7-1.5c-17.8,0-29.3,4-29.3,31.3V245c0,25.1,9.1,31.4,26.8,31.4c5.5,0,10.9-0.2,14.7-0.4v-26.6l-8.4,0v-15.7\\r\\n\\t\\t\\th28v57.4C783,292.4,769,294.5,753.2,294.5\\\"/>\\r\\n\\t</g>\\r\\n</g>\\r\\n</svg>\\r\\n\"},\"customWidth\":\"50\",\"name\":\"text - 1\"},{\"type\":1,\"content\":{\"json\":\"# ReversingLabs Spectra Detect\\r\\n\\r\\nThis workbook contains metrics and visualizations to improve the Spectra Detect experience within Microsoft Sentinel.\\r\\n\\r\\n[Click here to access Spectra Detect documentation.](https://docs.reversinglabs.com/SpectraDetect/)\"},\"customWidth\":\"50\",\"name\":\"welcome\",\"styleSettings\":{\"padding\":\"20px\",\"showBorder\":true}}]},\"name\":\"header group\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"e800163c-e34f-4e3a-a131-2376ea998b85\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"guide\",\"label\":\"❔Guide\",\"type\":10,\"isRequired\":true,\"isGlobal\":true,\"value\":\"Yes\",\"jsonData\":\"[\\\"Yes\\\", \\\"No\\\"]\",\"timeContext\":{\"durationMs\":86400000}},{\"id\":\"cc8e1a84-7479-4eb2-aa5a-d95ee81bc962\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"Subscription\",\"label\":\"🗝️ Subscription\",\"type\":6,\"isRequired\":true,\"typeSettings\":{\"includeAll\":true,\"showDefault\":false},\"timeContext\":{\"durationMs\":86400000},\"value\":\"\"},{\"id\":\"1231613d-d734-40da-8baf-c55fdee75df1\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"workspace\",\"label\":\"📈 Workspace\",\"type\":5,\"typeSettings\":{\"resourceTypeFilter\":{\"microsoft.operationalinsights/workspaces\":true}},\"timeContext\":{\"durationMs\":86400000},\"value\":\"\"},{\"id\":\"46ef1dfe-ea81-413c-a410-1ea67b7e61ab\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"timerange\",\"label\":\"⏱️ Time Range\",\"type\":4,\"isRequired\":true,\"isGlobal\":true,\"value\":{\"durationMs\":2592000000},\"typeSettings\":{\"selectableValues\":[{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":172800000},{\"durationMs\":604800000},{\"durationMs\":1209600000},{\"durationMs\":2419200000},{\"durationMs\":2592000000},{\"durationMs\":5184000000},{\"durationMs\":7776000000}],\"allowCustom\":true},\"timeContext\":{\"durationMs\":86400000}}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"name\":\"parameters - 2\"},{\"type\":1,\"content\":{\"json\":\"# How to use this workbook\\r\\n\\r\\nThis workbook is designed to give you a summary of your security operations with Spectra Detect.\\r\\n\\r\\nEnsure that you set the Subscription and Workspace parameters with values associated with your Microsoft Sentinel workspace.\\r\\n\\r\\nTo hide all informational messages, change the Guide parameter to \\\"No\\\"\",\"style\":\"info\"},\"conditionalVisibility\":{\"parameterName\":\"guide\",\"comparison\":\"isEqualTo\",\"value\":\"Yes\"},\"name\":\"text - 6\"},{\"type\":11,\"content\":{\"version\":\"LinkItem/1.0\",\"style\":\"tabs\",\"tabStyle\":\"bigger\",\"links\":[{\"id\":\"9f5bb9c2-95a4-4825-9b58-cda448650a8d\",\"cellValue\":\"section\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Overview\",\"subTarget\":\"ti\",\"preText\":\"\",\"style\":\"primary\"},{\"id\":\"5f16aeff-f8a3-40eb-9101-4cd932beb2ff\",\"cellValue\":\"section\",\"linkTarget\":\"parameter\",\"linkLabel\":\"Operations\",\"subTarget\":\"operations\",\"preText\":\"\",\"style\":\"primary\"}]},\"name\":\"links - 5\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":1,\"content\":{\"json\":\"# 🏠 Spectra Detect Overview\\r\\n\"},\"name\":\"text - 0\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SpectraDetectLogs_CL\\r\\n| extend reportClassification = tostring(classification.classification)\\r\\n| extend Classification = case(reportClassification == 1, \\\"goodware\\\", reportClassification == 2, \\\"suspicious\\\", reportClassification == 3, \\\"malicious\\\", \\\"unknown\\\")\\r\\n| summarize count() by Classification\",\"size\":4,\"title\":\"File Classifications Summary\",\"timeContextFromParameter\":\"timerange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"seriesLabelSettings\":[{\"seriesName\":\"malicious\",\"color\":\"red\"},{\"seriesName\":\"unknown\",\"color\":\"gray\"},{\"seriesName\":\"goodware\",\"color\":\"green\"},{\"seriesName\":\"suspicious\",\"color\":\"yellow\"}]}},\"customWidth\":\"33\",\"name\":\"query - 0\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SpectraDetectLogs_CL\\r\\n| extend ThreatName = tostring(classification.result)\\r\\n| where ThreatName != \\\"\\\"\\r\\n| summarize count() by ThreatName\",\"size\":4,\"title\":\"Most Common Threats\",\"timeContextFromParameter\":\"timerange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":\"33\",\"name\":\"query - 1\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SpectraDetectLogs_CL\\r\\n| extend file_name = tostring(parse_json(tostring(info.file)).file_name)\\r\\n| extend file_extension = tostring(parse_path(tostring(file_name)).Extension)\\r\\n| where file_extension != \\\"\\\"\\r\\n| summarize count() by file_extension\",\"size\":4,\"title\":\"Most Common File Extensions\",\"timeContextFromParameter\":\"timerange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\"},\"customWidth\":\"33\",\"name\":\"query - 1 - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SpectraDetectLogs_CL\\r\\n| where task_id != \\\"\\\"\\r\\n| summarize arg_min(TimeGenerated, *) by task_id\\r\\n| summarize count() by bin(TimeGenerated, 1d)\\r\\n\",\"size\":1,\"title\":\"Files Submitted For Analysis Over Time\",\"timeContextFromParameter\":\"timerange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"timechart\",\"chartSettings\":{\"seriesLabelSettings\":[{\"seriesName\":\"count_\",\"color\":\"green\"}]}},\"customWidth\":\"33\",\"name\":\"query - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SpectraDetectLogs_CL\\r\\n| summarize count() by bin(TimeGenerated, 1d)\\r\\n\",\"size\":1,\"title\":\"Total Files Analyzed Over Time\",\"timeContextFromParameter\":\"timerange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"timechart\",\"chartSettings\":{\"seriesLabelSettings\":[{\"seriesName\":\"count_\",\"color\":\"redBright\"}]}},\"customWidth\":\"33\",\"name\":\"query - 2 - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SpectraDetectLogs_CL\\r\\n| summarize count() by bin(TimeGenerated, 1d), worker_hostname\",\"size\":1,\"title\":\"Files Analyzed by Worker Node\",\"timeContextFromParameter\":\"timerange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"timechart\",\"chartSettings\":{\"seriesLabelSettings\":[{\"seriesName\":\"count_\",\"color\":\"redBright\"}]}},\"customWidth\":\"33\",\"name\":\"query - 2 - Copy\"}]},\"name\":\"overview group - 1\",\"styleSettings\":{\"showBorder\":true}}]},\"conditionalVisibility\":{\"parameterName\":\"section\",\"comparison\":\"isEqualTo\",\"value\":\"ti\"},\"name\":\"ti summary\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"loadType\":\"always\",\"items\":[{\"type\":1,\"content\":{\"json\":\"# 📊 Your Operations Summary\"},\"name\":\"text - 0\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":1,\"content\":{\"json\":\"## Microsoft Sentinel Incidents\"},\"name\":\"text - 4\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SecurityIncident\\r\\n| summarize arg_min(TimeGenerated, *) by IncidentNumber\\r\\n| mv-expand AlertIds\\r\\n| extend AlertId = tostring(AlertIds)\\r\\n| join SecurityAlert on $left.AlertId == $right.SystemAlertId\\r\\n| extend Query_ = tostring(parse_json(ExtendedProperties).Query)\\r\\n| where Query_ contains \\\"SpectraDetectLogs_CL\\\"\\r\\n| project TimeGenerated, IncidentNumber, Title, Description, Severity, Status, Entities\\r\\n| summarize count() by bin(TimeGenerated, 1d)\",\"size\":1,\"title\":\"Summary of Incidents\",\"timeContextFromParameter\":\"timerange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{workspace}\"],\"visualization\":\"linechart\",\"chartSettings\":{\"seriesLabelSettings\":[{\"seriesName\":\"TI\",\"color\":\"redBright\"}]}},\"customWidth\":\"50\",\"name\":\"query - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SecurityIncident\\r\\n| summarize arg_min(TimeGenerated, *) by IncidentNumber\\r\\n| mv-expand AlertIds\\r\\n| extend AlertId = tostring(AlertIds)\\r\\n| join SecurityAlert on $left.AlertId == $right.SystemAlertId\\r\\n| extend Query_ = tostring(parse_json(ExtendedProperties).Query)\\r\\n| where Query_ contains \\\"SpectraDetectLogs_CL\\\"\\r\\n| project Status, Classification, ClassificationReason\\r\\n| summarize count() by Status\",\"size\":3,\"title\":\"Operations Summary\",\"timeContextFromParameter\":\"timerange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"crossComponentResources\":[\"{workspace}\"],\"visualization\":\"piechart\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"Type\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"Type\",\"sortOrder\":2}]},\"customWidth\":\"50\",\"name\":\"query - 3\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SecurityIncident\\r\\n| summarize arg_min(TimeGenerated, *) by IncidentNumber\\r\\n| mv-expand AlertIds\\r\\n| extend AlertId = tostring(AlertIds)\\r\\n| join SecurityAlert on $left.AlertId == $right.SystemAlertId\\r\\n| extend Query_ = tostring(parse_json(ExtendedProperties).Query)\\r\\n| where Query_ contains \\\"SpectraDetectLogs_CL\\\"\\r\\n| project IncidentNumber, Title, Description, Severity, Status, Entities\\r\\n\",\"size\":1,\"title\":\"Malicious File Incidents\",\"timeContextFromParameter\":\"timerange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Entities\",\"formatter\":5}]}},\"name\":\"query - 4\"}]},\"name\":\"Operations Executive Summary\",\"styleSettings\":{\"showBorder\":true}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":1,\"content\":{\"json\":\"## Spectra Detect Operations\"},\"name\":\"text - 0\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SpectraDetectLogs_CL\\r\\n| summarize avg(process_duration)\\r\\n| extend avgs = strcat(tostring(round(avg_process_duration, 2)), \\\"s\\\")\",\"size\":4,\"title\":\"Average Analysis Time (seconds)\",\"timeContextFromParameter\":\"timerange\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"tiles\",\"tileSettings\":{\"titleContent\":{},\"leftContent\":{\"columnMatch\":\"avgs\",\"formatter\":12,\"formatOptions\":{\"palette\":\"blue\"}},\"showBorder\":false}},\"customWidth\":\"50\",\"name\":\"query - 1\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"SpectraDetectLogs_CL\\r\\n| summarize count() by worker_hostname\\r\\n| sort by count_ desc\",\"size\":1,\"title\":\"Total files analyzed by worker node\",\"timeContext\":{\"durationMs\":604800000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"50\",\"name\":\"query - 2\"}]},\"name\":\"operations - spectra detect\",\"styleSettings\":{\"showBorder\":true}}]},\"conditionalVisibility\":{\"parameterName\":\"section\",\"comparison\":\"isEqualTo\",\"value\":\"operations\"},\"name\":\"operations\"}],\"isLocked\":false,\"fallbackResourceIds\":[\"\"],\"fromTemplateId\":\"sentinel-UserWorkbook\"}",
                                "version": "1.0",
                                "sourceId": "[variables('logAnalyticsWorkspaceResourceId')]",
                                "category": "sentinel"
                            }
                        }
                    ]
                }
            }
        },
        {
            "type": "Microsoft.Insights/dataCollectionEndpoints",
            "apiVersion": "2023-03-11",
            "name": "[variables('dataCollectionEndpointName')]",
            "location": "[parameters('location')]",
            "properties": {
                "description": "Data collection endpoint for Spectra Detect logs"
            }
        },
        {
            "type": "Microsoft.Insights/dataCollectionRules",
            "apiVersion": "2023-03-11",
            "name": "[variables('dataCollectionRuleName')]",
            "location": "[parameters('location')]",
            "dependsOn": [
                "[resourceId('Microsoft.Insights/dataCollectionEndpoints', variables('dataCollectionEndpointName'))]",
                "[extensionResourceId(if(empty(parameters('logAnalyticsWorkspaceResourceGroup')), resourceGroup().id, concat(subscription().id, '/resourceGroups/', parameters('logAnalyticsWorkspaceResourceGroup'))), 'Microsoft.Resources/deployments', concat('deploy-table-', parameters('newTableName')))]"
            ],
            "properties": {
                "description": "Data collection rule for Spectra Detect logs",
                "dataCollectionEndpointId": "[resourceId('Microsoft.Insights/dataCollectionEndpoints', variables('dataCollectionEndpointName'))]",
                "destinations": {
                    "logAnalytics": [
                        {
                            "workspaceResourceId": "[variables('logAnalyticsWorkspaceResourceId')]",
                            "workspaceId": "[reference(variables('logAnalyticsWorkspaceResourceId'), '2023-09-01').customerId]",
                            "name": "[replace(reference(variables('logAnalyticsWorkspaceResourceId'), '2023-09-01').customerId, '-', '')]"
                        }
                    ]
                },
                "dataFlows": [
                    {
                        "streams": [
                            "[concat('Custom-', parameters('newTableName'), '_CL')]"
                        ],
                        "outputStream": "[concat('Custom-', parameters('newTableName'), '_CL')]",
                        "destinations": [
                            "[replace(reference(variables('logAnalyticsWorkspaceResourceId'), '2023-09-01').customerId, '-', '')]"
                        ],
                        "transformKql": "source"
                    }
                ],
                "streamDeclarations": {
                    "[concat('Custom-', parameters('newTableName'), '_CL')]": {
                        "columns": [
                            {
                                "name": "TimeGenerated",
                                "type": "datetime"
                            },
                            {
                                "name": "task_id",
                                "type": "int"
                            },
                            {
                                "name": "submitted",
                                "type": "int"
                            },
                            {
                                "name": "forwarded_for",
                                "type": "dynamic"
                            },
                            {
                                "name": "processed",
                                "type": "int"
                            },
                            {
                                "name": "process_duration",
                                "type": "int"
                            },
                            {
                                "name": "direct_sender",
                                "type": "string"
                            },
                            {
                                "name": "worker_hostname",
                                "type": "string"
                            },
                            {
                                "name": "worker_ip",
                                "type": "dynamic"
                            },
                            {
                                "name": "worker_address",
                                "type": "dynamic"
                            },
                            {
                                "name": "info",
                                "type": "dynamic"
                            },
                            {
                                "name": "classification",
                                "type": "dynamic"
                            },
                            {
                                "name": "story",
                                "type": "dynamic"
                            },
                            {
                                "name": "tags",
                                "type": "dynamic"
                            },
                            {
                                "name": "interesting_strings",
                                "type": "dynamic"
                            },
                            {
                                "name": "parent",
                                "type": "int"
                            },
                            {
                                "name": "index",
                                "type": "int"
                            },
                            {
                                "name": "custom_data",
                                "type": "dynamic"
                            }
                        ]
                    }
                }
            }
        },
        {
            "type": "Microsoft.EventGrid/systemTopics",
            "comments": "Event Grid system topic for Spectra Detect logs",
            "apiVersion": "2024-12-15-preview",
            "name": "[variables('eventGridSystemTopicName')]",
            "location": "[parameters('location')]",
            "identity": {
                "type": "SystemAssigned"
            },
            "properties": {
                "source": "[resourceId('Microsoft.Storage/storageAccounts', variables('reportsStorageAccountName'))]",
                "topicType": "Microsoft.Storage.StorageAccounts"
            },
            "dependsOn": [
                "[resourceId('Microsoft.Insights/dataCollectionEndpoints', variables('dataCollectionEndpointName'))]",
                "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]"
            ]
        },
        {
            "type": "Microsoft.EventGrid/systemTopics/eventSubscriptions",
            "comments": "Event subscription for the Event Grid system topic; triggers on Blob Created events",
            "apiVersion": "2024-12-15-preview",
            "name": "[concat(variables('eventGridSystemTopicName'), '/evgspectradetectlogs')]",
            "properties": {
                "destination": {
                    "endpointType": "AzureFunction",
                    "properties": {
                        "resourceId": "[concat(resourceId('Microsoft.Web/sites', variables('functionAppName')), '/functions/EventGridTrigger')]",
                        "maxEventsPerBatch": 1
                    }
                },
                "filter": {
                    "includedEventTypes": [
                        "Microsoft.Storage.BlobCreated"
                    ]
                }
            },
            "dependsOn": [
                "[resourceId('Microsoft.EventGrid/systemTopics', variables('eventGridSystemTopicName'))]",
                "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]",
                "[resourceId('Microsoft.Storage/storageAccounts', variables('reportsStorageAccountName'))]",
                "[resourceId('Microsoft.Resources/deploymentScripts', 'waitForFunctionApp')]"
            ]
        },
        {
            "type": "Microsoft.Authorization/roleAssignments",
            "comments": "Monitoring Metrics Publisher role assignment for the function app to write logs to the Data Collection Endpoint",
            "apiVersion": "2022-04-01",
            "name": "[guid(resourceId('Microsoft.Insights/dataCollectionEndpoints', variables('dataCollectionEndpointName')))]",
            "scope": "[resourceId('Microsoft.Insights/dataCollectionEndpoints', variables('dataCollectionEndpointName'))]",
            "dependsOn": [
                "[resourceId('Microsoft.Insights/dataCollectionEndpoints', variables('dataCollectionEndpointName'))]",
                "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]"
            ],
            "properties": {
                "roleDefinitionId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', variables('monitoringMetricsPublisherRoleGuid'))]",
                "principalId": "[reference(resourceId('Microsoft.Web/sites', variables('functionAppName')), '2024-04-01', 'full').identity.principalId]"
            }
        },
        {
            "type": "Microsoft.Authorization/roleAssignments",
            "comments": "Monitoring Metrics Publisher role assignment for the function app to write logs to the Data Collection Rule",
            "apiVersion": "2022-04-01",
            "name": "[guid(resourceId('Microsoft.Insights/dataCollectionRules', variables('dataCollectionRuleName')))]",
            "scope": "[resourceId('Microsoft.Insights/dataCollectionRules', variables('dataCollectionRuleName'))]",
            "dependsOn": [
                "[resourceId('Microsoft.Insights/dataCollectionRules', variables('dataCollectionRuleName'))]",
                "[resourceId('Microsoft.Insights/dataCollectionEndpoints', variables('dataCollectionEndpointName'))]",
                "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]"
            ],
            "properties": {
                "roleDefinitionId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', variables('monitoringMetricsPublisherRoleGuid'))]",
                "principalId": "[reference(resourceId('Microsoft.Web/sites', variables('functionAppName')), '2024-04-01', 'full').identity.principalId]"
            }
        },
        {
            "type": "Microsoft.Authorization/roleAssignments",
            "comments": "Storage Blob Data Contributor role assignment for the function app to write logs to the Storage Account",
            "apiVersion": "2022-04-01",
            "name": "[guid(variables('reportsStorageAccountResourceId'))]",
            "scope": "[variables('reportsStorageAccountResourceId')]",
            "dependsOn": [
                "[resourceId('Microsoft.Storage/storageAccounts', variables('reportsStorageAccountName'))]",
                "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]"
            ],
            "properties": {
                "roleDefinitionId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', variables('storageBlobDataContributorRoleGuid'))]",
                "principalId": "[reference(resourceId('Microsoft.Web/sites', variables('functionAppName')), '2024-04-01', 'full').identity.principalId]"
            }
        },
        {
            "type": "Microsoft.Resources/deploymentScripts",
            "comments": "Deployment script to wait for the function app to be ready",
            "apiVersion": "2020-10-01",
            "name": "waitForFunctionApp",
            "location": "[parameters('location')]",
            "kind": "AzurePowerShell",
            "properties": {
                "azPowerShellVersion": "9.7",
                "timeout": "PT20M",
                "retentionInterval": "PT1H",
                "cleanupPreference": "OnSuccess",
                "scriptContent": "Start-Sleep -Seconds 900"
            },
            "dependsOn": [
                "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]"
            ]
        }
    ],
    "outputs": {
        "ADLSStorageAccountName": {
            "type": "string",
            "value": "[variables('reportsStorageAccountName')]"
        },
        "ADLSStorageAccountAccessKey": {
            "type": "string",
            "value": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('reportsStorageAccountName')), '2023-05-01').keys[0].value]"
        },
        "ADLSContainerName": {
            "type": "string",
            "value": "reports"
        }
    }
}