{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "SentinelWorkspaceName": {
            "type": "string",
            "metadata": {
                "description": "Name of the Sentinel log analytics workspace to connect to"
            }
        },
        "LogicAppName": {
            "defaultValue": "logic-SyncDfCAlertsWithSentinelIncidents",
            "type": "String",
            "metadata": {
                "description": "Name of the logic app to create"
            }
        },
        "SentinelConnectionName": {
            "defaultValue": "connection-SyncDfCAlertsWithSentinelIncidents",
            "type": "string",
            "metadata": {
                "description": "Name of the API connection to create"
            }
        },
        "SentinelResourceGroupName": {
            "defaultValue": "[resourceGroup().name]",
            "type": "string",
            "metadata": {
                "description": "Name of the Sentinel resource group, if different from the resource group where the logic app is deployed"
            }
        }
    },
    "variables": {
        "MiRoleAssignmentId": "[guid(concat(resourceGroup().id, 'microsoftsentinelresponder-smi'))]",
        "SentinelResponderRoleDefinitionId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', '3e150937-b8fe-4cfb-8069-0eaf05ecd056')]",
        "SentinelConnectionApiId": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',resourceGroup().location,'/managedApis/azuresentinel')]",
        "SentinelConnectionId": "[concat(resourceGroup().id, '/providers/Microsoft.Web/connections/', parameters('SentinelConnectionName'))]",
        "ArmIncidentPrefix": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', parameters('SentinelResourceGroupName'), '/providers/Microsoft.OperationalInsights/workspaces/', parameters('SentinelWorkspaceName'), '/providers/Microsoft.SecurityInsights/Incidents/')]"
    },
    "resources": [
        {
            "type": "Microsoft.Web/connections",
            "apiVersion": "2016-06-01",
            "name": "[parameters('SentinelConnectionName')]",
            "location": "[resourceGroup().location]",
            "kind": "V1",
            "properties": {
                "displayName": "[parameters('SentinelConnectionName')]",
                "api": {
                    "name": "azuresentinel",
                    "displayName": "Microsoft Sentinel",
                    "description": "Cloud-native SIEM with a built-in AI so you can focus on what matters most",
                    "iconUri": "https://connectoricons-prod.azureedge.net/releases/v1.0.1645/1.0.1645.3345/azuresentinel/icon.png",
                    "brandColor": "#0072C6",
                    "id": "[variables('SentinelConnectionApiId')]",
                    "type": "Microsoft.Web/locations/managedApis"
                },
                "customParameterValues": {},
                "alternativeParameterValues": {},
                "parameterValueType": "Alternative"
            }
        },
        {
            "type": "Microsoft.Logic/workflows",
            "apiVersion": "2017-07-01",
            "name": "[parameters('LogicAppName')]",
            "dependsOn": [
                "[resourceId('Microsoft.Web/connections', parameters('SentinelConnectionName'))]"
            ],
            "location": "[resourceGroup().location]",
            "identity": {
                "type": "SystemAssigned"
            },
            "properties": {
                "state": "Disabled",
                "definition": {
                    "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
                    "contentVersion": "1.0.0.0",
                    "parameters": {
                        "$connections": {
                            "defaultValue": {},
                            "type": "Object"
                        }
                    },
                    "triggers": {
                        "Recurrence": {
                            "recurrence": {
                                "frequency": "Minute",
                                "interval": 60
                            },
                            "evaluatedRecurrence": {
                                "frequency": "Minute",
                                "interval": 60
                            },
                            "type": "Recurrence"
                        }
                    },
                    "actions": {
                        "HTTP": {
                            "runAfter": {
                                "KQL_Query": [
                                    "Succeeded"
                                ]
                            },
                            "type": "Http",
                            "inputs": {
                                "authentication": {
                                    "audience": "https://api.loganalytics.io",
                                    "type": "ManagedServiceIdentity"
                                },
                                "method": "GET",
                                "queries": {
                                    "query": "@{outputs('KQL_Query')}"
                                },
                                "uri": "https://api.loganalytics.io/v1/workspaces/@{variables('WorkspaceId')}/query"
                            }
                        },
                        "Initialize_variable": {
                            "runAfter": {},
                            "type": "InitializeVariable",
                            "inputs": {
                                "variables": [
                                    {
                                        "name": "ArmIncidentPrefix",
                                        "type": "string",
                                        "value": "[variables('ArmIncidentPrefix')]"
                                    }
                                ]
                            }
                        },
                        "KQL_Query": {
                            "runAfter": {
                                "WorkspaceId": [
                                    "Succeeded"
                                ]
                            },
                            "type": "Compose",
                            "inputs": "SecurityIncident\n| where TimeGenerated > ago(30d)\n// Limit results to incidents that are from Defender for Cloud\n| where AdditionalData.alertProductNames has \"Azure Security Center\"\n// Get only the latest incident status\n| summarize arg_max(TimeGenerated,*) by IncidentNumber\n// Only return incidents that are not closed\n| where Status != \"Closed\"\n// Join all alerts based on the AlertId with the latest alert event\n| mv-expand AlertIds\n| extend SystemAlertId = tostring(AlertIds)\n| join kind=inner ( SecurityAlert | summarize arg_max(TimeGenerated,*) by SystemAlertId | project SystemAlertId, Status ) on SystemAlertId\n| extend AlertStatus = Status1\n| extend IncidentStatus = Status\n// Summarize the results to filter out any incidents where there are more than one alert and one of them is either in status \"New\" or \"InProgress\"\n// to avoid prematurely closing the whole incident.\n// Normally there should always be a 1:1 mapping, but a SOC analyst might have added related alerts\n// https://learn.microsoft.com/en-us/azure/sentinel/relate-alerts-to-incidents\n| summarize by IncidentName, IncidentStatus, AlertStatus\n| summarize AlertStatus = make_set(AlertStatus) by IncidentName, IncidentStatus\n| where not (AlertStatus has_any (\"New\", \"InProgress\") and array_length(AlertStatus) > 1) and not (AlertStatus has_any (\"New\"))\n| mv-expand AlertStatus\n// Remove all incidents that already are in status active, when the alert status is inProgress\n| where not ( AlertStatus == \"InProgress\" and IncidentStatus == \"Active\" )"
                        },
                        "Loop_tables": {
                            "foreach": "@body('Parse_JSON')?['tables']",
                            "actions": {
                                "Check_if_rows_are_empty": {
                                    "actions": {
                                        "Loop_rows": {
                                            "foreach": "@items('Loop_tables')?['rows']",
                                            "actions": {
                                                "Compose": {
                                                    "runAfter": {},
                                                    "type": "Compose",
                                                    "inputs": "@items('Loop_rows')[2]"
                                                },
                                                "Switch": {
                                                    "runAfter": {
                                                        "Compose": [
                                                            "Succeeded"
                                                        ]
                                                    },
                                                    "cases": {
                                                        "Dismissed": {
                                                            "case": "Dismissed",
                                                            "actions": {
                                                                "Update_incident_2": {
                                                                    "runAfter": {},
                                                                    "type": "ApiConnection",
                                                                    "inputs": {
                                                                        "body": {
                                                                            "classification": {
                                                                                "ClassificationAndReason": "BenignPositive - SuspiciousButExpected",
                                                                                "ClassificationReasonText": "Closed because action taken on Defender for Cloud alert by the subscription owner. Original alert status was \"Dismissed\"."
                                                                            },
                                                                            "incidentArmId": "@{concat(variables('ArmIncidentPrefix'),items('Loop_rows')[0])}",
                                                                            "status": "Closed"
                                                                        },
                                                                        "host": {
                                                                            "connection": {
                                                                                "name": "@parameters('$connections')['azuresentinel-6064e82c']['connectionId']"
                                                                            }
                                                                        },
                                                                        "method": "put",
                                                                        "path": "/Incidents"
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "InProgress": {
                                                            "case": "InProgress",
                                                            "actions": {
                                                                "Update_incident_3": {
                                                                    "runAfter": {},
                                                                    "type": "ApiConnection",
                                                                    "inputs": {
                                                                        "body": {
                                                                            "incidentArmId": "@{concat(variables('ArmIncidentPrefix'),items('Loop_rows')[0])}",
                                                                            "status": "Active"
                                                                        },
                                                                        "host": {
                                                                            "connection": {
                                                                                "name": "@parameters('$connections')['azuresentinel-6064e82c']['connectionId']"
                                                                            }
                                                                        },
                                                                        "method": "put",
                                                                        "path": "/Incidents"
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "Resolved": {
                                                            "case": "Resolved",
                                                            "actions": {
                                                                "Update_incident": {
                                                                    "runAfter": {},
                                                                    "type": "ApiConnection",
                                                                    "inputs": {
                                                                        "body": {
                                                                            "classification": {
                                                                                "ClassificationAndReason": "TruePositive - SuspiciousActivity",
                                                                                "ClassificationReasonText": "Closed because action taken on Defender for Cloud alert by the subscription owner. Original alert status was \"Resolved\"."
                                                                            },
                                                                            "incidentArmId": "@{concat(variables('ArmIncidentPrefix'),items('Loop_rows')[0])}",
                                                                            "status": "Closed"
                                                                        },
                                                                        "host": {
                                                                            "connection": {
                                                                                "name": "@parameters('$connections')['azuresentinel-6064e82c']['connectionId']"
                                                                            }
                                                                        },
                                                                        "method": "put",
                                                                        "path": "/Incidents"
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    },
                                                    "default": {
                                                        "actions": {}
                                                    },
                                                    "expression": "@items('Loop_rows')[2]",
                                                    "type": "Switch"
                                                }
                                            },
                                            "runAfter": {},
                                            "type": "Foreach"
                                        }
                                    },
                                    "runAfter": {},
                                    "expression": {
                                        "and": [
                                            {
                                                "equals": [
                                                    "@empty(items('Loop_tables')?['rows'])",
                                                    "@false"
                                                ]
                                            }
                                        ]
                                    },
                                    "type": "If"
                                }
                            },
                            "runAfter": {
                                "Parse_JSON": [
                                    "Succeeded"
                                ]
                            },
                            "type": "Foreach"
                        },
                        "Parse_JSON": {
                            "runAfter": {
                                "HTTP": [
                                    "Succeeded"
                                ]
                            },
                            "type": "ParseJson",
                            "inputs": {
                                "content": "@body('HTTP')",
                                "schema": {
                                    "properties": {
                                        "tables": {
                                            "items": {
                                                "properties": {
                                                    "columns": {
                                                        "items": {
                                                            "properties": {
                                                                "name": {
                                                                    "type": "string"
                                                                },
                                                                "type": {
                                                                    "type": "string"
                                                                }
                                                            },
                                                            "required": [
                                                                "name",
                                                                "type"
                                                            ],
                                                            "type": "object"
                                                        },
                                                        "type": "array"
                                                    },
                                                    "name": {
                                                        "type": "string"
                                                    },
                                                    "rows": {
                                                        "items": {
                                                            "items": {
                                                                "type": "string"
                                                            },
                                                            "type": "array"
                                                        },
                                                        "type": "array"
                                                    }
                                                },
                                                "required": [
                                                    "name",
                                                    "columns",
                                                    "rows"
                                                ],
                                                "type": "object"
                                            },
                                            "type": "array"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        },
                        "WorkspaceId": {
                            "runAfter": {
                                "Initialize_variable": [
                                    "Succeeded"
                                ]
                            },
                            "type": "InitializeVariable",
                            "inputs": {
                                "variables": [
                                    {
                                        "name": "WorkspaceId",
                                        "type": "string",
                                        "value": "[reference(resourceId(subscription().subscriptionId, parameters('SentinelResourceGroupName'),'Microsoft.OperationalInsights/workspaces', parameters('SentinelWorkspaceName')), '2017-03-15-preview').customerId]"
                                    }
                                ]
                            }
                        }
                    },
                    "outputs": {}
                },
                "parameters": {
                    "$connections": {
                        "value": {
                            "azuresentinel-6064e82c": {
                                "connectionId": "[variables('SentinelConnectionId')]",
                                "connectionName": "[parameters('SentinelConnectionName')]",
                                "connectionProperties": {
                                    "authentication": {
                                        "type": "ManagedServiceIdentity"
                                    }
                                },
                                "id": "[variables('SentinelConnectionApiId')]"
                            }
                        }
                    }
                }
            }
        },
        {
            "type": "Microsoft.Resources/deployments",
            "apiVersion": "2022-09-01",
            "name": "nested-role-assignment",
            "resourceGroup": "[parameters('SentinelResourceGroupName')]",
            "subscriptionId": "[subscription().subscriptionId]",
            "dependsOn": [
                "[resourceId('Microsoft.Logic/workflows', parameters('LogicAppName'))]"
            ],
            "properties": {
                "mode": "Incremental",
                "template": {
                    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
                    "contentVersion": "1.0.0.0",
                    "resources": [
                        {
                            "type": "Microsoft.Authorization/roleAssignments",
                            "apiVersion": "2022-04-01",
                            "name": "[variables('MiRoleAssignmentId')]",
                            "properties": {
                                "roleDefinitionId": "[variables('SentinelResponderRoleDefinitionId')]",
                                "principalId": "[reference(resourceId(subscription().subscriptionId, resourceGroup().name,'Microsoft.Logic/workflows', parameters('LogicAppName')), '2019-05-01', 'full').identity.principalId]",
                                "principalType": "ServicePrincipal"
                            }
                        }
                    ]
                }
            }
        }
    ]
}