diff --git a/Logos/NetApp.svg b/Logos/NetApp.svg
new file mode 100644
index 00000000000..f9f49b9771c
--- /dev/null
+++ b/Logos/NetApp.svg
@@ -0,0 +1,4 @@
+
diff --git a/Solutions/NetApp Ransomware Resilience/Data/Solution_NetAppRansomwareResilience.json b/Solutions/NetApp Ransomware Resilience/Data/Solution_NetAppRansomwareResilience.json
new file mode 100644
index 00000000000..f7a2190ce85
--- /dev/null
+++ b/Solutions/NetApp Ransomware Resilience/Data/Solution_NetAppRansomwareResilience.json
@@ -0,0 +1,20 @@
+{
+ "Name": "NetApp Ransomware Resilience",
+ "Author": "NetApp - support@netapp.com",
+ "Title": "NetApp Ransomware Resilience",
+ "Logo": "",
+ "Description": "NetApp Ransomware Resilience - Comprehensive security solution for detecting and responding to ransomware threats across NetApp storage environments.",
+ "Playbooks": [
+ "Playbooks/NetApp-RansomwareResilience-Auth-Playbook/azuredeploy.json",
+ "Playbooks/NetApp-RansomwareResilience_Volume_Offline_Playbook/azuredeploy.json",
+ "Playbooks/NetApp-RansomwareResilience_Async_Poll_Playbook/azuredeploy.json",
+ "Playbooks/NetApp-RansomwareResilience_Volume_Snapshot_Playbook/azuredeploy.json",
+ "Playbooks/NetApp-RansomwareResilience_Enrich_StorageVM_Playbook/azuredeploy.json",
+ "Playbooks/NetApp-RansomwareResilience_Enrich_IP_Playbook/azuredeploy.json"
+ ],
+ "Version": "3.0.0",
+ "BasePath": "C:\\GitHub\\Azure-Sentinel\\solutions\\NetApp Ransomware Resilience",
+ "Metadata": "SolutionMetadata.json",
+ "TemplateSpec": true,
+ "StaticDataConnectorIds": []
+}
\ No newline at end of file
diff --git a/Solutions/NetApp Ransomware Resilience/Package/3.0.0.zip b/Solutions/NetApp Ransomware Resilience/Package/3.0.0.zip
new file mode 100644
index 00000000000..b1ae890f256
Binary files /dev/null and b/Solutions/NetApp Ransomware Resilience/Package/3.0.0.zip differ
diff --git a/Solutions/NetApp Ransomware Resilience/Package/createUiDefinition.json b/Solutions/NetApp Ransomware Resilience/Package/createUiDefinition.json
new file mode 100644
index 00000000000..dc29e9aa6f1
--- /dev/null
+++ b/Solutions/NetApp Ransomware Resilience/Package/createUiDefinition.json
@@ -0,0 +1,89 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#",
+ "handler": "Microsoft.Azure.CreateUIDef",
+ "version": "0.1.2-preview",
+ "parameters": {
+ "config": {
+ "isWizard": false,
+ "basics": {
+ "description": "
\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/NetApp%20Ransomware%20Resilience/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nNetApp Ransomware Resilience - Comprehensive security solution for detecting and responding to ransomware threats across NetApp storage environments.\n\n**Playbooks:** 6\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)",
+ "subscription": {
+ "resourceProviders": [
+ "Microsoft.OperationsManagement/solutions",
+ "Microsoft.OperationalInsights/workspaces/providers/alertRules",
+ "Microsoft.Insights/workbooks",
+ "Microsoft.Logic/workflows"
+ ]
+ },
+ "location": {
+ "metadata": {
+ "hidden": "Hiding location, we get it from the log analytics workspace"
+ },
+ "visible": false
+ },
+ "resourceGroup": {
+ "allowExisting": true
+ }
+ }
+ },
+ "basics": [
+ {
+ "name": "getLAWorkspace",
+ "type": "Microsoft.Solutions.ArmApiControl",
+ "toolTip": "This filters by workspaces that exist in the Resource Group selected",
+ "condition": "[greater(length(resourceGroup().name),0)]",
+ "request": {
+ "method": "GET",
+ "path": "[concat(subscription().id,'/providers/Microsoft.OperationalInsights/workspaces?api-version=2020-08-01')]"
+ }
+ },
+ {
+ "name": "workspace",
+ "type": "Microsoft.Common.DropDown",
+ "label": "Workspace",
+ "placeholder": "Select a workspace",
+ "toolTip": "This dropdown will list only workspace that exists in the Resource Group selected",
+ "constraints": {
+ "allowedValues": "[map(filter(basics('getLAWorkspace').value, (filter) => contains(toLower(filter.id), toLower(resourceGroup().name))), (item) => parse(concat('{\"label\":\"', item.name, '\",\"value\":\"', item.name, '\"}')))]",
+ "required": true
+ },
+ "visible": true
+ }
+ ],
+ "steps": [
+ {
+ "name": "playbooks",
+ "label": "Playbooks",
+ "subLabel": {
+ "preValidation": "Configure the playbooks",
+ "postValidation": "Done"
+ },
+ "bladeTitle": "Playbooks",
+ "elements": [
+ {
+ "name": "playbooks-text",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "text": "This solution installs the Playbook templates to help implement your Security Orchestration, Automation and Response (SOAR) operations. After installing the solution, these will be deployed under Playbook Templates in the Automation blade in Microsoft Sentinel. They can be configured and managed from the Manage solution view in Content Hub."
+ }
+ },
+ {
+ "name": "playbooks-link",
+ "type": "Microsoft.Common.TextBlock",
+ "options": {
+ "link": {
+ "label": "Learn more",
+ "uri": "https://docs.microsoft.com/azure/sentinel/tutorial-respond-threats-playbook?WT.mc_id=Portal-Microsoft_Azure_CreateUIDef"
+ }
+ }
+ }
+ ]
+ }
+ ],
+ "outputs": {
+ "workspace-location": "[first(map(filter(basics('getLAWorkspace').value, (filter) => and(contains(toLower(filter.id), toLower(resourceGroup().name)),equals(filter.name,basics('workspace')))), (item) => item.location))]",
+ "location": "[location()]",
+ "workspace": "[basics('workspace')]"
+ }
+ }
+}
diff --git a/Solutions/NetApp Ransomware Resilience/Package/mainTemplate.json b/Solutions/NetApp Ransomware Resilience/Package/mainTemplate.json
new file mode 100644
index 00000000000..7071525f549
--- /dev/null
+++ b/Solutions/NetApp Ransomware Resilience/Package/mainTemplate.json
@@ -0,0 +1,3143 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "metadata": {
+ "author": "NetApp - support@netapp.com",
+ "comments": "Solution template for NetApp Ransomware Resilience"
+ },
+ "parameters": {
+ "location": {
+ "type": "string",
+ "minLength": 1,
+ "defaultValue": "[resourceGroup().location]",
+ "metadata": {
+ "description": "Not used, but needed to pass arm-ttk test `Location-Should-Not-Be-Hardcoded`. We instead use the `workspace-location` which is derived from the LA workspace"
+ }
+ },
+ "workspace-location": {
+ "type": "string",
+ "defaultValue": "",
+ "metadata": {
+ "description": "[concat('Region to deploy solution resources -- separate from location selection',parameters('location'))]"
+ }
+ },
+ "workspace": {
+ "defaultValue": "",
+ "type": "string",
+ "metadata": {
+ "description": "Workspace name for Log Analytics where Microsoft Sentinel is setup"
+ }
+ }
+ },
+ "variables": {
+ "email": "support@netapp.com",
+ "_email": "[variables('email')]",
+ "_solutionName": "NetApp Ransomware Resilience",
+ "_solutionVersion": "3.0.0",
+ "solutionId": "netapp1234567890.azure-sentinel-solution-netapprrs",
+ "_solutionId": "[variables('solutionId')]",
+ "NetApp-RansomwareResilience-Auth-Playbook": "NetApp-RansomwareResilience-Auth-Playbook",
+ "_NetApp-RansomwareResilience-Auth-Playbook": "[variables('NetApp-RansomwareResilience-Auth-Playbook')]",
+ "TemplateEmptyArray": "[json('[]')]",
+ "playbookVersion1": "1.0",
+ "playbookContentId1": "NetApp-RansomwareResilience-Auth-Playbook",
+ "_playbookContentId1": "[variables('playbookContentId1')]",
+ "playbookId1": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId1'))]",
+ "playbookTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId1'))))]",
+ "workspaceResourceId": "[resourceId('microsoft.OperationalInsights/Workspaces', parameters('workspace'))]",
+ "_playbookcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId1'),'-', variables('playbookVersion1'))))]",
+ "blanks": "[replace('b', 'b', '')]",
+ "NetApp-RansomwareResilience_Volume_Offline_Playbook": "NetApp-RansomwareResilience_Volume_Offline_Playbook",
+ "_NetApp-RansomwareResilience_Volume_Offline_Playbook": "[variables('NetApp-RansomwareResilience_Volume_Offline_Playbook')]",
+ "TemplateEmptyObject": "[json('{}')]",
+ "playbookVersion2": "1.0",
+ "playbookContentId2": "NetApp-RansomwareResilience_Volume_Offline_Playbook",
+ "_playbookContentId2": "[variables('playbookContentId2')]",
+ "playbookId2": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId2'))]",
+ "playbookTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId2'))))]",
+ "_playbookcontentProductId2": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId2'),'-', variables('playbookVersion2'))))]",
+ "NetApp-RansomwareResilience_Async_Poll_Playbook": "NetApp-RansomwareResilience_Async_Poll_Playbook",
+ "_NetApp-RansomwareResilience_Async_Poll_Playbook": "[variables('NetApp-RansomwareResilience_Async_Poll_Playbook')]",
+ "playbookVersion3": "1.0",
+ "playbookContentId3": "NetApp-RansomwareResilience_Async_Poll_Playbook",
+ "_playbookContentId3": "[variables('playbookContentId3')]",
+ "playbookId3": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId3'))]",
+ "playbookTemplateSpecName3": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId3'))))]",
+ "_playbookcontentProductId3": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId3'),'-', variables('playbookVersion3'))))]",
+ "NetApp-RansomwareResilience_Volume_Snapshot_Playbook": "NetApp-RansomwareResilience_Volume_Snapshot_Playbook",
+ "_NetApp-RansomwareResilience_Volume_Snapshot_Playbook": "[variables('NetApp-RansomwareResilience_Volume_Snapshot_Playbook')]",
+ "playbookVersion4": "1.0",
+ "playbookContentId4": "NetApp-RansomwareResilience_Volume_Snapshot_Playbook",
+ "_playbookContentId4": "[variables('playbookContentId4')]",
+ "playbookId4": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId4'))]",
+ "playbookTemplateSpecName4": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId4'))))]",
+ "_playbookcontentProductId4": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId4'),'-', variables('playbookVersion4'))))]",
+ "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook": "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook",
+ "_NetApp-RansomwareResilience_Enrich_StorageVM_Playbook": "[variables('NetApp-RansomwareResilience_Enrich_StorageVM_Playbook')]",
+ "playbookVersion5": "1.0",
+ "playbookContentId5": "NetApp-RansomwareResilience_Enrich_StorageVM_Playbook",
+ "_playbookContentId5": "[variables('playbookContentId5')]",
+ "playbookId5": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId5'))]",
+ "playbookTemplateSpecName5": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId5'))))]",
+ "_playbookcontentProductId5": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId5'),'-', variables('playbookVersion5'))))]",
+ "NetApp-RansomwareResilience_Enrich_IP_Playbook": "NetApp-RansomwareResilience_Enrich_IP_Playbook",
+ "_NetApp-RansomwareResilience_Enrich_IP_Playbook": "[variables('NetApp-RansomwareResilience_Enrich_IP_Playbook')]",
+ "playbookVersion6": "1.0",
+ "playbookContentId6": "NetApp-RansomwareResilience_Enrich_IP_Playbook",
+ "_playbookContentId6": "[variables('playbookContentId6')]",
+ "playbookId6": "[resourceId('Microsoft.Logic/workflows', variables('playbookContentId6'))]",
+ "playbookTemplateSpecName6": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pl-',uniquestring(variables('_playbookContentId6'))))]",
+ "_playbookcontentProductId6": "[concat(take(variables('_solutionId'),50),'-','pl','-', uniqueString(concat(variables('_solutionId'),'-','Playbook','-',variables('_playbookContentId6'),'-', variables('playbookVersion6'))))]",
+ "_solutioncontentProductId": "[concat(take(variables('_solutionId'),50),'-','sl','-', uniqueString(concat(variables('_solutionId'),'-','Solution','-',variables('_solutionId'),'-', variables('_solutionVersion'))))]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('playbookTemplateSpecName1')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "NetApp-RansomwareResilience-Auth Playbook with template version 3.0.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('playbookVersion1')]",
+ "parameters": {
+ "PlaybookName": {
+ "type": "String",
+ "defaultValue": "NetApp-RansomwareResilience-Auth",
+ "metadata": {
+ "description": "Name of the Logic App playbook to be created"
+ }
+ },
+ "KeyVaultName": {
+ "type": "String",
+ "defaultValue": "[concat('RRSkv', uniqueString(resourceGroup().id))]",
+ "metadata": {
+ "description": "Name of the shared Key Vault to store NetApp Ransomware Resilience credentials"
+ }
+ },
+ "location": {
+ "type": "string",
+ "defaultValue": "[parameters('location')]",
+ "metadata": {
+ "description": "Location for all resources"
+ }
+ },
+ "ClientId": {
+ "type": "securestring",
+ "metadata": {
+ "description": "Client ID for NetApp Ransomware Resilience API authentication"
+ }
+ },
+ "ClientSecret": {
+ "type": "securestring",
+ "metadata": {
+ "description": "Client Secret for NetApp Ransomware Resilience API authentication"
+ }
+ },
+ "AccountId": {
+ "type": "securestring",
+ "metadata": {
+ "description": "Account ID for NetApp Ransomware Resilience API authentication"
+ }
+ }
+ },
+ "variables": {
+ "KeyVaultConnectionName": "[[concat('keyvault-', parameters('PlaybookName'))]",
+ "connection-5": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', parameters('location'), '/managedApis/keyvault')]",
+ "_connection-5": "[[variables('connection-5')]",
+ "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]",
+ "workspace-name": "[parameters('workspace')]",
+ "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.KeyVault/vaults",
+ "apiVersion": "2023-07-01",
+ "name": "[[parameters('KeyVaultName')]",
+ "location": "[[parameters('location')]",
+ "properties": {
+ "sku": {
+ "family": "A",
+ "name": "standard"
+ },
+ "tenantId": "[[subscription().tenantId]",
+ "enabledForDeployment": false,
+ "enabledForDiskEncryption": false,
+ "enabledForTemplateDeployment": true,
+ "enableSoftDelete": true,
+ "softDeleteRetentionInDays": 90,
+ "enableRbacAuthorization": false,
+ "accessPolicies": "[variables('TemplateEmptyArray')]"
+ }
+ },
+ {
+ "type": "Microsoft.KeyVault/vaults/secrets",
+ "apiVersion": "2019-09-01",
+ "name": "[[concat(parameters('KeyVaultName'), '/client-id')]",
+ "dependsOn": [
+ "[[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]"
+ ],
+ "properties": {
+ "value": "[[parameters('ClientId')]"
+ }
+ },
+ {
+ "type": "Microsoft.KeyVault/vaults/secrets",
+ "apiVersion": "2019-09-01",
+ "name": "[[concat(parameters('KeyVaultName'), '/client-secret')]",
+ "dependsOn": [
+ "[[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]"
+ ],
+ "properties": {
+ "value": "[[parameters('ClientSecret')]"
+ }
+ },
+ {
+ "type": "Microsoft.KeyVault/vaults/secrets",
+ "apiVersion": "2019-09-01",
+ "name": "[[concat(parameters('KeyVaultName'), '/account-id')]",
+ "dependsOn": [
+ "[[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]"
+ ],
+ "properties": {
+ "value": "[[parameters('AccountId')]"
+ }
+ },
+ {
+ "type": "Microsoft.Web/connections",
+ "apiVersion": "2016-06-01",
+ "name": "[[variables('KeyVaultConnectionName')]",
+ "location": "[[parameters('location')]",
+ "kind": "V1",
+ "dependsOn": [
+ "[[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]"
+ ],
+ "properties": {
+ "displayName": "[[variables('KeyVaultConnectionName')]",
+ "parameterValueSet": {
+ "name": "oauthMI",
+ "values": {
+ "vaultName": {
+ "value": "[[parameters('KeyVaultName')]"
+ }
+ }
+ },
+ "api": {
+ "id": "[[variables('_connection-5')]"
+ }
+ }
+ },
+ {
+ "type": "Microsoft.Logic/workflows",
+ "apiVersion": "2019-05-01",
+ "name": "[[parameters('PlaybookName')]",
+ "location": "[[parameters('location')]",
+ "dependsOn": [
+ "[[resourceId('Microsoft.Web/connections', variables('KeyVaultConnectionName'))]",
+ "[[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]"
+ ],
+ "identity": {
+ "type": "SystemAssigned"
+ },
+ "properties": {
+ "state": "Enabled",
+ "definition": {
+ "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "$connections": {
+ "type": "Object"
+ }
+ },
+ "triggers": {
+ "manual": {
+ "type": "Request",
+ "kind": "Http",
+ "inputs": {
+ "schema": {
+ "properties": {
+ "account_id": {
+ "type": "string"
+ },
+ "api_hostname": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ }
+ }
+ }
+ },
+ "actions": {
+ "Get_Client_ID": {
+ "type": "ApiConnection",
+ "inputs": {
+ "host": {
+ "connection": {
+ "name": "@parameters('$connections')['keyvault']['connectionId']"
+ }
+ },
+ "method": "get",
+ "path": "/secrets/@{encodeURIComponent('client-id')}/value"
+ }
+ },
+ "Get_Client_Secret": {
+ "runAfter": {
+ "Get_Client_ID": [
+ "Succeeded"
+ ]
+ },
+ "type": "ApiConnection",
+ "inputs": {
+ "host": {
+ "connection": {
+ "name": "@parameters('$connections')['keyvault']['connectionId']"
+ }
+ },
+ "method": "get",
+ "path": "/secrets/@{encodeURIComponent('client-secret')}/value"
+ }
+ },
+ "Get_Account_ID": {
+ "runAfter": {
+ "Get_Client_Secret": [
+ "Succeeded"
+ ]
+ },
+ "type": "ApiConnection",
+ "inputs": {
+ "host": {
+ "connection": {
+ "name": "@parameters('$connections')['keyvault']['connectionId']"
+ }
+ },
+ "method": "get",
+ "path": "/secrets/@{encodeURIComponent('account-id')}/value"
+ }
+ },
+ "HTTP_Token_Request": {
+ "runAfter": {
+ "Get_Account_ID": [
+ "Succeeded"
+ ]
+ },
+ "type": "Http",
+ "inputs": {
+ "method": "POST",
+ "uri": "https://netapp-cloud-account.auth0.com/oauth/token",
+ "headers": {
+ "Content-Type": "application/x-www-form-urlencoded"
+ },
+ "body": "grant_type=client_credentials&client_id=@{body('Get_Client_ID')?['value']}&client_secret=@{body('Get_Client_Secret')?['value']}&audience=https://api.cloud.netapp.com"
+ }
+ },
+ "Response": {
+ "runAfter": {
+ "HTTP_Token_Request": [
+ "Succeeded"
+ ]
+ },
+ "type": "Response",
+ "kind": "Http",
+ "inputs": {
+ "statusCode": 200,
+ "headers": {
+ "Content-Type": "application/json"
+ },
+ "body": {
+ "access_token": "@{body('HTTP_Token_Request')?['access_token']}",
+ "token_type": "@{body('HTTP_Token_Request')?['token_type']}",
+ "expires_in": "@{body('HTTP_Token_Request')?['expires_in']}",
+ "account_id": "@{body('Get_Account_ID')?['value']}"
+ }
+ }
+ }
+ }
+ },
+ "parameters": {
+ "$connections": {
+ "value": {
+ "keyvault": {
+ "connectionId": "[[resourceId('Microsoft.Web/connections', variables('KeyVaultConnectionName'))]",
+ "connectionName": "[[variables('KeyVaultConnectionName')]",
+ "connectionProperties": {
+ "authentication": {
+ "type": "ManagedServiceIdentity"
+ }
+ },
+ "id": "[[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Web/locations/', parameters('location'), '/managedApis/keyvault')]"
+ }
+ }
+ }
+ }
+ },
+ "tags": {
+ "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]"
+ }
+ },
+ {
+ "type": "Microsoft.KeyVault/vaults/accessPolicies",
+ "apiVersion": "2019-09-01",
+ "name": "[[concat(parameters('KeyVaultName'), '/add')]",
+ "dependsOn": [
+ "[[resourceId('Microsoft.Logic/workflows', parameters('PlaybookName'))]",
+ "[[resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName'))]"
+ ],
+ "properties": {
+ "accessPolicies": [
+ {
+ "tenantId": "[[subscription().tenantId]",
+ "objectId": "[[reference(resourceId('Microsoft.Logic/workflows', parameters('PlaybookName')), '2019-05-01', 'Full').identity.principalId]",
+ "permissions": {
+ "secrets": [
+ "get"
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId1'),'/'))))]",
+ "properties": {
+ "parentId": "[variables('playbookId1')]",
+ "contentId": "[variables('_playbookContentId1')]",
+ "kind": "Playbook",
+ "version": "[variables('playbookVersion1')]",
+ "source": {
+ "kind": "Solution",
+ "name": "NetApp Ransomware Resilience",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "NetApp",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "NetApp",
+ "email": "support@netapp.com",
+ "tier": "Partner",
+ "link": "https://support.netapp.com"
+ }
+ }
+ }
+ ],
+ "metadata": {
+ "title": "NetApp Ransomware Resilience Authentication Playbook",
+ "description": "This playbook creates a shared Key Vault for NetApp Ransomware Resilience credentials and provides authentication services to all NetApp Ransomware Resilience playbooks in the solution.",
+ "prerequisites": [
+ "1. Valid client_id, client_secret, and account_id for NetApp Ransomware Resilience API authentication",
+ "2. API endpoint that accepts OAuth2 client credentials flow"
+ ],
+ "postDeployment": [
+ "1. Update the client_id, client_secret, and account_id values in the Key Vault",
+ "2. Test the Logic App to ensure proper token retrieval",
+ "3. The Key Vault created by this playbook will be shared across all NetApp Ransomware Resilience playbooks",
+ "4. Other playbooks will call this Auth playbook to obtain authentication tokens"
+ ],
+ "lastUpdateTime": "2025-09-17T00:00:00Z",
+ "tags": [
+ "NetApp",
+ "RansomwareResilience",
+ "Playbook",
+ "Authentication"
+ ],
+ "releaseNotes": {
+ "version": "1.0",
+ "title": "[variables('blanks')]",
+ "notes": [
+ "Initial version"
+ ]
+ }
+ }
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_playbookContentId1')]",
+ "contentKind": "Playbook",
+ "displayName": "NetApp-RansomwareResilience-Auth",
+ "contentProductId": "[variables('_playbookcontentProductId1')]",
+ "id": "[variables('_playbookcontentProductId1')]",
+ "version": "[variables('playbookVersion1')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('playbookTemplateSpecName2')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "NetApp-RansomwareResilience-Volume-Offline Playbook with template version 3.0.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('playbookVersion2')]",
+ "parameters": {
+ "PlaybookName": {
+ "type": "String",
+ "defaultValue": "NetApp-RansomwareResilience-Volume-Offline",
+ "metadata": {
+ "description": "Name of the Logic App/Playbook"
+ }
+ },
+ "NetAppRansomwareResilienceAuthPlaybookName": {
+ "type": "String",
+ "defaultValue": "NetApp-RansomwareResilience-Auth",
+ "metadata": {
+ "description": "Name of the NetApp Ransomware Resilience authentication playbook"
+ }
+ },
+ "NetAppRansomwareResilienceAsyncPollPlaybookName": {
+ "type": "String",
+ "defaultValue": "NetApp-RansomwareResilience-Async-Poll",
+ "metadata": {
+ "description": "Name of the NetApp Ransomware Resilience async poll playbook"
+ }
+ },
+ "location": {
+ "type": "string",
+ "defaultValue": "[parameters('location')]",
+ "metadata": {
+ "description": "Location for all resources"
+ }
+ }
+ },
+ "variables": {
+ "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]",
+ "workspace-name": "[parameters('workspace')]",
+ "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Logic/workflows",
+ "apiVersion": "2019-05-01",
+ "name": "[[parameters('PlaybookName')]",
+ "location": "[[parameters('location')]",
+ "identity": {
+ "type": "SystemAssigned"
+ },
+ "properties": {
+ "state": "Enabled",
+ "definition": {
+ "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "authPlaybookName": {
+ "defaultValue": "[[parameters('NetAppRansomwareResilienceAuthPlaybookName')]",
+ "type": "String"
+ },
+ "asyncPollPlaybookName": {
+ "defaultValue": "[[parameters('NetAppRansomwareResilienceAsyncPollPlaybookName')]",
+ "type": "String"
+ }
+ },
+ "triggers": {
+ "manual": {
+ "type": "Request",
+ "kind": "Http",
+ "inputs": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "volume_id": {
+ "type": "string"
+ },
+ "agent_id": {
+ "type": "string"
+ },
+ "system_id": {
+ "type": "string"
+ },
+ "callbackData": {
+ "type": "object"
+ },
+ "poll": {
+ "type": "boolean"
+ }
+ },
+ "required": [
+ "volume_id",
+ "agent_id",
+ "system_id"
+ ]
+ }
+ }
+ }
+ },
+ "actions": {
+ "Initialize_Variables": {
+ "type": "InitializeVariable",
+ "inputs": {
+ "variables": [
+ {
+ "name": "VolumeId",
+ "type": "string",
+ "value": "@triggerBody()?['volume_id']"
+ },
+ {
+ "name": "AgentId",
+ "type": "string",
+ "value": "@triggerBody()?['agent_id']"
+ },
+ {
+ "name": "SystemId",
+ "type": "string",
+ "value": "@triggerBody()?['system_id']"
+ },
+ {
+ "name": "CallbackData",
+ "type": "object",
+ "value": "@triggerBody()?['callbackData']"
+ },
+ {
+ "name": "AccountId",
+ "type": "string"
+ },
+ {
+ "name": "DoPoll",
+ "type": "boolean",
+ "value": "@coalesce(triggerBody()?['poll'], true)"
+ },
+ {
+ "name": "Token",
+ "type": "string"
+ },
+ {
+ "name": "JobId",
+ "type": "string"
+ },
+ {
+ "name": "JobAgentId",
+ "type": "string"
+ },
+ {
+ "name": "PollResponse",
+ "type": "object",
+ "value": "[variables('TemplateEmptyObject')]"
+ },
+ {
+ "name": "SubmissionStatusCode",
+ "type": "integer",
+ "value": 0
+ }
+ ]
+ }
+ },
+ "Call_Auth_Playbook": {
+ "runAfter": {
+ "Initialize_Variables": [
+ "Succeeded"
+ ]
+ },
+ "type": "Http",
+ "inputs": {
+ "method": "POST",
+ "uri": "[[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('NetAppRansomwareResilienceAuthPlaybookName'), 'manual'), '2019-05-01').value]",
+ "headers": {
+ "Content-Type": "application/json"
+ },
+ "body": {
+ "caller_info": {
+ "playbook_name": "@workflow().name",
+ "correlation_id": "@workflow().run.name",
+ "request_id": "@guid()"
+ }
+ },
+ "retryPolicy": {
+ "type": "exponential",
+ "count": 3,
+ "interval": "PT5S",
+ "minimumInterval": "PT5S",
+ "maximumInterval": "PT30S"
+ }
+ }
+ },
+ "Parse_Auth_Response": {
+ "runAfter": {
+ "Call_Auth_Playbook": [
+ "Succeeded"
+ ]
+ },
+ "type": "ParseJson",
+ "inputs": {
+ "content": "@body('Call_Auth_Playbook')",
+ "schema": {
+ "type": "object",
+ "properties": {
+ "access_token": {
+ "type": "string"
+ },
+ "account_id": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "access_token",
+ "account_id"
+ ]
+ }
+ }
+ },
+ "Set_Token": {
+ "runAfter": {
+ "Parse_Auth_Response": [
+ "Succeeded"
+ ]
+ },
+ "type": "SetVariable",
+ "inputs": {
+ "name": "Token",
+ "value": "@body('Parse_Auth_Response')?['access_token']"
+ }
+ },
+ "Set_Account_ID": {
+ "runAfter": {
+ "Set_Token": [
+ "Succeeded"
+ ]
+ },
+ "type": "SetVariable",
+ "inputs": {
+ "name": "AccountId",
+ "value": "@body('Parse_Auth_Response')?['account_id']"
+ }
+ },
+ "Submit_Volume_Offline": {
+ "runAfter": {
+ "Set_Account_ID": [
+ "Succeeded"
+ ]
+ },
+ "type": "Http",
+ "inputs": {
+ "method": "POST",
+ "uri": "https://api.bluexp.netapp.com/v1/services/rps/v1/account/@{variables('AccountId')}/storage/take-volume-offline",
+ "headers": {
+ "Authorization": "Bearer @{variables('Token')}",
+ "Content-Type": "application/json",
+ "accept": "application/json"
+ },
+ "body": {
+ "volume_id": "@variables('VolumeId')",
+ "agent_id": "@variables('AgentId')",
+ "system_id": "@variables('SystemId')"
+ },
+ "retryPolicy": {
+ "type": "exponential",
+ "count": 3,
+ "interval": "PT5S",
+ "minimumInterval": "PT5S",
+ "maximumInterval": "PT30S"
+ }
+ }
+ },
+ "Capture_Submission_Status_Code": {
+ "runAfter": {
+ "Submit_Volume_Offline": [
+ "Succeeded",
+ "Failed"
+ ]
+ },
+ "type": "SetVariable",
+ "inputs": {
+ "name": "SubmissionStatusCode",
+ "value": "@outputs('Submit_Volume_Offline')['statusCode']"
+ }
+ },
+ "Parse_Submission_Response": {
+ "runAfter": {
+ "Capture_Submission_Status_Code": [
+ "Succeeded"
+ ]
+ },
+ "type": "ParseJson",
+ "inputs": {
+ "content": "@body('Submit_Volume_Offline')",
+ "schema": {
+ "type": "object",
+ "properties": {
+ "job_id": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ },
+ "agent_id": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "Store_JobId": {
+ "runAfter": {
+ "Parse_Submission_Response": [
+ "Succeeded"
+ ]
+ },
+ "type": "SetVariable",
+ "inputs": {
+ "name": "JobId",
+ "value": "@body('Parse_Submission_Response')?['job_id']"
+ }
+ },
+ "Store_Job_AgentId": {
+ "runAfter": {
+ "Store_JobId": [
+ "Succeeded"
+ ]
+ },
+ "type": "SetVariable",
+ "inputs": {
+ "name": "JobAgentId",
+ "value": "@body('Parse_Submission_Response')?['agent_id']"
+ }
+ },
+ "Check_If_Should_Poll": {
+ "runAfter": {
+ "Store_Job_AgentId": [
+ "Succeeded"
+ ]
+ },
+ "type": "If",
+ "expression": {
+ "and": [
+ {
+ "equals": [
+ "@variables('DoPoll')",
+ true
+ ]
+ },
+ {
+ "or": [
+ {
+ "equals": [
+ "@variables('SubmissionStatusCode')",
+ 200
+ ]
+ },
+ {
+ "equals": [
+ "@variables('SubmissionStatusCode')",
+ 201
+ ]
+ },
+ {
+ "equals": [
+ "@variables('SubmissionStatusCode')",
+ 202
+ ]
+ }
+ ]
+ },
+ {
+ "not": {
+ "equals": [
+ "@variables('JobId')",
+ ""
+ ]
+ }
+ }
+ ]
+ },
+ "actions": {
+ "Call_Async_Poll_Playbook": {
+ "type": "Http",
+ "inputs": {
+ "method": "POST",
+ "uri": "[[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName'), 'manual'), '2019-05-01').value]",
+ "headers": {
+ "Content-Type": "application/json"
+ },
+ "body": {
+ "job_id": "@variables('JobId')",
+ "agent_id": "@variables('JobAgentId')",
+ "system_id": "@variables('SystemId')",
+ "source": "ontap",
+ "caller_info": {
+ "playbook_name": "@workflow().name",
+ "correlation_id": "@workflow().run.name",
+ "original_volume_id": "@variables('VolumeId')"
+ }
+ },
+ "retryPolicy": {
+ "type": "exponential",
+ "count": 3,
+ "interval": "PT5S",
+ "minimumInterval": "PT5S",
+ "maximumInterval": "PT30S"
+ }
+ }
+ }
+ }
+ },
+ "Parse_Poll_Response": {
+ "runAfter": {
+ "Check_If_Should_Poll": [
+ "Succeeded"
+ ]
+ },
+ "type": "Compose",
+ "inputs": "@if(equals(actions('Call_Async_Poll_Playbook')['status'], 'Succeeded'), body('Call_Async_Poll_Playbook'), json('{\"success\": false, \"status\": \"FAILED\", \"error\": \"Poll playbook failed or timed out\"}'))"
+ },
+ "Store_Poll_Response": {
+ "runAfter": {
+ "Parse_Poll_Response": [
+ "Succeeded"
+ ]
+ },
+ "type": "SetVariable",
+ "inputs": {
+ "name": "PollResponse",
+ "value": "@outputs('Parse_Poll_Response')"
+ }
+ },
+ "Finalize_Execution": {
+ "runAfter": {
+ "Store_Poll_Response": [
+ "Succeeded",
+ "Skipped",
+ "Failed",
+ "TimedOut"
+ ],
+ "Check_If_Should_Poll": [
+ "Succeeded",
+ "Skipped",
+ "Failed",
+ "TimedOut"
+ ],
+ "Call_Auth_Playbook": [
+ "Failed",
+ "TimedOut"
+ ],
+ "Submit_Volume_Offline": [
+ "Failed",
+ "TimedOut"
+ ]
+ },
+ "type": "Compose",
+ "inputs": {
+ "execution_completed": true,
+ "timestamp": "@utcNow()"
+ }
+ },
+ "Return_Response": {
+ "runAfter": {
+ "Finalize_Execution": [
+ "Succeeded",
+ "Skipped",
+ "Failed",
+ "TimedOut"
+ ]
+ },
+ "type": "Response",
+ "kind": "Http",
+ "inputs": {
+ "statusCode": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 401, if(or(equals(actions('Submit_Volume_Offline')['status'], 'Failed'), equals(actions('Submit_Volume_Offline')['status'], 'TimedOut')), 500, if(or(equals(variables('SubmissionStatusCode'), 200), equals(variables('SubmissionStatusCode'), 201), equals(variables('SubmissionStatusCode'), 202)), 200, if(equals(variables('SubmissionStatusCode'), 0), 500, variables('SubmissionStatusCode')))))",
+ "headers": {
+ "Content-Type": "application/json"
+ },
+ "body": {
+ "success": "@and(not(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut'))), not(or(equals(actions('Submit_Volume_Offline')['status'], 'Failed'), equals(actions('Submit_Volume_Offline')['status'], 'TimedOut'))), or(equals(variables('SubmissionStatusCode'), 200), equals(variables('SubmissionStatusCode'), 201), equals(variables('SubmissionStatusCode'), 202)))",
+ "error": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'Authentication failed in auth playbook', if(or(equals(actions('Submit_Volume_Offline')['status'], 'Failed'), equals(actions('Submit_Volume_Offline')['status'], 'TimedOut')), 'Failed submitting volume offline request', null))",
+ "stage": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'auth', if(or(equals(actions('Submit_Volume_Offline')['status'], 'Failed'), equals(actions('Submit_Volume_Offline')['status'], 'TimedOut')), 'submit', 'success'))",
+ "submission": {
+ "statusCode": "@variables('SubmissionStatusCode')",
+ "jobId": "@variables('JobId')",
+ "raw": "@body('Submit_Volume_Offline')",
+ "details": "@if(or(equals(actions('Submit_Volume_Offline')['status'], 'Failed'), equals(actions('Submit_Volume_Offline')['status'], 'TimedOut')), body('Submit_Volume_Offline'), null)"
+ },
+ "polling": {
+ "invoked": "@and(variables('DoPoll'), not(empty(variables('JobId'))))",
+ "playbook": "@parameters('asyncPollPlaybookName')",
+ "jobFinalStatus": "@coalesce(variables('PollResponse')?['status'], 'unknown')",
+ "jobResponse": "@variables('PollResponse')"
+ },
+ "callbackData": "@variables('CallbackData')",
+ "timestamp": "@utcnow()"
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": {
+ "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId2'),'/'))))]",
+ "properties": {
+ "parentId": "[variables('playbookId2')]",
+ "contentId": "[variables('_playbookContentId2')]",
+ "kind": "Playbook",
+ "version": "[variables('playbookVersion2')]",
+ "source": {
+ "kind": "Solution",
+ "name": "NetApp Ransomware Resilience",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "NetApp",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "NetApp",
+ "email": "support@netapp.com",
+ "tier": "Partner",
+ "link": "https://support.netapp.com"
+ }
+ }
+ }
+ ],
+ "metadata": {
+ "title": "NetApp Ransomware Resilience Volume Offline Playbook",
+ "description": "This playbook takes a NetApp volume offline using the updated NetApp Ransomware Resilience take-volume-offline API endpoint and optionally polls for completion.",
+ "prerequisites": [
+ "1. NetApp Ransomware Resilience Auth Playbook must be deployed first and ensure that it is functioning correctly",
+ "2. NetApp Ransomware Resilience Async Poll Playbook must be deployed first and ensure that it is functioning correctly",
+ "3. Valid NetApp Ransomware Resilience API credentials configured in the Auth Playbook",
+ "4. Caller must provide volume_id, agent_id, and system_id parameters"
+ ],
+ "postDeployment": [
+ "1. Test the volume offline functionality with valid volume_id, agent_id, and system_id"
+ ],
+ "lastUpdateTime": "2025-09-17T00:00:00Z",
+ "tags": [
+ "NetApp",
+ "RansomwareResilience",
+ "Playbook",
+ "Volume",
+ "Offline"
+ ],
+ "releaseNotes": {
+ "version": "1.0",
+ "title": "[variables('blanks')]",
+ "notes": [
+ "Initial version"
+ ]
+ }
+ }
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_playbookContentId2')]",
+ "contentKind": "Playbook",
+ "displayName": "NetApp-RansomwareResilience-Volume-Offline",
+ "contentProductId": "[variables('_playbookcontentProductId2')]",
+ "id": "[variables('_playbookcontentProductId2')]",
+ "version": "[variables('playbookVersion2')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('playbookTemplateSpecName3')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "NetApp-RansomwareResilience-Async-Poll Playbook with template version 3.0.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('playbookVersion3')]",
+ "parameters": {
+ "PlaybookName": {
+ "type": "String",
+ "defaultValue": "NetApp-RansomwareResilience-Async-Poll",
+ "metadata": {
+ "description": "Name of the Logic App/Playbook"
+ }
+ },
+ "NetAppRansomwareResilienceAuthPlaybookName": {
+ "type": "String",
+ "defaultValue": "NetApp-RansomwareResilience-Auth",
+ "metadata": {
+ "description": "Name of the NetApp Ransomware Resilience authentication playbook"
+ }
+ },
+ "location": {
+ "type": "string",
+ "defaultValue": "[parameters('location')]",
+ "metadata": {
+ "description": "Location for all resources"
+ }
+ }
+ },
+ "variables": {
+ "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]",
+ "workspace-name": "[parameters('workspace')]",
+ "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Logic/workflows",
+ "apiVersion": "2019-05-01",
+ "name": "[[parameters('PlaybookName')]",
+ "location": "[[parameters('location')]",
+ "identity": {
+ "type": "SystemAssigned"
+ },
+ "properties": {
+ "state": "Enabled",
+ "definition": {
+ "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "authPlaybookName": {
+ "defaultValue": "[[parameters('NetAppRansomwareResilienceAuthPlaybookName')]",
+ "type": "String"
+ }
+ },
+ "triggers": {
+ "manual": {
+ "type": "Request",
+ "kind": "Http",
+ "inputs": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "job_id": {
+ "type": "string",
+ "description": "The NetApp Ransomware Resilience job ID to poll"
+ },
+ "agent_id": {
+ "type": "string",
+ "description": "NetApp Ransomware Resilience agent ID"
+ },
+ "system_id": {
+ "type": "string",
+ "description": "System ID for the working environment"
+ },
+ "source": {
+ "type": "string",
+ "description": "Job source type"
+ },
+ "caller_info": {
+ "type": "object",
+ "description": "Optional caller information for tracking"
+ }
+ },
+ "required": [
+ "job_id",
+ "agent_id",
+ "system_id",
+ "source"
+ ]
+ }
+ }
+ }
+ },
+ "actions": {
+ "Initialize_variables": {
+ "type": "InitializeVariable",
+ "inputs": {
+ "variables": [
+ {
+ "name": "JobId",
+ "type": "string",
+ "value": "@triggerBody()?['job_id']"
+ },
+ {
+ "name": "AgentId",
+ "type": "string",
+ "value": "@triggerBody()?['agent_id']"
+ },
+ {
+ "name": "SystemId",
+ "type": "string",
+ "value": "@triggerBody()?['system_id']"
+ },
+ {
+ "name": "Source",
+ "type": "string",
+ "value": "@triggerBody()?['source']"
+ },
+ {
+ "name": "AccountId",
+ "type": "string"
+ },
+ {
+ "name": "PollCount",
+ "type": "integer",
+ "value": 0
+ },
+ {
+ "name": "MaxPollAttempts",
+ "type": "integer",
+ "value": 10
+ },
+ {
+ "name": "PollIntervalSeconds",
+ "type": "integer",
+ "value": 30
+ },
+ {
+ "name": "JobStatus",
+ "type": "string",
+ "value": "pending"
+ },
+ {
+ "name": "JobResponse",
+ "type": "object",
+ "value": "[variables('TemplateEmptyObject')]"
+ }
+ ]
+ }
+ },
+ "Call_Auth_Playbook": {
+ "runAfter": {
+ "Initialize_variables": [
+ "Succeeded"
+ ]
+ },
+ "type": "Http",
+ "inputs": {
+ "method": "POST",
+ "uri": "[[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('NetAppRansomwareResilienceAuthPlaybookName'), 'manual'), '2019-05-01').value]",
+ "headers": {
+ "Content-Type": "application/json"
+ },
+ "body": {
+ "caller_info": {
+ "playbook_name": "@workflow().name",
+ "correlation_id": "@workflow().run.name",
+ "request_id": "@guid()"
+ }
+ }
+ }
+ },
+ "Set_Account_ID": {
+ "runAfter": {
+ "Call_Auth_Playbook": [
+ "Succeeded"
+ ]
+ },
+ "type": "SetVariable",
+ "inputs": {
+ "name": "AccountId",
+ "value": "@body('Call_Auth_Playbook')?['account_id']"
+ }
+ },
+ "Initial_Status_Check": {
+ "runAfter": {
+ "Set_Account_ID": [
+ "Succeeded"
+ ]
+ },
+ "type": "Http",
+ "inputs": {
+ "method": "GET",
+ "uri": "https://api.bluexp.netapp.com/v1/services/rps/v1/account/@{variables('AccountId')}/job/status?source=@{variables('Source')}&job_id=@{variables('JobId')}&agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}",
+ "headers": {
+ "Authorization": "Bearer @{body('Call_Auth_Playbook')?['access_token']}",
+ "accept": "application/json"
+ },
+ "retryPolicy": {
+ "type": "exponential",
+ "count": 2,
+ "interval": "PT5S",
+ "minimumInterval": "PT5S",
+ "maximumInterval": "PT10S"
+ },
+ "timeout": "PT30S"
+ }
+ },
+ "Update_Initial_Status": {
+ "runAfter": {
+ "Initial_Status_Check": [
+ "Succeeded"
+ ]
+ },
+ "type": "SetVariable",
+ "inputs": {
+ "name": "JobStatus",
+ "value": "@body('Initial_Status_Check')?['status']"
+ }
+ },
+ "Update_Initial_Response": {
+ "runAfter": {
+ "Update_Initial_Status": [
+ "Succeeded"
+ ]
+ },
+ "type": "SetVariable",
+ "inputs": {
+ "name": "JobResponse",
+ "value": "@body('Initial_Status_Check')"
+ }
+ },
+ "Polling_Loop": {
+ "runAfter": {
+ "Update_Initial_Response": [
+ "Succeeded"
+ ]
+ },
+ "type": "Until",
+ "expression": "@or(or(equals(variables('JobStatus'), 'SUCCESS'), equals(variables('JobStatus'), 'success')), or(equals(variables('JobStatus'), 'FAILED'), equals(variables('JobStatus'), 'failed')), greater(variables('PollCount'), variables('MaxPollAttempts')))",
+ "limit": {
+ "count": 10,
+ "timeout": "PT6M"
+ },
+ "actions": {
+ "Increment_Poll_Count": {
+ "type": "IncrementVariable",
+ "inputs": {
+ "name": "PollCount",
+ "value": 1
+ }
+ },
+ "Check_Job_Status": {
+ "runAfter": {
+ "Increment_Poll_Count": [
+ "Succeeded"
+ ]
+ },
+ "type": "Http",
+ "inputs": {
+ "method": "GET",
+ "uri": "https://api.bluexp.netapp.com/v1/services/rps/v1/account/@{variables('AccountId')}/job/status?source=@{variables('Source')}&job_id=@{variables('JobId')}&agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}",
+ "headers": {
+ "Authorization": "Bearer @{body('Call_Auth_Playbook')?['access_token']}",
+ "accept": "application/json"
+ },
+ "retryPolicy": {
+ "type": "exponential",
+ "count": 2,
+ "interval": "PT5S",
+ "minimumInterval": "PT5S",
+ "maximumInterval": "PT10S"
+ },
+ "timeout": "PT30S"
+ }
+ },
+ "Update_Job_Status": {
+ "runAfter": {
+ "Check_Job_Status": [
+ "Succeeded"
+ ]
+ },
+ "type": "SetVariable",
+ "inputs": {
+ "name": "JobStatus",
+ "value": "@body('Check_Job_Status')?['status']"
+ }
+ },
+ "Handle_Status_Check_Failure": {
+ "runAfter": {
+ "Check_Job_Status": [
+ "Failed",
+ "TimedOut"
+ ]
+ },
+ "type": "SetVariable",
+ "inputs": {
+ "name": "JobStatus",
+ "value": "failed"
+ }
+ },
+ "Update_Job_Response": {
+ "runAfter": {
+ "Update_Job_Status": [
+ "Succeeded"
+ ],
+ "Handle_Status_Check_Failure": [
+ "Succeeded"
+ ]
+ },
+ "type": "SetVariable",
+ "inputs": {
+ "name": "JobResponse",
+ "value": "@body('Check_Job_Status')"
+ }
+ },
+ "Wait_If_Needed": {
+ "runAfter": {
+ "Update_Job_Response": [
+ "Succeeded"
+ ]
+ },
+ "type": "If",
+ "expression": {
+ "not": {
+ "or": [
+ {
+ "equals": [
+ "@variables('JobStatus')",
+ "SUCCESS"
+ ]
+ },
+ {
+ "equals": [
+ "@variables('JobStatus')",
+ "success"
+ ]
+ }
+ ]
+ }
+ },
+ "actions": {
+ "Wait_Before_Retry": {
+ "type": "Wait",
+ "inputs": {
+ "interval": {
+ "count": "@variables('PollIntervalSeconds')",
+ "unit": "Second"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "Check_Final_Status": {
+ "runAfter": {
+ "Polling_Loop": [
+ "Succeeded"
+ ]
+ },
+ "type": "If",
+ "expression": {
+ "and": [
+ {
+ "or": [
+ {
+ "equals": [
+ "@variables('JobStatus')",
+ "SUCCESS"
+ ]
+ },
+ {
+ "equals": [
+ "@variables('JobStatus')",
+ "success"
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ "actions": {
+ "Success_Response": {
+ "type": "Response",
+ "kind": "Http",
+ "inputs": {
+ "statusCode": 200,
+ "headers": {
+ "Content-Type": "application/json"
+ },
+ "body": {
+ "success": true,
+ "job_id": "@variables('JobId')",
+ "status": "@variables('JobStatus')",
+ "poll_count": "@variables('PollCount')",
+ "data": "@variables('JobResponse')",
+ "caller_info": "@triggerBody()?['caller_info']"
+ }
+ }
+ }
+ },
+ "else": {
+ "actions": {
+ "Error_Response": {
+ "type": "Response",
+ "kind": "Http",
+ "inputs": {
+ "statusCode": 408,
+ "headers": {
+ "Content-Type": "application/json"
+ },
+ "body": {
+ "success": false,
+ "error": "Job polling timeout or failed",
+ "job_id": "@variables('JobId')",
+ "status": "@variables('JobStatus')",
+ "poll_count": "@variables('PollCount')",
+ "max_attempts": "@variables('MaxPollAttempts')",
+ "data": "@variables('JobResponse')",
+ "caller_info": "@triggerBody()?['caller_info']"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": {
+ "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId3'),'/'))))]",
+ "properties": {
+ "parentId": "[variables('playbookId3')]",
+ "contentId": "[variables('_playbookContentId3')]",
+ "kind": "Playbook",
+ "version": "[variables('playbookVersion3')]",
+ "source": {
+ "kind": "Solution",
+ "name": "NetApp Ransomware Resilience",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "NetApp",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "NetApp",
+ "email": "support@netapp.com",
+ "tier": "Partner",
+ "link": "https://support.netapp.com"
+ }
+ }
+ }
+ ],
+ "metadata": {
+ "title": "NetApp Ransomware Resilience Async Poll Playbook",
+ "description": "This playbook polls NetApp Ransomware Resilience job status asynchronously until completion or timeout using the updated job status API endpoint.",
+ "prerequisites": [
+ "1. NetApp Ransomware Resilience Auth Playbook must be deployed first and ensure that it is functioning correctly",
+ "2. Valid NetApp Ransomware Resilience API credentials configured in the Auth Playbook",
+ "3. Caller must provide job_id, agent_id, system_id, and source parameters"
+ ],
+ "postDeployment": [
+ "1. Test the playbook by triggering it with a valid job_id, agent_id, system_id, and source",
+ "2. Monitor the playbook run history to verify successful polling and completion"
+ ],
+ "lastUpdateTime": "2025-09-17T00:00:00Z",
+ "tags": [
+ "NetApp",
+ "RansomwareResilience",
+ "Playbook",
+ "Async",
+ "Polling"
+ ],
+ "releaseNotes": {
+ "version": "1.0",
+ "title": "[variables('blanks')]",
+ "notes": [
+ "Initial version"
+ ]
+ }
+ }
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_playbookContentId3')]",
+ "contentKind": "Playbook",
+ "displayName": "NetApp-RansomwareResilience-Async-Poll",
+ "contentProductId": "[variables('_playbookcontentProductId3')]",
+ "id": "[variables('_playbookcontentProductId3')]",
+ "version": "[variables('playbookVersion3')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('playbookTemplateSpecName4')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "NetApp-RansomwareResilience-Volume-Snapshot Playbook with template version 3.0.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('playbookVersion4')]",
+ "parameters": {
+ "PlaybookName": {
+ "type": "String",
+ "defaultValue": "NetApp-RansomwareResilience-Volume-Snapshot",
+ "metadata": {
+ "description": "Name of the Logic App/Playbook"
+ }
+ },
+ "NetAppRansomwareResilienceAuthPlaybookName": {
+ "type": "String",
+ "defaultValue": "NetApp-RansomwareResilience-Auth",
+ "metadata": {
+ "description": "Name of the NetApp Ransomware Resilience authentication playbook"
+ }
+ },
+ "NetAppRansomwareResilienceAsyncPollPlaybookName": {
+ "type": "String",
+ "defaultValue": "NetApp-RansomwareResilience-Async-Poll",
+ "metadata": {
+ "description": "Name of the NetApp Ransomware Resilience async poll playbook"
+ }
+ },
+ "location": {
+ "type": "string",
+ "defaultValue": "[parameters('location')]",
+ "metadata": {
+ "description": "Location for all resources"
+ }
+ }
+ },
+ "variables": {
+ "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]",
+ "workspace-name": "[parameters('workspace')]",
+ "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Logic/workflows",
+ "apiVersion": "2019-05-01",
+ "name": "[[parameters('PlaybookName')]",
+ "location": "[[parameters('location')]",
+ "identity": {
+ "type": "SystemAssigned"
+ },
+ "properties": {
+ "state": "Enabled",
+ "definition": {
+ "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "authPlaybookName": {
+ "defaultValue": "[[parameters('NetAppRansomwareResilienceAuthPlaybookName')]",
+ "type": "String"
+ },
+ "asyncPollPlaybookName": {
+ "defaultValue": "[[parameters('NetAppRansomwareResilienceAsyncPollPlaybookName')]",
+ "type": "String"
+ }
+ },
+ "triggers": {
+ "manual": {
+ "type": "Request",
+ "kind": "Http",
+ "inputs": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "volume_id": {
+ "type": "string"
+ },
+ "agent_id": {
+ "type": "string"
+ },
+ "system_id": {
+ "type": "string"
+ },
+ "callbackData": {
+ "type": "object"
+ },
+ "poll": {
+ "type": "boolean"
+ }
+ },
+ "required": [
+ "volume_id",
+ "agent_id",
+ "system_id"
+ ]
+ }
+ }
+ }
+ },
+ "actions": {
+ "Initialize_Variables": {
+ "type": "InitializeVariable",
+ "inputs": {
+ "variables": [
+ {
+ "name": "VolumeId",
+ "type": "string",
+ "value": "@triggerBody()?['volume_id']"
+ },
+ {
+ "name": "AgentId",
+ "type": "string",
+ "value": "@triggerBody()?['agent_id']"
+ },
+ {
+ "name": "SystemId",
+ "type": "string",
+ "value": "@triggerBody()?['system_id']"
+ },
+ {
+ "name": "CallbackData",
+ "type": "object",
+ "value": "@triggerBody()?['callbackData']"
+ },
+ {
+ "name": "AccountId",
+ "type": "string"
+ },
+ {
+ "name": "DoPoll",
+ "type": "boolean",
+ "value": "@coalesce(triggerBody()?['poll'], true)"
+ },
+ {
+ "name": "Token",
+ "type": "string"
+ },
+ {
+ "name": "JobId",
+ "type": "string"
+ },
+ {
+ "name": "JobAgentId",
+ "type": "string"
+ },
+ {
+ "name": "PollResponse",
+ "type": "object",
+ "value": "[variables('TemplateEmptyObject')]"
+ },
+ {
+ "name": "SubmissionStatusCode",
+ "type": "integer",
+ "value": 0
+ }
+ ]
+ }
+ },
+ "Call_Auth_Playbook": {
+ "runAfter": {
+ "Initialize_Variables": [
+ "Succeeded"
+ ]
+ },
+ "type": "Http",
+ "inputs": {
+ "method": "POST",
+ "uri": "[[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('NetAppRansomwareResilienceAuthPlaybookName'), 'manual'), '2019-05-01').value]",
+ "headers": {
+ "Content-Type": "application/json"
+ },
+ "body": {
+ "caller_info": {
+ "playbook_name": "@workflow().name",
+ "correlation_id": "@workflow().run.name",
+ "request_id": "@guid()"
+ }
+ },
+ "retryPolicy": {
+ "type": "exponential",
+ "count": 3,
+ "interval": "PT5S",
+ "minimumInterval": "PT5S",
+ "maximumInterval": "PT30S"
+ }
+ }
+ },
+ "Parse_Auth_Response": {
+ "runAfter": {
+ "Call_Auth_Playbook": [
+ "Succeeded"
+ ]
+ },
+ "type": "ParseJson",
+ "inputs": {
+ "content": "@body('Call_Auth_Playbook')",
+ "schema": {
+ "type": "object",
+ "properties": {
+ "access_token": {
+ "type": "string"
+ },
+ "account_id": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "access_token",
+ "account_id"
+ ]
+ }
+ }
+ },
+ "Set_Token": {
+ "runAfter": {
+ "Parse_Auth_Response": [
+ "Succeeded"
+ ]
+ },
+ "type": "SetVariable",
+ "inputs": {
+ "name": "Token",
+ "value": "@body('Parse_Auth_Response')?['access_token']"
+ }
+ },
+ "Set_Account_ID": {
+ "runAfter": {
+ "Set_Token": [
+ "Succeeded"
+ ]
+ },
+ "type": "SetVariable",
+ "inputs": {
+ "name": "AccountId",
+ "value": "@body('Parse_Auth_Response')?['account_id']"
+ }
+ },
+ "Submit_Volume_Snapshot": {
+ "runAfter": {
+ "Set_Account_ID": [
+ "Succeeded"
+ ]
+ },
+ "type": "Http",
+ "inputs": {
+ "method": "POST",
+ "uri": "https://api.bluexp.netapp.com/v1/services/rps/v1/account/@{variables('AccountId')}/storage/take-snapshot",
+ "headers": {
+ "Authorization": "Bearer @{variables('Token')}",
+ "Content-Type": "application/json",
+ "accept": "application/json"
+ },
+ "body": {
+ "volume_id": "@variables('VolumeId')",
+ "agent_id": "@variables('AgentId')",
+ "system_id": "@variables('SystemId')"
+ },
+ "retryPolicy": {
+ "type": "exponential",
+ "count": 3,
+ "interval": "PT5S",
+ "minimumInterval": "PT5S",
+ "maximumInterval": "PT30S"
+ }
+ }
+ },
+ "Capture_Submission_Status_Code": {
+ "runAfter": {
+ "Submit_Volume_Snapshot": [
+ "Succeeded",
+ "Failed"
+ ]
+ },
+ "type": "SetVariable",
+ "inputs": {
+ "name": "SubmissionStatusCode",
+ "value": "@outputs('Submit_Volume_Snapshot')['statusCode']"
+ }
+ },
+ "Parse_Submission_Response": {
+ "runAfter": {
+ "Capture_Submission_Status_Code": [
+ "Succeeded"
+ ]
+ },
+ "type": "ParseJson",
+ "inputs": {
+ "content": "@body('Submit_Volume_Snapshot')",
+ "schema": {
+ "type": "object",
+ "properties": {
+ "job_id": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ },
+ "agent_id": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "Store_JobId": {
+ "runAfter": {
+ "Parse_Submission_Response": [
+ "Succeeded"
+ ]
+ },
+ "type": "SetVariable",
+ "inputs": {
+ "name": "JobId",
+ "value": "@body('Parse_Submission_Response')?['job_id']"
+ }
+ },
+ "Store_Job_AgentId": {
+ "runAfter": {
+ "Store_JobId": [
+ "Succeeded"
+ ]
+ },
+ "type": "SetVariable",
+ "inputs": {
+ "name": "JobAgentId",
+ "value": "@body('Parse_Submission_Response')?['agent_id']"
+ }
+ },
+ "Check_If_Should_Poll": {
+ "runAfter": {
+ "Store_Job_AgentId": [
+ "Succeeded"
+ ]
+ },
+ "type": "If",
+ "expression": {
+ "and": [
+ {
+ "equals": [
+ "@variables('DoPoll')",
+ true
+ ]
+ },
+ {
+ "or": [
+ {
+ "equals": [
+ "@variables('SubmissionStatusCode')",
+ 200
+ ]
+ },
+ {
+ "equals": [
+ "@variables('SubmissionStatusCode')",
+ 201
+ ]
+ },
+ {
+ "equals": [
+ "@variables('SubmissionStatusCode')",
+ 202
+ ]
+ }
+ ]
+ },
+ {
+ "not": {
+ "equals": [
+ "@variables('JobId')",
+ ""
+ ]
+ }
+ }
+ ]
+ },
+ "actions": {
+ "Call_Async_Poll_Playbook": {
+ "type": "Http",
+ "inputs": {
+ "method": "POST",
+ "uri": "[[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName'), 'manual'), '2019-05-01').value]",
+ "headers": {
+ "Content-Type": "application/json"
+ },
+ "body": {
+ "job_id": "@variables('JobId')",
+ "agent_id": "@variables('JobAgentId')",
+ "system_id": "@variables('SystemId')",
+ "source": "ontap",
+ "caller_info": {
+ "playbook_name": "@workflow().name",
+ "correlation_id": "@workflow().run.name",
+ "original_volume_id": "@variables('VolumeId')"
+ }
+ },
+ "retryPolicy": {
+ "type": "exponential",
+ "count": 3,
+ "interval": "PT5S",
+ "minimumInterval": "PT5S",
+ "maximumInterval": "PT30S"
+ }
+ }
+ }
+ }
+ },
+ "Parse_Poll_Response": {
+ "runAfter": {
+ "Check_If_Should_Poll": [
+ "Succeeded"
+ ]
+ },
+ "type": "ParseJson",
+ "inputs": {
+ "content": "@body('Call_Async_Poll_Playbook')",
+ "schema": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "string"
+ },
+ "jobId": {
+ "type": "string"
+ },
+ "success": {
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ },
+ "Store_Poll_Response": {
+ "runAfter": {
+ "Parse_Poll_Response": [
+ "Succeeded"
+ ]
+ },
+ "type": "SetVariable",
+ "inputs": {
+ "name": "PollResponse",
+ "value": "@body('Parse_Poll_Response')"
+ }
+ },
+ "Return_Response": {
+ "runAfter": {
+ "Store_Poll_Response": [
+ "Succeeded",
+ "Skipped"
+ ],
+ "Check_If_Should_Poll": [
+ "Succeeded"
+ ],
+ "Call_Auth_Playbook": [
+ "Failed",
+ "TimedOut"
+ ],
+ "Submit_Volume_Snapshot": [
+ "Failed",
+ "TimedOut"
+ ]
+ },
+ "type": "Response",
+ "kind": "Http",
+ "inputs": {
+ "statusCode": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 401, if(or(equals(actions('Submit_Volume_Snapshot')['status'], 'Failed'), equals(actions('Submit_Volume_Snapshot')['status'], 'TimedOut')), 500, if(or(equals(variables('SubmissionStatusCode'), 200), equals(variables('SubmissionStatusCode'), 201), equals(variables('SubmissionStatusCode'), 202)), 200, if(equals(variables('SubmissionStatusCode'), 0), 500, variables('SubmissionStatusCode')))))",
+ "headers": {
+ "Content-Type": "application/json"
+ },
+ "body": {
+ "success": "@and(not(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut'))), not(or(equals(actions('Submit_Volume_Snapshot')['status'], 'Failed'), equals(actions('Submit_Volume_Snapshot')['status'], 'TimedOut'))), or(equals(variables('SubmissionStatusCode'), 200), equals(variables('SubmissionStatusCode'), 201), equals(variables('SubmissionStatusCode'), 202)))",
+ "error": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'Authentication failed in auth playbook', if(or(equals(actions('Submit_Volume_Snapshot')['status'], 'Failed'), equals(actions('Submit_Volume_Snapshot')['status'], 'TimedOut')), 'Failed submitting volume snapshot request', null))",
+ "stage": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'auth', if(or(equals(actions('Submit_Volume_Snapshot')['status'], 'Failed'), equals(actions('Submit_Volume_Snapshot')['status'], 'TimedOut')), 'submit', 'success'))",
+ "submission": {
+ "statusCode": "@variables('SubmissionStatusCode')",
+ "jobId": "@variables('JobId')",
+ "raw": "@body('Submit_Volume_Snapshot')",
+ "details": "@if(or(equals(actions('Submit_Volume_Snapshot')['status'], 'Failed'), equals(actions('Submit_Volume_Snapshot')['status'], 'TimedOut')), body('Submit_Volume_Snapshot'), null)"
+ },
+ "polling": {
+ "invoked": "@and(variables('DoPoll'), not(empty(variables('JobId'))))",
+ "playbook": "@parameters('asyncPollPlaybookName')",
+ "jobFinalStatus": "@coalesce(variables('PollResponse')?['status'], 'unknown')",
+ "jobResponse": "@variables('PollResponse')"
+ },
+ "callbackData": "@variables('CallbackData')",
+ "timestamp": "@utcnow()"
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": {
+ "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId4'),'/'))))]",
+ "properties": {
+ "parentId": "[variables('playbookId4')]",
+ "contentId": "[variables('_playbookContentId4')]",
+ "kind": "Playbook",
+ "version": "[variables('playbookVersion4')]",
+ "source": {
+ "kind": "Solution",
+ "name": "NetApp Ransomware Resilience",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "NetApp",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "NetApp",
+ "email": "support@netapp.com",
+ "tier": "Partner",
+ "link": "https://support.netapp.com"
+ }
+ }
+ }
+ ],
+ "metadata": {
+ "title": "NetApp Ransomware Resilience Volume Snapshot Playbook",
+ "description": "This playbook creates a NetApp volume snapshot using the updated NetApp Ransomware Resilience take-snapshot API endpoint and optionally polls for completion.",
+ "prerequisites": [
+ "1. NetApp Ransomware Resilience Auth Playbook must be deployed first and ensure that it is functioning correctly",
+ "2. NetApp Ransomware Resilience Async Poll Playbook must be deployed first and ensure that it is functioning correctly",
+ "3. Valid NetApp Ransomware Resilience API credentials configured in the Auth Playbook",
+ "4. Caller must provide volume_id, agent_id, and system_id parameters"
+ ],
+ "postDeployment": [
+ "1. Test the volume snapshot functionality with valid volume_id, agent_id, and system_id"
+ ],
+ "lastUpdateTime": "2025-09-22T00:00:00Z",
+ "tags": [
+ "NetApp",
+ "RansomwareResilience",
+ "Playbook",
+ "Volume",
+ "Snapshot"
+ ],
+ "releaseNotes": {
+ "version": "1.0",
+ "title": "[variables('blanks')]",
+ "notes": [
+ "Initial version"
+ ]
+ }
+ }
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_playbookContentId4')]",
+ "contentKind": "Playbook",
+ "displayName": "NetApp-RansomwareResilience-Volume-Snapshot",
+ "contentProductId": "[variables('_playbookcontentProductId4')]",
+ "id": "[variables('_playbookcontentProductId4')]",
+ "version": "[variables('playbookVersion4')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('playbookTemplateSpecName5')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "NetApp-RansomwareResilience-Enrich-StorageVM Playbook with template version 3.0.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('playbookVersion5')]",
+ "parameters": {
+ "PlaybookName": {
+ "type": "String",
+ "defaultValue": "NetApp-RansomwareResilience-Enrich-StorageVM",
+ "metadata": {
+ "description": "Name of the Logic App/Playbook"
+ }
+ },
+ "NetAppRansomwareResilienceAuthPlaybookName": {
+ "type": "String",
+ "defaultValue": "NetApp-RansomwareResilience-Auth",
+ "metadata": {
+ "description": "Name of the NetApp Ransomware Resilience authentication playbook"
+ }
+ },
+ "location": {
+ "type": "string",
+ "defaultValue": "[parameters('location')]",
+ "metadata": {
+ "description": "Location for all resources"
+ }
+ }
+ },
+ "variables": {
+ "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]",
+ "workspace-name": "[parameters('workspace')]",
+ "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Logic/workflows",
+ "apiVersion": "2019-05-01",
+ "name": "[[parameters('PlaybookName')]",
+ "location": "[[parameters('location')]",
+ "identity": {
+ "type": "SystemAssigned"
+ },
+ "properties": {
+ "state": "Enabled",
+ "definition": {
+ "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "authPlaybookName": {
+ "defaultValue": "[[parameters('NetAppRansomwareResilienceAuthPlaybookName')]",
+ "type": "String"
+ }
+ },
+ "triggers": {
+ "manual": {
+ "type": "Request",
+ "kind": "Http",
+ "inputs": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "agent_id": {
+ "type": "string"
+ },
+ "system_id": {
+ "type": "string"
+ },
+ "callbackData": {
+ "type": "object"
+ }
+ },
+ "required": [
+ "agent_id",
+ "system_id"
+ ]
+ }
+ }
+ }
+ },
+ "actions": {
+ "Initialize_Variables": {
+ "type": "InitializeVariable",
+ "inputs": {
+ "variables": [
+ {
+ "name": "AgentId",
+ "type": "string",
+ "value": "@triggerBody()?['agent_id']"
+ },
+ {
+ "name": "SystemId",
+ "type": "string",
+ "value": "@triggerBody()?['system_id']"
+ },
+ {
+ "name": "CallbackData",
+ "type": "object",
+ "value": "@triggerBody()?['callbackData']"
+ },
+ {
+ "name": "AccountId",
+ "type": "string"
+ },
+ {
+ "name": "Token",
+ "type": "string"
+ },
+ {
+ "name": "StorageVMData",
+ "type": "array"
+ },
+ {
+ "name": "EnrichmentStatusCode",
+ "type": "integer",
+ "value": 0
+ }
+ ]
+ }
+ },
+ "Call_Auth_Playbook": {
+ "runAfter": {
+ "Initialize_Variables": [
+ "Succeeded"
+ ]
+ },
+ "type": "Http",
+ "inputs": {
+ "method": "POST",
+ "uri": "[[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('NetAppRansomwareResilienceAuthPlaybookName'), 'manual'), '2019-05-01').value]",
+ "headers": {
+ "Content-Type": "application/json"
+ },
+ "body": {
+ "caller_info": {
+ "playbook_name": "@workflow().name",
+ "correlation_id": "@workflow().run.name",
+ "request_id": "@guid()"
+ }
+ },
+ "retryPolicy": {
+ "type": "exponential",
+ "count": 3,
+ "interval": "PT5S",
+ "minimumInterval": "PT5S",
+ "maximumInterval": "PT30S"
+ }
+ }
+ },
+ "Parse_Auth_Response": {
+ "runAfter": {
+ "Call_Auth_Playbook": [
+ "Succeeded"
+ ]
+ },
+ "type": "ParseJson",
+ "inputs": {
+ "content": "@body('Call_Auth_Playbook')",
+ "schema": {
+ "type": "object",
+ "properties": {
+ "access_token": {
+ "type": "string"
+ },
+ "account_id": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "access_token",
+ "account_id"
+ ]
+ }
+ }
+ },
+ "Set_Token": {
+ "runAfter": {
+ "Parse_Auth_Response": [
+ "Succeeded"
+ ]
+ },
+ "type": "SetVariable",
+ "inputs": {
+ "name": "Token",
+ "value": "@body('Parse_Auth_Response')?['access_token']"
+ }
+ },
+ "Set_Account_ID": {
+ "runAfter": {
+ "Set_Token": [
+ "Succeeded"
+ ]
+ },
+ "type": "SetVariable",
+ "inputs": {
+ "name": "AccountId",
+ "value": "@body('Parse_Auth_Response')?['account_id']"
+ }
+ },
+ "Get_StorageVM_Data": {
+ "runAfter": {
+ "Set_Account_ID": [
+ "Succeeded"
+ ]
+ },
+ "type": "Http",
+ "inputs": {
+ "method": "GET",
+ "uri": "https://api.bluexp.netapp.com/v1/services/rps/v1/account/@{variables('AccountId')}/enrich/storage?agent_id=@{variables('AgentId')}&system_id=@{variables('SystemId')}",
+ "headers": {
+ "Authorization": "Bearer @{variables('Token')}",
+ "accept": "application/json"
+ },
+ "retryPolicy": {
+ "type": "exponential",
+ "count": 3,
+ "interval": "PT5S",
+ "minimumInterval": "PT5S",
+ "maximumInterval": "PT30S"
+ }
+ }
+ },
+ "Capture_Enrichment_Status_Code": {
+ "runAfter": {
+ "Get_StorageVM_Data": [
+ "Succeeded",
+ "Failed"
+ ]
+ },
+ "type": "SetVariable",
+ "inputs": {
+ "name": "EnrichmentStatusCode",
+ "value": "@outputs('Get_StorageVM_Data')['statusCode']"
+ }
+ },
+ "Parse_StorageVM_Response": {
+ "runAfter": {
+ "Capture_Enrichment_Status_Code": [
+ "Succeeded"
+ ]
+ },
+ "type": "ParseJson",
+ "inputs": {
+ "content": "@body('Get_StorageVM_Data')",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "volume_uuid": {
+ "type": "string"
+ },
+ "volume_name": {
+ "type": "string"
+ },
+ "svm_name": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "Store_StorageVM_Data": {
+ "runAfter": {
+ "Parse_StorageVM_Response": [
+ "Succeeded"
+ ]
+ },
+ "type": "SetVariable",
+ "inputs": {
+ "name": "StorageVMData",
+ "value": "@body('Parse_StorageVM_Response')"
+ }
+ },
+ "Finalize_Execution": {
+ "runAfter": {
+ "Store_StorageVM_Data": [
+ "Succeeded",
+ "Skipped",
+ "Failed",
+ "TimedOut"
+ ],
+ "Call_Auth_Playbook": [
+ "Failed",
+ "TimedOut"
+ ],
+ "Get_StorageVM_Data": [
+ "Failed",
+ "TimedOut"
+ ]
+ },
+ "type": "Compose",
+ "inputs": {
+ "execution_completed": true,
+ "timestamp": "@utcNow()"
+ }
+ },
+ "Return_Response": {
+ "runAfter": {
+ "Finalize_Execution": [
+ "Succeeded",
+ "Skipped",
+ "Failed",
+ "TimedOut"
+ ]
+ },
+ "type": "Response",
+ "kind": "Http",
+ "inputs": {
+ "statusCode": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 401, if(or(equals(actions('Get_StorageVM_Data')['status'], 'Failed'), equals(actions('Get_StorageVM_Data')['status'], 'TimedOut')), 500, if(equals(variables('EnrichmentStatusCode'), 200), 200, if(equals(variables('EnrichmentStatusCode'), 0), 500, variables('EnrichmentStatusCode')))))",
+ "headers": {
+ "Content-Type": "application/json"
+ },
+ "body": {
+ "success": "@and(not(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut'))), not(or(equals(actions('Get_StorageVM_Data')['status'], 'Failed'), equals(actions('Get_StorageVM_Data')['status'], 'TimedOut'))), equals(variables('EnrichmentStatusCode'), 200))",
+ "error": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'Authentication failed in auth playbook', if(or(equals(actions('Get_StorageVM_Data')['status'], 'Failed'), equals(actions('Get_StorageVM_Data')['status'], 'TimedOut')), 'Failed retrieving storage VM data', null))",
+ "stage": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'auth', if(or(equals(actions('Get_StorageVM_Data')['status'], 'Failed'), equals(actions('Get_StorageVM_Data')['status'], 'TimedOut')), 'enrichment', 'success'))",
+ "account_id": "@variables('AccountId')",
+ "enrichment": {
+ "statusCode": "@variables('EnrichmentStatusCode')",
+ "storage_vms": "@variables('StorageVMData')",
+ "count": "@length(variables('StorageVMData'))",
+ "raw": "@body('Get_StorageVM_Data')"
+ },
+ "callbackData": "@variables('CallbackData')",
+ "timestamp": "@utcnow()"
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": {
+ "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId5'),'/'))))]",
+ "properties": {
+ "parentId": "[variables('playbookId5')]",
+ "contentId": "[variables('_playbookContentId5')]",
+ "kind": "Playbook",
+ "version": "[variables('playbookVersion5')]",
+ "source": {
+ "kind": "Solution",
+ "name": "NetApp Ransomware Resilience",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "NetApp",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "NetApp",
+ "email": "support@netapp.com",
+ "tier": "Partner",
+ "link": "https://support.netapp.com"
+ }
+ }
+ }
+ ],
+ "metadata": {
+ "title": "NetApp Ransomware Resilience Enrich StorageVM Playbook",
+ "description": "This playbook enriches storage data by calling the updated NetApp Ransomware Resilience enrich storage API endpoint.",
+ "prerequisites": [
+ "1. NetApp Ransomware Resilience Auth Playbook must be deployed first and ensure that it is functioning correctly",
+ "2. Valid NetApp Ransomware Resilience API credentials configured in the Auth Playbook",
+ "3. Caller must provide agent_id and system_id parameters"
+ ],
+ "postDeployment": [
+ "1. Test the storage enrichment functionality with valid agent_id and system_id"
+ ],
+ "lastUpdateTime": "2025-09-23T00:00:00Z",
+ "tags": [
+ "NetApp",
+ "RansomwareResilience",
+ "Playbook",
+ "StorageVM",
+ "Enrich"
+ ],
+ "releaseNotes": {
+ "version": "1.0",
+ "title": "[variables('blanks')]",
+ "notes": [
+ "Initial version"
+ ]
+ }
+ }
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_playbookContentId5')]",
+ "contentKind": "Playbook",
+ "displayName": "NetApp-RansomwareResilience-Enrich-StorageVM",
+ "contentProductId": "[variables('_playbookcontentProductId5')]",
+ "id": "[variables('_playbookcontentProductId5')]",
+ "version": "[variables('playbookVersion5')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates",
+ "apiVersion": "2023-04-01-preview",
+ "name": "[variables('playbookTemplateSpecName6')]",
+ "location": "[parameters('workspace-location')]",
+ "dependsOn": [
+ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
+ ],
+ "properties": {
+ "description": "NetApp-RansomwareResilience-Enrich-IP Playbook with template version 3.0.0",
+ "mainTemplate": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "[variables('playbookVersion6')]",
+ "parameters": {
+ "PlaybookName": {
+ "type": "String",
+ "defaultValue": "NetApp-RansomwareResilience-Enrich-IP",
+ "metadata": {
+ "description": "Name of the Logic App/Playbook"
+ }
+ },
+ "NetAppRansomwareResilienceAuthPlaybookName": {
+ "type": "String",
+ "defaultValue": "NetApp-RansomwareResilience-Auth",
+ "metadata": {
+ "description": "Name of the NetApp Ransomware Resilience authentication playbook"
+ }
+ },
+ "NetAppRansomwareResilienceAsyncPollPlaybookName": {
+ "type": "String",
+ "defaultValue": "NetApp-RansomwareResilience-Async-Poll",
+ "metadata": {
+ "description": "Name of the NetApp Ransomware Resilience async poll playbook"
+ }
+ },
+ "location": {
+ "type": "string",
+ "defaultValue": "[parameters('location')]",
+ "metadata": {
+ "description": "Location for all resources"
+ }
+ }
+ },
+ "variables": {
+ "workspace-location-inline": "[concat('[resourceGroup().locatio', 'n]')]",
+ "workspace-name": "[parameters('workspace')]",
+ "workspaceResourceId": "[[resourceId('microsoft.OperationalInsights/Workspaces', variables('workspace-name'))]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Logic/workflows",
+ "apiVersion": "2019-05-01",
+ "name": "[[parameters('PlaybookName')]",
+ "location": "[[parameters('location')]",
+ "identity": {
+ "type": "SystemAssigned"
+ },
+ "properties": {
+ "state": "Enabled",
+ "definition": {
+ "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "authPlaybookName": {
+ "defaultValue": "[[parameters('NetAppRansomwareResilienceAuthPlaybookName')]",
+ "type": "String"
+ },
+ "asyncPollPlaybookName": {
+ "defaultValue": "[[parameters('NetAppRansomwareResilienceAsyncPollPlaybookName')]",
+ "type": "String"
+ }
+ },
+ "triggers": {
+ "manual": {
+ "type": "Request",
+ "kind": "Http",
+ "inputs": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "ip_address": {
+ "type": "string"
+ },
+ "callbackData": {
+ "type": "object"
+ }
+ },
+ "required": [
+ "ip_address"
+ ]
+ }
+ }
+ }
+ },
+ "actions": {
+ "Initialize_Variables": {
+ "type": "InitializeVariable",
+ "inputs": {
+ "variables": [
+ {
+ "name": "IpAddress",
+ "type": "string",
+ "value": "@triggerBody()?['ip_address']"
+ },
+ {
+ "name": "CallbackData",
+ "type": "object",
+ "value": "@triggerBody()?['callbackData']"
+ },
+ {
+ "name": "AccountId",
+ "type": "string"
+ },
+ {
+ "name": "Token",
+ "type": "string"
+ },
+ {
+ "name": "JobIds",
+ "type": "array"
+ },
+ {
+ "name": "PollingResults",
+ "type": "array"
+ },
+ {
+ "name": "EnrichmentStatusCode",
+ "type": "integer",
+ "value": 0
+ }
+ ]
+ }
+ },
+ "Call_Auth_Playbook": {
+ "runAfter": {
+ "Initialize_Variables": [
+ "Succeeded"
+ ]
+ },
+ "type": "Http",
+ "inputs": {
+ "method": "POST",
+ "uri": "[[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('NetAppRansomwareResilienceAuthPlaybookName'), 'manual'), '2019-05-01').value]",
+ "headers": {
+ "Content-Type": "application/json"
+ },
+ "body": {
+ "caller_info": {
+ "playbook_name": "@workflow().name",
+ "correlation_id": "@workflow().run.name",
+ "request_id": "@guid()"
+ }
+ },
+ "retryPolicy": {
+ "type": "exponential",
+ "count": 3,
+ "interval": "PT5S",
+ "minimumInterval": "PT5S",
+ "maximumInterval": "PT30S"
+ },
+ "timeout": "PT30S"
+ }
+ },
+ "Parse_Auth_Response": {
+ "runAfter": {
+ "Call_Auth_Playbook": [
+ "Succeeded"
+ ]
+ },
+ "type": "ParseJson",
+ "inputs": {
+ "content": "@body('Call_Auth_Playbook')",
+ "schema": {
+ "type": "object",
+ "properties": {
+ "access_token": {
+ "type": "string"
+ },
+ "account_id": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "access_token",
+ "account_id"
+ ]
+ }
+ }
+ },
+ "Set_Token": {
+ "runAfter": {
+ "Parse_Auth_Response": [
+ "Succeeded"
+ ]
+ },
+ "type": "SetVariable",
+ "inputs": {
+ "name": "Token",
+ "value": "@body('Parse_Auth_Response')?['access_token']"
+ }
+ },
+ "Set_Account_ID": {
+ "runAfter": {
+ "Set_Token": [
+ "Succeeded"
+ ]
+ },
+ "type": "SetVariable",
+ "inputs": {
+ "name": "AccountId",
+ "value": "@body('Parse_Auth_Response')?['account_id']"
+ }
+ },
+ "Get_IP_NetworkInterfaces": {
+ "runAfter": {
+ "Set_Account_ID": [
+ "Succeeded"
+ ]
+ },
+ "type": "Http",
+ "inputs": {
+ "method": "POST",
+ "uri": "https://api.bluexp.netapp.com/v1/services/rps/v1/account/@{variables('AccountId')}/enrich/ip-address",
+ "headers": {
+ "Authorization": "Bearer @{variables('Token')}",
+ "accept": "application/json",
+ "Content-Type": "application/json"
+ },
+ "body": {
+ "ip_address": "@{variables('IpAddress')}"
+ },
+ "retryPolicy": {
+ "type": "exponential",
+ "count": 3,
+ "interval": "PT5S",
+ "minimumInterval": "PT5S",
+ "maximumInterval": "PT30S"
+ },
+ "timeout": "PT45S"
+ }
+ },
+ "Capture_Enrichment_Status_Code": {
+ "runAfter": {
+ "Get_IP_NetworkInterfaces": [
+ "Succeeded",
+ "Failed"
+ ]
+ },
+ "type": "SetVariable",
+ "inputs": {
+ "name": "EnrichmentStatusCode",
+ "value": "@outputs('Get_IP_NetworkInterfaces')['statusCode']"
+ }
+ },
+ "Parse_JobIds_Response": {
+ "runAfter": {
+ "Capture_Enrichment_Status_Code": [
+ "Succeeded"
+ ]
+ },
+ "type": "ParseJson",
+ "inputs": {
+ "content": "@body('Get_IP_NetworkInterfaces')",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "job_id": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ },
+ "agent_id": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "Extract_Job_IDs": {
+ "runAfter": {
+ "Parse_JobIds_Response": [
+ "Succeeded"
+ ]
+ },
+ "type": "SetVariable",
+ "inputs": {
+ "name": "JobIds",
+ "value": "@body('Parse_JobIds_Response')"
+ }
+ },
+ "Poll_All_Jobs": {
+ "runAfter": {
+ "Extract_Job_IDs": [
+ "Succeeded"
+ ]
+ },
+ "type": "Foreach",
+ "foreach": "@variables('JobIds')",
+ "actions": {
+ "Call_Async_Poll_Playbook": {
+ "type": "Http",
+ "inputs": {
+ "method": "POST",
+ "uri": "[[listCallbackUrl(resourceId('Microsoft.Logic/workflows/triggers', parameters('NetAppRansomwareResilienceAsyncPollPlaybookName'), 'manual'), '2019-05-01').value]",
+ "headers": {
+ "Content-Type": "application/json"
+ },
+ "body": {
+ "job_id": "@item()?['job_id']",
+ "agent_id": "@item()?['agent_id']",
+ "system_id": "default",
+ "source": "@item()?['source']",
+ "caller_info": {
+ "playbook_name": "@workflow().name",
+ "correlation_id": "@workflow().run.name",
+ "original_ip": "@variables('IpAddress')"
+ }
+ },
+ "retryPolicy": {
+ "type": "exponential",
+ "count": 3,
+ "interval": "PT5S",
+ "minimumInterval": "PT5S",
+ "maximumInterval": "PT30S"
+ },
+ "timeout": "PT90S"
+ }
+ },
+ "Add_Poll_Result": {
+ "runAfter": {
+ "Call_Async_Poll_Playbook": [
+ "Succeeded"
+ ]
+ },
+ "type": "AppendToArrayVariable",
+ "inputs": {
+ "name": "PollingResults",
+ "value": {
+ "job_id": "@item()?['job_id']",
+ "poll_response": "@body('Call_Async_Poll_Playbook')",
+ "original_job_info": "@item()"
+ }
+ }
+ },
+ "Add_Failed_Poll_Result": {
+ "runAfter": {
+ "Call_Async_Poll_Playbook": [
+ "Failed",
+ "TimedOut"
+ ]
+ },
+ "type": "AppendToArrayVariable",
+ "inputs": {
+ "name": "PollingResults",
+ "value": {
+ "job_id": "@item()?['job_id']",
+ "poll_response": {
+ "success": false,
+ "error": "Failed to poll job or timeout occurred"
+ },
+ "original_job_info": "@item()"
+ }
+ }
+ }
+ },
+ "runtimeConfiguration": {
+ "concurrency": {
+ "repetitions": 1
+ }
+ }
+ },
+ "Finalize_Execution": {
+ "runAfter": {
+ "Poll_All_Jobs": [
+ "Succeeded",
+ "Skipped",
+ "Failed",
+ "TimedOut"
+ ],
+ "Call_Auth_Playbook": [
+ "Failed",
+ "TimedOut"
+ ],
+ "Get_IP_NetworkInterfaces": [
+ "Failed",
+ "TimedOut"
+ ]
+ },
+ "type": "Compose",
+ "inputs": {
+ "execution_completed": true,
+ "timestamp": "@utcNow()"
+ }
+ },
+ "Return_Response": {
+ "runAfter": {
+ "Finalize_Execution": [
+ "Succeeded",
+ "Skipped",
+ "Failed",
+ "TimedOut"
+ ]
+ },
+ "type": "Response",
+ "kind": "Http",
+ "inputs": {
+ "statusCode": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 401, if(or(equals(actions('Get_IP_NetworkInterfaces')['status'], 'Failed'), equals(actions('Get_IP_NetworkInterfaces')['status'], 'TimedOut')), 500, if(equals(variables('EnrichmentStatusCode'), 200), 200, if(equals(variables('EnrichmentStatusCode'), 0), 500, variables('EnrichmentStatusCode')))))",
+ "headers": {
+ "Content-Type": "application/json"
+ },
+ "body": {
+ "success": "@and(not(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut'))), not(or(equals(actions('Get_IP_NetworkInterfaces')['status'], 'Failed'), equals(actions('Get_IP_NetworkInterfaces')['status'], 'TimedOut'))), equals(variables('EnrichmentStatusCode'), 200))",
+ "error": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'Authentication failed in auth playbook', if(or(equals(actions('Get_IP_NetworkInterfaces')['status'], 'Failed'), equals(actions('Get_IP_NetworkInterfaces')['status'], 'TimedOut')), 'Failed retrieving IP network interfaces data', null))",
+ "stage": "@if(or(equals(actions('Call_Auth_Playbook')['status'], 'Failed'), equals(actions('Call_Auth_Playbook')['status'], 'TimedOut')), 'auth', if(or(equals(actions('Get_IP_NetworkInterfaces')['status'], 'Failed'), equals(actions('Get_IP_NetworkInterfaces')['status'], 'TimedOut')), 'enrichment', 'success'))",
+ "account_id": "@variables('AccountId')",
+ "ip_address": "@variables('IpAddress')",
+ "enrichment": {
+ "statusCode": "@variables('EnrichmentStatusCode')",
+ "job_ids_count": "@length(variables('JobIds'))",
+ "polling_results_count": "@length(variables('PollingResults'))",
+ "original_jobs": "@variables('JobIds')",
+ "polling_results": "@variables('PollingResults')",
+ "raw_initial_response": "@body('Get_IP_NetworkInterfaces')"
+ },
+ "callbackData": "@variables('CallbackData')",
+ "timestamp": "@utcnow()"
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": {
+ "hidden-SentinelWorkspaceId": "[[variables('workspaceResourceId')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/metadata",
+ "apiVersion": "2022-01-01-preview",
+ "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Playbook-', last(split(variables('playbookId6'),'/'))))]",
+ "properties": {
+ "parentId": "[variables('playbookId6')]",
+ "contentId": "[variables('_playbookContentId6')]",
+ "kind": "Playbook",
+ "version": "[variables('playbookVersion6')]",
+ "source": {
+ "kind": "Solution",
+ "name": "NetApp Ransomware Resilience",
+ "sourceId": "[variables('_solutionId')]"
+ },
+ "author": {
+ "name": "NetApp",
+ "email": "[variables('_email')]"
+ },
+ "support": {
+ "name": "NetApp",
+ "email": "support@netapp.com",
+ "tier": "Partner",
+ "link": "https://support.netapp.com"
+ }
+ }
+ }
+ ],
+ "metadata": {
+ "title": "NetApp Ransomware Resilience Enrich IP Playbook",
+ "description": "This playbook enriches IP data by calling the updated NetApp Ransomware Resilience enrich IP address API endpoint and asynchronously polls multiple job results.",
+ "prerequisites": [
+ "1. NetApp Ransomware Resilience Auth Playbook must be deployed first and ensure that it is functioning correctly",
+ "2. NetApp Ransomware Resilience Async Poll Playbook must be deployed and ensure that it is functioning correctly",
+ "3. Valid NetApp Ransomware Resilience API credentials configured in the Auth Playbook",
+ "4. Caller must provide ip_address parameter"
+ ],
+ "postDeployment": [
+ "1. Test the IP enrichment functionality with valid IP address"
+ ],
+ "lastUpdateTime": "2025-09-26T00:00:00Z",
+ "tags": [
+ "NetApp",
+ "RansomwareResilience",
+ "Playbook",
+ "IP",
+ "Enrich",
+ "NetworkInterface"
+ ],
+ "releaseNotes": {
+ "version": "1.0",
+ "title": "[variables('blanks')]",
+ "notes": [
+ "Initial version"
+ ]
+ }
+ }
+ },
+ "packageKind": "Solution",
+ "packageVersion": "[variables('_solutionVersion')]",
+ "packageName": "[variables('_solutionName')]",
+ "packageId": "[variables('_solutionId')]",
+ "contentSchemaVersion": "3.0.0",
+ "contentId": "[variables('_playbookContentId6')]",
+ "contentKind": "Playbook",
+ "displayName": "NetApp-RansomwareResilience-Enrich-IP",
+ "contentProductId": "[variables('_playbookcontentProductId6')]",
+ "id": "[variables('_playbookcontentProductId6')]",
+ "version": "[variables('playbookVersion6')]"
+ }
+ },
+ {
+ "type": "Microsoft.OperationalInsights/workspaces/providers/contentPackages",
+ "apiVersion": "2023-04-01-preview",
+ "location": "[parameters('workspace-location')]",
+ "properties": {
+ "version": "3.0.0",
+ "kind": "Solution",
+ "contentSchemaVersion": "3.0.0",
+ "displayName": "NetApp Ransomware Resilience",
+ "publisherDisplayName": "NetApp",
+ "descriptionHtml": "
Note: Please refer to the following before installing the solution:
\n• Review the solution Release Notes
\n• There may be known issues pertaining to this Solution, please refer to them before installing.
\nNetApp Ransomware Resilience - Comprehensive security solution for detecting and responding to ransomware threats across NetApp storage environments.
\nPlaybooks: 6
\nLearn more about Microsoft Sentinel | Learn more about Solutions
\n", + "contentKind": "Solution", + "contentProductId": "[variables('_solutioncontentProductId')]", + "id": "[variables('_solutioncontentProductId')]", + "icon": "