From 465df3028f5b26554fc0144a5639264868a40699 Mon Sep 17 00:00:00 2001
From: Stefano Pescosolido <stefanpe@live.it>
Date: Tue, 28 May 2024 09:35:58 +0200
Subject: [PATCH] Added Adjust CFS Capacity with Azure Logic App

---
 .../README.md                                 |  10 +
 .../template.json                             | 445 ++++++++++++++++++
 2 files changed, 455 insertions(+)
 create mode 100644 Monitoring/Adjust CFS Capacity with Azure Logic App/README.md
 create mode 100644 Monitoring/Adjust CFS Capacity with Azure Logic App/template.json

diff --git a/Monitoring/Adjust CFS Capacity with Azure Logic App/README.md b/Monitoring/Adjust CFS Capacity with Azure Logic App/README.md
new file mode 100644
index 00000000..41bebeb6
--- /dev/null
+++ b/Monitoring/Adjust CFS Capacity with Azure Logic App/README.md	
@@ -0,0 +1,10 @@
+# Azure Logic App ARM Template for scheduling Copilot for Security SCU provisioning. 
+
+The file template.json is an ARM template for creating an Azure Logic App that is capable of automatically changing the capacity (SCUs) of Copilot for Security based on the time of the day and wheater the day is a workday, weekend of national holiday.
+
+### Prerequisites:
+* Credit in Azure for consuming SCUs
+
+### Description and Instructions: 
+The following article contains a detailed description of how the Logic App works and how to set it up:
+[Scheduling the Provisioning of Capacity (SCUs) for Copilot for Security - Logic App Template](https://www.linkedin.com/pulse/scheduling-provisioning-capacity-scus-copilot-logic-pescosolido-ku8ef/?trackingId=vhZAZBr9Snqoj%2FkSaFdqJQ%3D%3D)
diff --git a/Monitoring/Adjust CFS Capacity with Azure Logic App/template.json b/Monitoring/Adjust CFS Capacity with Azure Logic App/template.json
new file mode 100644
index 00000000..71188b54
--- /dev/null
+++ b/Monitoring/Adjust CFS Capacity with Azure Logic App/template.json	
@@ -0,0 +1,445 @@
+{
+  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+  "contentVersion": "1.0.0.0",
+  "parameters": {
+    "logicAppName": {
+      "type": "string",
+      "defaultValue": "cfs-set-X-SCUs",
+      "metadata": {
+        "description": "Name of the Logic App."
+      }
+    },
+    "logicAppLocation": {
+      "type": "string",
+      "defaultValue": "[resourceGroup().location]",
+      "allowedValues": [
+        "[resourceGroup().location]",
+        "asia",
+        "asiapacific",
+        "australia",
+        "australiacentral",
+        "australiacentral2",
+        "australiaeast",
+        "australiasoutheast",
+        "brazil",
+        "brazilsouth",
+        "brazilsoutheast",
+        "canada",
+        "canadacentral",
+        "canadaeast",
+        "centralindia",
+        "centralus",
+        "centraluseuap",
+        "centralusstage",
+        "chinaeast",
+        "chinanorth",
+        "eastasia",
+        "eastasiastage",
+        "eastus",
+        "eastus2",
+        "eastus2euap",
+        "eastus2stage",
+        "eastusstage",
+        "europe",
+        "francecentral",
+        "francesouth",
+        "germanycentral",
+        "germanynorth",
+        "germanynortheast",
+        "germanywestcentral",
+        "global",
+        "india",
+        "japan",
+        "japaneast",
+        "japanwest",
+        "jioindiawest",
+        "koreacentral",
+        "koreasouth",
+        "northcentralus",
+        "northcentralusstage",
+        "northeurope",
+        "norwayeast",
+        "norwaywest",
+        "southafricanorth",
+        "southafricawest",
+        "southcentralus",
+        "southcentralusstage",
+        "southeastasia",
+        "southeastasiastage",
+        "southindia",
+        "switzerland",
+        "switzerlandnorth",
+        "switzerlandwest",
+        "uaecentral",
+        "uaenorth",
+        "uk",
+        "uksouth",
+        "ukwest",
+        "unitedstates",
+        "usdodeast",
+        "usdodwest",
+        "usgovarizona",
+        "usgoviowa",
+        "usgovtexas",
+        "usgovvirginia",
+        "usseceast",
+        "ussecwest",
+        "west",
+        "westcentralus",
+        "westeurope",
+        "westindia",
+        "westus",
+        "westus2",
+        "westus2stage",
+        "westus3",
+        "westusstage"
+      ],
+      "metadata": {
+        "description": "Location of the Logic App."
+      }
+    },
+    "RecurrenceFrequency": {
+      "type": "string",
+      "defaultValue": "Day"
+    },
+    "RecurrenceInterval": {
+      "type": "int",
+      "defaultValue": 1
+    },
+    "RecurrenceTimeZone": {
+      "type": "string",
+      "defaultValue": "W. Europe Standard Time"
+    },
+    "RecurrenceSchedule": {
+      "type": "Object",
+      "defaultValue": {
+        "hours": [
+          "8"
+        ],
+        "minutes": [
+          30
+        ]
+      }
+    },
+    "paramNumberOfSCUs": {
+      "type": "int",
+      "defaultValue": 0
+    },
+    "paramCrossGeoCompute": {
+      "type": "string",
+      "defaultValue": "Allowed"
+    },
+    "paramGeo": {
+      "type": "string",
+      "defaultValue": "EU"
+    },
+    "paramCapacityName": {
+      "type": "string",
+      "defaultValue": ""
+    },
+    "paramSubscriptionID": {
+      "type": "string",
+      "defaultValue": ""
+    },
+    "paramResourceGroup": {
+      "type": "string",
+      "defaultValue": ""
+    },
+    "paramLocation": {
+      "type": "string",
+      "defaultValue": "westeurope"
+    },
+    "connection_name": {
+      "type": "string",
+      "defaultValue": "temp-Connection"
+    },
+    "connection_displayName": {
+      "type": "string",
+      "defaultValue": "temp-Connection"
+    }
+  },
+  "variables": {},
+  "resources": [
+    {
+      "type": "Microsoft.Logic/workflows",
+      "apiVersion": "2019-05-01",
+      "name": "[parameters('logicAppName')]",
+      "location": "[parameters('logicAppLocation')]",
+      "dependsOn": [
+        "[resourceId('Microsoft.Web/connections', parameters('connection_name'))]"
+      ],
+      "properties": {
+        "definition": {
+          "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
+          "contentVersion": "1.0.0.0",
+          "parameters": {
+            "NumberOfSCUs": {
+              "defaultValue": "[parameters('paramNumberOfSCUs')]",
+              "type": "Int"
+            },
+            "CrossGeoCompute": {
+              "defaultValue": "[parameters('paramCrossGeoCompute')]",
+              "type": "String"
+            },
+            "Geo": {
+              "defaultValue": "[parameters('paramGeo')]",
+              "type": "String"
+            },
+            "CapacityName": {
+              "defaultValue": "[parameters('paramCapacityName')]",
+              "type": "String"
+            },
+            "SubscriptionID": {
+              "defaultValue": "[parameters('paramSubscriptionID')]",
+              "type": "String"
+            },
+            "ResourceGroup": {
+              "defaultValue": "[parameters('paramResourceGroup')]",
+              "type": "String"
+            },
+            "Location": {
+              "defaultValue": "[parameters('paramLocation')]",
+              "type": "String"
+            },
+            "$connections": {
+              "defaultValue": {},
+              "type": "Object"
+            }
+          },
+          "triggers": {
+            "Recurrence": {
+              "recurrence": {
+                "interval": "[parameters('RecurrenceInterval')]",
+                "frequency": "[parameters('RecurrenceFrequency')]",
+                "timeZone": "[parameters('RecurrenceTimeZone')]",
+                "schedule": "[parameters('RecurrenceSchedule')]"
+              },
+              "type": "Recurrence"
+            }
+          },
+          "actions": {
+            "Initialize_National_Holidays": {
+              "runAfter": {
+                "Initialize_Today": [
+                  "Succeeded"
+                ]
+              },
+              "type": "InitializeVariable",
+              "inputs": {
+                "variables": [
+                  {
+                    "name": "Holidays",
+                    "type": "array",
+                    "value": "@createArray('2024-01-01', '2024-01-06', '2024-03-31', '2024-04-01', '2024-04-25', '2024-05-01', '2024-06-02', '2024-06-29', '2024-08-15', '2024-08-16', '2024-11-01', '2024-12-08', '2024-12-25', '2024-12-26', '2025-01-01', '2025-01-06', '2025-04-25', '2025-05-01', '2025-06-02', '2025-06-29', '2025-08-15', '2025-08-16', '2025-11-01', '2025-12-08', '2025-12-25', '2025-12-26')"
+                  }
+                ]
+              }
+            },
+            "Initialize_IsTodayHoliday": {
+              "runAfter": {
+                "Initialize_National_Holidays": [
+                  "Succeeded"
+                ]
+              },
+              "type": "InitializeVariable",
+              "inputs": {
+                "variables": [
+                  {
+                    "name": "IsTodayHoliday",
+                    "type": "boolean",
+                    "value": false
+                  }
+                ]
+              }
+            },
+            "Initialize_Today": {
+              "runAfter": {},
+              "type": "InitializeVariable",
+              "inputs": {
+                "variables": [
+                  {
+                    "name": "Today",
+                    "type": "string",
+                    "value": "@{formatDateTime(startOfDay(utcNow()),'yyyy-MM-dd')}"
+                  }
+                ]
+              }
+            },
+            "Condition_Is_Create_or_Update_Capacity": {
+              "actions": {
+                "Condition_Is_Today_National_Holiday": {
+                  "actions": {
+                    "Set_IsTodayHoliday": {
+                      "type": "SetVariable",
+                      "inputs": {
+                        "name": "IsTodayHoliday",
+                        "value": true
+                      }
+                    }
+                  },
+                  "else": {
+                    "actions": {}
+                  },
+                  "expression": {
+                    "and": [
+                      {
+                        "contains": [
+                          "@variables('Holidays')",
+                          "@variables('Today')"
+                        ]
+                      }
+                    ]
+                  },
+                  "type": "If"
+                },
+                "Condition_Is_Working_Day": {
+                  "actions": {
+                    "Create_or_Update_Capacity": {
+                      "type": "ApiConnection",
+                      "inputs": {
+                        "host": {
+                          "connection": {
+                            "name": "@parameters('$connections')['arm-1']['connectionId']"
+                          }
+                        },
+                        "method": "put",
+                        "body": {
+                          "location": "@parameters('Location')",
+                          "properties": {
+                            "numberOfUnits": "@parameters('NumberOfSCUs')",
+                            "crossGeoCompute": "@{parameters('CrossGeoCompute')}",
+                            "geo": "@{parameters('Geo')}"
+                          }
+                        },
+                        "path": "/subscriptions/@{encodeURIComponent(parameters('SubscriptionID'))}/resourcegroups/@{encodeURIComponent(parameters('ResourceGroup'))}/providers/@{encodeURIComponent('Microsoft.SecurityCopilot')}/@{encodeURIComponent('capacities/',parameters('CapacityName'))}",
+                        "queries": {
+                          "x-ms-api-version": "2023-12-01-preview"
+                        }
+                      }
+                    }
+                  },
+                  "runAfter": {
+                    "Condition_Is_Today_National_Holiday": [
+                      "Succeeded"
+                    ]
+                  },
+                  "else": {
+                    "actions": {}
+                  },
+                  "expression": {
+                    "and": [
+                      {
+                        "not": {
+                          "equals": [
+                            "@variables('DayOfTheWeek')",
+                            0
+                          ]
+                        }
+                      },
+                      {
+                        "not": {
+                          "equals": [
+                            "@variables('DayOfTheWeek')",
+                            6
+                          ]
+                        }
+                      },
+                      {
+                        "equals": [
+                          "@variables('IsTodayHoliday')",
+                          "@false"
+                        ]
+                      }
+                    ]
+                  },
+                  "type": "If"
+                }
+              },
+              "runAfter": {
+                "Initialize_DayOfTheWeek": [
+                  "Succeeded"
+                ]
+              },
+              "else": {
+                "actions": {
+                  "Delete_Capacity": {
+                    "type": "ApiConnection",
+                    "inputs": {
+                      "host": {
+                        "connection": {
+                          "name": "@parameters('$connections')['arm-1']['connectionId']"
+                        }
+                      },
+                      "method": "delete",
+                      "path": "/subscriptions/@{encodeURIComponent(parameters('SubscriptionID'))}/resourcegroups/@{encodeURIComponent(parameters('ResourceGroup'))}/providers/@{encodeURIComponent('Microsoft.SecurityCopilot')}/@{encodeURIComponent('capacities/',parameters('CapacityName'))}",
+                      "queries": {
+                        "x-ms-api-version": "2023-12-01-preview"
+                      }
+                    }
+                  }
+                }
+              },
+              "expression": {
+                "and": [
+                  {
+                    "not": {
+                      "equals": [
+                        "@parameters('NumberOfSCUs')",
+                        0
+                      ]
+                    }
+                  }
+                ]
+              },
+              "type": "If"
+            },
+            "Initialize_DayOfTheWeek": {
+              "runAfter": {
+                "Initialize_IsTodayHoliday": [
+                  "Succeeded"
+                ]
+              },
+              "type": "InitializeVariable",
+              "inputs": {
+                "variables": [
+                  {
+                    "name": "DayOfTheWeek",
+                    "type": "integer",
+                    "value": "@int(dayOfWeek(convertFromUtc(concat(variables('Today'),'T00:00:00.0000000Z'),'W. Europe Standard Time')))"
+                  }
+                ]
+              }
+            }
+          },
+          "outputs": {}
+        },
+        "parameters": {
+          "$connections": {
+            "value": {
+              "arm-1": {
+                "id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',parameters('logicAppLocation'),'/managedApis/arm')]",
+                "connectionId": "[resourceId('Microsoft.Web/connections', parameters('connection_name'))]",
+                "connectionName": "[parameters('connection_name')]"
+              }
+            }
+          }
+        }
+      }
+    },
+    {
+      "type": "Microsoft.Web/connections",
+      "apiVersion": "2016-06-01",
+      "location": "[parameters('logicAppLocation')]",
+      "name": "[parameters('connection_name')]",
+      "properties": {
+        "api": {
+          "id": "[concat('/subscriptions/',subscription().subscriptionId,'/providers/Microsoft.Web/locations/',parameters('logicAppLocation'),'/managedApis/arm')]"
+        },
+        "displayName": "[parameters('connection_displayName')]",
+        "parameterValues": {          
+        }
+      }
+    }
+  ],
+  "outputs": {}
+}