diff --git a/.github/workflows/generate-templates.yml b/.github/workflows/generate-templates.yml
new file mode 100644
index 000000000..3b4c836bb
--- /dev/null
+++ b/.github/workflows/generate-templates.yml
@@ -0,0 +1,83 @@
+# Workflow for generating (arm/bicep/etc) templates for each alert
+name: Generate Templates
+
+on:
+ # Runs on pushes targeting the default branch
+ push:
+ branches:
+ - main
+ paths:
+ - 'services/**/alerts.yaml'
+ - 'tooling/generate-templates/**'
+
+ # Allows you to run this workflow manually from the Actions tab
+ workflow_dispatch: {}
+
+jobs:
+ generate-templates:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ ref: main
+ submodules: recursive
+ fetch-depth: 0
+
+ - name: Setup Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: '3.12' # install the python version needed
+
+ - name: Install Python Packages and Requirements
+ run: |
+ python -m pip install --upgrade pip
+ pip install -r requirements.txt
+ working-directory: tooling/generate-templates
+
+ - name: Generate Templates
+ id: generate
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ git config --local user.email "github-actions[bot]@users.noreply.github.com"
+ git config --local user.name "github-actions[bot]"
+
+ git checkout -b github-action-generate-templates
+
+ # Generate templates for alerts
+ echo "Generating templates for alerts..."
+ python tooling/generate-templates/generate-templates.py --path services --output services --template_path tooling/generate-templates/templates
+
+ # Check if there are any changes in the services directory
+ git add services
+
+ # Check if there are any changes to commit
+ if [[ `git status --porcelain` ]]; then
+ git commit -m "[GitHub Action - Generate Templates] Generate templates for alerts"
+
+ # Push changes to the current branch
+ git push --set-upstream origin github-action-generate-templates --force
+
+ prs=$(gh pr list \
+ --repo "$GITHUB_REPOSITORY" \
+ --head 'github-action-generate-templates' \
+ --base 'main' \
+ --json title \
+ --jq 'length')
+
+ if ((prs > 0)); then
+ echo "skippr=true" >> "$GITHUB_OUTPUT"
+ fi
+ else
+ echo "skippr=true" >> "$GITHUB_OUTPUT"
+ fi
+ - name: Create pull request
+ if: '!steps.generate.outputs.skippr'
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ # Create a pull request
+ echo "Creating a pull request..."
+ gh pr --repo ${{ github.repository }} create --title "[GitHub Action - Generate Templates] Generate templates for alerts" --body "This PR was automatically generated by the workflow." --base main --head github-action-generate-templates
+
diff --git a/.github/workflows/hugo-build-pr-check.yml b/.github/workflows/hugo-build-pr-check.yml
index 847761cfd..4c659dc4a 100644
--- a/.github/workflows/hugo-build-pr-check.yml
+++ b/.github/workflows/hugo-build-pr-check.yml
@@ -7,6 +7,11 @@ on:
- main
paths:
- 'docs/**'
+ - 'services/**/alerts.yaml'
+ - 'services/**/*.md'
+ - 'services/**/templates/**'
+ - 'tooling/export-alerts/**'
+ - 'tooling/generate-templates/**'
- '.github/workflows/hugo-build-pr-check.yml'
workflow_dispatch: {}
diff --git a/.github/workflows/hugo-site-build.yml b/.github/workflows/hugo-site-build.yml
index a46eb5120..40335b5b3 100644
--- a/.github/workflows/hugo-site-build.yml
+++ b/.github/workflows/hugo-site-build.yml
@@ -10,6 +10,7 @@ on:
- 'docs/**'
- 'services/**/alerts.yaml'
- 'services/**/*.md'
+ - 'services/**/templates/**'
- 'tooling/export-alerts/**'
- 'tooling/generate-templates/**'
@@ -69,12 +70,6 @@ jobs:
python export-alerts.py --path ../../services --template ./alerts-template.xlsx --output-xls ../../services/amba-alerts.xlsx --output-json ../../services/amba-alerts.json --output-yaml ../../services/amba-alerts.yaml
working-directory: tooling/export-alerts
- - name: Generate Templates
- run: |
- pip install -r requirements.txt
- python generate-templates.py --path ../../services --output ../../artifacts/templates
- working-directory: tooling/generate-templates
-
- name: Setup Pages
id: pages
uses: actions/configure-pages@v5
diff --git a/docs/layouts/partials/templates/template-tabs.html b/docs/layouts/partials/templates/template-tabs.html
index 61b59b461..33acd7d25 100644
--- a/docs/layouts/partials/templates/template-tabs.html
+++ b/docs/layouts/partials/templates/template-tabs.html
@@ -1,8 +1,9 @@
{{ $category := .category }}
{{ $type := .type }}
-{{ $filename := printf "%s.json" .alert.guid | printf "%s"}}
-{{ $version := readFile "artifacts/templates/latest_version.txt" }}
-{{ $file := path.Join "artifacts/templates" $version $category $type $filename }}
+{{ $alert_name := .alert.name | replaceRE `[^a-zA-Z0-9-]` "" }}
+{{ $alert_name := printf "%s_%s" $alert_name .alert.guid }}
+{{ $filename := printf "%s.json" $alert_name | printf "%s"}}
+{{ $file := path.Join "services" $category $type "templates/arm" $filename }}
- {{ $filename := printf "%s.bicep" .alert.guid | printf "%s"}}
- {{ $file := path.Join "artifacts/templates" $version $category $type $filename }}
+ {{ $filename := printf "%s.bicep" $alert_name | printf "%s"}}
+ {{ $file := path.Join "services" $category $type "templates/bicep" $filename }}
{{ $data := readFile $file }}
{{ highlight $data "bicep" }}
diff --git a/tooling/generate-templates/generate-templates.py b/tooling/generate-templates/generate-templates.py
index d6c64b66c..3f2572d50 100644
--- a/tooling/generate-templates/generate-templates.py
+++ b/tooling/generate-templates/generate-templates.py
@@ -2,13 +2,13 @@
import yaml
import json
import argparse
-import datetime
# Parse command line arguments
def parseArguments():
parser = argparse.ArgumentParser(description='This script will generate ARM and Bicep templates for each alert.')
parser.add_argument('-p', '--path', type=str, required=False, metavar='path', help='Path to services directory', default='../../services')
- parser.add_argument('-o', '--output', type=str, required=False, metavar='output', help='Path to output directory', default='../../artifacts/templates')
+ parser.add_argument('-o', '--output', type=str, required=False, metavar='output', help='Path to output directory', default='../../services')
+ parser.add_argument('-s', '--template_path', type=str, required=False, metavar='template_path', help='Path to templates directory', default='templates')
parser.add_argument('-t', '--telemetry_pid', type=str, required=False, metavar='telemetry_pid', help='Telemetry PID', default='pid-8bb7cf8a-bcf7-4264-abcb-703ace2fc84d')
args = parser.parse_args()
@@ -18,8 +18,7 @@ def readYamlData(dir, export_hidden):
# Walk the directory tree and load all the alerts.yaml files
# into a list of dictionaries using the folder path as the structure
- # for the dictionary. This will allow us to easily export the data
- # to a CSV or XLS file.
+ # for the dictionary.
data = {}
for root, dirs, files in os.walk(dir):
for file in files:
@@ -45,12 +44,12 @@ def readYamlData(dir, export_hidden):
return data
-def readTemplates():
+def readTemplates(template_path):
arm = {}
bicep = {}
# Read ARM templates from arm directory into a string
- for root, dirs, files in os.walk(os.path.join('.', 'arm')):
+ for root, dirs, files in os.walk(os.path.join(template_path, 'arm')):
for file in files:
if file.endswith('.json'):
# read the file into a string
@@ -58,7 +57,7 @@ def readTemplates():
arm[file.replace('.json','')] = f.read()
# Read Bicep templates from arm directory into a string
- for root, dirs, files in os.walk(os.path.join('.', 'bicep')):
+ for root, dirs, files in os.walk(os.path.join(template_path, 'bicep')):
for file in files:
if file.endswith('.bicep'):
# read the file into a string
@@ -73,30 +72,35 @@ def main():
data = readYamlData(args.path, False)
- arm, bicep = readTemplates()
+ arm, bicep = readTemplates(args.template_path)
import datetime
+ import re
- # Get the current timestamp
- timestamp = datetime.datetime.now()
+ for category in data:
+ for resourceType in data[category]:
- # Format it as a string
- formatted_timestamp = timestamp.strftime("%Y%m%d%H%M%S")
+ print(f"Generating templates for {len(data[category][resourceType])} alerts in {category}/{resourceType}...")
- # Create the output directory if it doesn't exist
- os.makedirs(args.output, exist_ok=True)
+ # create directories based on template types if it doesn't exist
+ os.makedirs(os.path.join(args.output, category, resourceType, "templates", "arm"), exist_ok=True)
+ os.makedirs(os.path.join(args.output, category, resourceType, "templates", "bicep"), exist_ok=True)
- # Write timestamp to a file
- with open(os.path.join(args.output, 'latest_version.txt'), 'w') as f:
- f.write(formatted_timestamp)
+ # Remove all files in arm and bicep directories
+ for root, dirs, files in os.walk(os.path.join(args.output, category, resourceType, "templates", "arm")):
+ for file in files:
+ os.remove(os.path.join(root, file))
- for category in data:
- for resourceType in data[category]:
- # create directory based on resourceType if it doesn't exist
- os.makedirs(os.path.join(args.output, formatted_timestamp, category, resourceType), exist_ok=True)
+ for root, dirs, files in os.walk(os.path.join(args.output, category, resourceType, "templates", "bicep")):
+ for file in files:
+ os.remove(os.path.join(root, file))
+
+ alert_file_names = []
for alert in data[category][resourceType]:
arm_template_type = ""
+ alert_file_name = re.sub(r'[^a-zA-Z0-9-]', '', alert['name']) + '_' + alert['guid']
+
if alert["type"] == "Metric":
if 'criterionType' in alert["properties"]:
if alert["properties"]["criterionType"] == "StaticThresholdCriterion":
@@ -114,6 +118,8 @@ def main():
template_type = "activity-resourcehealth"
elif alert["properties"]["category"] == "ServiceHealth":
template_type = "activity-servicehealth"
+ else:
+ continue
if template_type == "":
print(f"Template not found for alert {alert['guid']}")
@@ -125,21 +131,21 @@ def main():
arm_template = arm_template.replace("##TELEMETRY_PID##", args.telemetry_pid)
bicep_template = bicep_template.replace("##TELEMETRY_PID##", args.telemetry_pid)
- if 'description' in alert and alert["description"]:
+ if 'description' in alert and alert["description"] is not None:
arm_template = arm_template.replace("##DESCRIPTION##", alert["description"])
bicep_template = bicep_template.replace("##DESCRIPTION##", alert["description"])
else:
arm_template = arm_template.replace("##DESCRIPTION##", "")
bicep_template = bicep_template.replace("##DESCRIPTION##", "")
- if 'severity' in alert["properties"] and alert["properties"]["severity"]:
+ if 'severity' in alert["properties"] and alert["properties"]["severity"] is not None:
arm_template = arm_template.replace("##SEVERITY##", str(int(alert["properties"]["severity"])))
bicep_template = bicep_template.replace("##SEVERITY##", str(int(alert["properties"]["severity"])))
else:
arm_template = arm_template.replace("##SEVERITY##", "")
bicep_template = bicep_template.replace("##SEVERITY##", "")
- if 'autoMitigate' in alert["properties"] and alert["properties"]["autoMitigate"]:
+ if 'autoMitigate' in alert["properties"] and alert["properties"]["autoMitigate"] is not None:
if alert["properties"]["autoMitigate"] == True:
arm_template = arm_template.replace("##AUTO_MITIGATE##", "true")
bicep_template = bicep_template.replace("##AUTO_MITIGATE##", "true")
@@ -150,7 +156,7 @@ def main():
arm_template = arm_template.replace("##AUTO_MITIGATE##", "")
bicep_template = bicep_template.replace("##AUTO_MITIGATE##", "")
- if 'query' in alert["properties"] and alert["properties"]["query"]:
+ if 'query' in alert["properties"] and alert["properties"]["query"] is not None:
arm_template = arm_template.replace("##QUERY##", json.dumps(alert["properties"]["query"].replace("\n", " ")))
query = alert["properties"]["query"].replace("\n", " ").replace("'", "\\'")
bicep_template = bicep_template.replace("##QUERY##", query)
@@ -158,77 +164,83 @@ def main():
arm_template = arm_template.replace("##QUERY##", "")
bicep_template = bicep_template.replace("##QUERY##", "")
- if 'metricMeasureColumn' in alert["properties"] and alert["properties"]["metricMeasureColumn"]:
+ if 'metricName' in alert["properties"] and alert["properties"]["metricName"] is not None:
+ arm_template = arm_template.replace("##METRIC_NAME##", alert["properties"]["metricName"])
+ bicep_template = bicep_template.replace("##METRIC_NAME##", alert["properties"]["metricName"])
+ else:
+ arm_template = arm_template.replace("##METRIC_NAME##", "")
+ bicep_template = bicep_template.replace("##METRIC_NAME##", "")
+
+ if 'metricMeasureColumn' in alert["properties"] and alert["properties"]["metricMeasureColumn"] is not None:
arm_template = arm_template.replace("##METRIC_MEASURE_COLUMN##", alert["properties"]["metricMeasureColumn"])
bicep_template = bicep_template.replace("##METRIC_MEASURE_COLUMN##", alert["properties"]["metricMeasureColumn"])
else:
arm_template = arm_template.replace("##METRIC_MEASURE_COLUMN##", "")
bicep_template = bicep_template.replace("##METRIC_MEASURE_COLUMN##", "")
- if 'resouceIdColumn' in alert["properties"] and alert["properties"]["resouceIdColumn"]:
+ if 'resouceIdColumn' in alert["properties"] and alert["properties"]["resouceIdColumn"] is not None:
arm_template = arm_template.replace("##RESOURCE_ID_COLUMN##", alert["properties"]["resouceIdColumn"])
bicep_template = bicep_template.replace("##RESOURCE_ID_COLUMN##", alert["properties"]["resouceIdColumn"])
else:
arm_template = arm_template.replace("##RESOURCE_ID_COLUMN##", "")
bicep_template = bicep_template.replace("##RESOURCE_ID_COLUMN##", "")
- if 'operator' in alert["properties"] and alert["properties"]["operator"]:
+ if 'operator' in alert["properties"] and alert["properties"]["operator"] is not None:
arm_template = arm_template.replace("##OPERATOR##", alert["properties"]["operator"])
bicep_template = bicep_template.replace("##OPERATOR##", alert["properties"]["operator"])
else:
arm_template = arm_template.replace("##OPERATOR##", "")
bicep_template = bicep_template.replace("##OPERATOR##", "")
- if 'failingPeriods' in alert["properties"] and alert["properties"]["failingPeriods"]["numberOfEvaluationPeriods"]:
+ if 'failingPeriods' in alert["properties"] and alert["properties"]["failingPeriods"]["numberOfEvaluationPeriods"] is not None:
arm_template = arm_template.replace("##FAILING_PERIODS_NUMBER_OF_EVALUATION_PERIODS##", str(int(alert["properties"]["failingPeriods"]["numberOfEvaluationPeriods"])))
bicep_template = bicep_template.replace("##FAILING_PERIODS_NUMBER_OF_EVALUATION_PERIODS##", str(int(alert["properties"]["failingPeriods"]["numberOfEvaluationPeriods"])))
else:
arm_template = arm_template.replace("##FAILING_PERIODS_NUMBER_OF_EVALUATION_PERIODS##", "")
bicep_template = bicep_template.replace("##FAILING_PERIODS_NUMBER_OF_EVALUATION_PERIODS##", "")
- if 'failingPeriods' in alert["properties"] and alert["properties"]["failingPeriods"]["numberOfEvaluationPeriods"]:
+ if 'failingPeriods' in alert["properties"] and alert["properties"]["failingPeriods"]["numberOfEvaluationPeriods"] is not None:
arm_template = arm_template.replace("##FAILING_PERIODS_MIN_FAILING_PERIODS_TO_ALERT##", str(int(alert["properties"]["failingPeriods"]["minFailingPeriodsToAlert"])))
bicep_template = bicep_template.replace("##FAILING_PERIODS_MIN_FAILING_PERIODS_TO_ALERT##", str(int(alert["properties"]["failingPeriods"]["minFailingPeriodsToAlert"])))
else:
arm_template = arm_template.replace("##FAILING_PERIODS_MIN_FAILING_PERIODS_TO_ALERT##", "")
bicep_template = bicep_template.replace("##FAILING_PERIODS_MIN_FAILING_PERIODS_TO_ALERT##", "")
- if 'threshold' in alert["properties"] and alert["properties"]["threshold"]:
- arm_template = arm_template.replace("##THRESHOLD##", str(int(alert["properties"]["threshold"])))
- bicep_template = bicep_template.replace("##THRESHOLD##", str(int(alert["properties"]["threshold"])))
+ if 'threshold' in alert["properties"] and alert["properties"]["threshold"] is not None:
+ # Convert the threshold to a float
+ threshold = float(alert["properties"]["threshold"])
+ threshold = str(round(threshold))
+ if threshold == "":
+ raise Exception(f"Threshold is empty for alert {alert['guid']}")
+
+ arm_template = arm_template.replace("##THRESHOLD##", threshold)
+ bicep_template = bicep_template.replace("##THRESHOLD##", threshold)
else:
arm_template = arm_template.replace("##THRESHOLD##", "")
bicep_template = bicep_template.replace("##THRESHOLD##", "")
- if 'timeAggregation' in alert["properties"] and alert["properties"]["timeAggregation"]:
+ if 'timeAggregation' in alert["properties"] and alert["properties"]["timeAggregation"] is not None:
arm_template = arm_template.replace("##TIME_AGGREGATION##", alert["properties"]["timeAggregation"])
bicep_template = bicep_template.replace("##TIME_AGGREGATION##", alert["properties"]["timeAggregation"])
else:
arm_template = arm_template.replace("##TIME_AGGREGATION##", "")
bicep_template = bicep_template.replace("##TIME_AGGREGATION##", "")
- if 'windowSize' in alert["properties"] and alert["properties"]["windowSize"]:
+ if 'windowSize' in alert["properties"] and alert["properties"]["windowSize"] is not None:
arm_template = arm_template.replace("##WINDOW_SIZE##", alert["properties"]["windowSize"])
bicep_template = bicep_template.replace("##WINDOW_SIZE##", alert["properties"]["windowSize"])
else:
arm_template = arm_template.replace("##WINDOW_SIZE##", "")
bicep_template = bicep_template.replace("##WINDOW_SIZE##", "")
- if 'evaluationFrequency' in alert["properties"] and alert["properties"]["evaluationFrequency"]:
+ if 'evaluationFrequency' in alert["properties"] and alert["properties"]["evaluationFrequency"] is not None:
arm_template = arm_template.replace("##EVALUATION_FREQUENCY##", alert["properties"]["evaluationFrequency"])
bicep_template = bicep_template.replace("##EVALUATION_FREQUENCY##", alert["properties"]["evaluationFrequency"])
else:
arm_template = arm_template.replace("##EVALUATION_FREQUENCY##", "")
bicep_template = bicep_template.replace("##EVALUATION_FREQUENCY##", "")
- if 'metricName' in alert["properties"] and alert["properties"]["metricName"]:
- arm_template = arm_template.replace("##METRIC_NAME##", alert["properties"]["metricName"])
- bicep_template = bicep_template.replace("##METRIC_NAME##", alert["properties"]["metricName"])
- else:
- arm_template = arm_template.replace("##METRIC_NAME##", "")
- bicep_template = bicep_template.replace("##METRIC_NAME##", "")
-
- if 'dimensions' in alert["properties"] and "dimensions" in alert["properties"]:
+ if 'dimensions' in alert["properties"] and alert["properties"]["dimensions"] is not None:
arm_template = arm_template.replace("##DIMENSIONS##", json.dumps(alert["properties"]["dimensions"]))
dimensions = []
@@ -246,17 +258,17 @@ def main():
bicep_template = bicep_template.replace("##DIMENSIONS##", "".join(dimensions))
else:
- arm_template = arm_template.replace("##DIMENSIONS##", "")
- bicep_template = bicep_template.replace("##DIMENSIONS##", "")
+ arm_template = arm_template.replace("##DIMENSIONS##", "[]")
+ bicep_template = bicep_template.replace("##DIMENSIONS##", "[]")
- if 'operationName' in alert["properties"] and alert["properties"]["operationName"]:
+ if 'operationName' in alert["properties"] and alert["properties"]["operationName"] is not None:
arm_template = arm_template.replace("##OPERATION_NAME##", alert["properties"]["operationName"])
bicep_template = bicep_template.replace("##OPERATION_NAME##", alert["properties"]["operationName"])
else:
arm_template = arm_template.replace("##OPERATION_NAME##", "")
bicep_template = bicep_template.replace("##OPERATION_NAME##", "")
- if 'status' in alert["properties"] and alert["properties"]["status"]:
+ if 'status' in alert["properties"] and alert["properties"]["status"] is not None:
arm_template = arm_template.replace("##STATUS##", json.dumps(alert["properties"]["status"]))
statuses = []
@@ -268,7 +280,7 @@ def main():
arm_template = arm_template.replace("##STATUS##", "")
bicep_template = bicep_template.replace("##STATUS##", "")
- if 'causes' in alert["properties"] and alert["properties"]["causes"]:
+ if 'causes' in alert["properties"] and alert["properties"]["causes"] is not None:
causes = []
for cause in alert["properties"]["causes"]:
@@ -293,7 +305,7 @@ def main():
arm_template = arm_template.replace("##CAUSES##", "")
bicep_template = bicep_template.replace("##CAUSES##", "")
- if 'currentHealthStatus' in alert["properties"] and alert["properties"]["currentHealthStatus"]:
+ if 'currentHealthStatus' in alert["properties"] and alert["properties"]["currentHealthStatus"] is not None:
currentHealthStatuses = []
for currentHealthStatus in alert["properties"]["currentHealthStatus"]:
currentHealthStatuses.append(f"""
@@ -317,19 +329,24 @@ def main():
arm_template = arm_template.replace("##CURRENT_HEALTH_STATUS##", "")
bicep_template = bicep_template.replace("##CURRENT_HEALTH_STATUS##", "")
- if 'incidentType' in alert["properties"] and alert["properties"]["incidentType"]:
+ if 'incidentType' in alert["properties"] and alert["properties"]["incidentType"] is not None:
arm_template = arm_template.replace("##INCIDENT_TYPE##", alert["properties"]["incidentType"])
bicep_template = bicep_template.replace("##INCIDENT_TYPE##", alert["properties"]["incidentType"])
else:
arm_template = arm_template.replace("##INCIDENT_TYPE##", "")
bicep_template = bicep_template.replace("##INCIDENT_TYPE##", "")
- # Save the ARM template
- with open(os.path.join(args.output, formatted_timestamp, category, resourceType, alert['guid'] + '.json'), 'w') as f:
+ # Check if alert name already exists
+ if alert_file_name in alert_file_names:
+ raise Exception(f"Alert name {alert_file_name} already exists in the list of alerts for {category}/{resourceType}")
+ else:
+ alert_file_names.append(alert_file_name)
+
+ with open(os.path.join(args.output, category, resourceType, "templates", "arm", alert_file_name + '.json'), 'w') as f:
f.write(arm_template)
# Save the Bicep template
- with open(os.path.join(args.output, formatted_timestamp, category, resourceType, alert['guid'] + '.bicep'), 'w') as f:
+ with open(os.path.join(args.output, category, resourceType, "templates", "bicep", alert_file_name + '.bicep'), 'w') as f:
f.write(bicep_template)
if __name__ == '__main__':
diff --git a/tooling/generate-templates/templates/arm/activity-administrative.json b/tooling/generate-templates/templates/arm/activity-administrative.json
new file mode 100644
index 000000000..a48293408
--- /dev/null
+++ b/tooling/generate-templates/templates/arm/activity-administrative.json
@@ -0,0 +1,95 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "alertName": {
+ "type": "string",
+ "metadata": {
+ "description": "Unique name (within the Resource Group) for the Activity log alert."
+ }
+ },
+ "alertDescription": {
+ "type": "string",
+ "defaultValue": "##DESCRIPTION##",
+ "metadata": {
+ "description": "Description of alert"
+ }
+ },
+ "isEnabled": {
+ "type": "bool",
+ "defaultValue": true,
+ "metadata": {
+ "description": "Indicates whether or not the alert is enabled."
+ }
+ },
+ "currentDateTimeUtcNow": {
+ "type": "string",
+ "defaultValue": "[utcNow()]",
+ "metadata": {
+ "description": "The current date and time using the utcNow function. Used for deployment name uniqueness"
+ }
+ },
+ "telemetryOptOut": {
+ "type": "string",
+ "defaultValue": "No",
+ "allowedValues": [
+ "Yes",
+ "No"
+ ],
+ "metadata": {
+ "description": "The customer usage identifier used for telemetry purposes. The default value of False enables telemetry. The value of True disables telemetry."
+ }
+ }
+ },
+ "variables": {
+ "pidDeploymentName": "[take(concat('##TELEMETRY_PID##-', uniqueString(resourceGroup().id, parameters('alertName'), parameters('currentDateTimeUtcNow'))), 64)]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Insights/activityLogAlerts",
+ "apiVersion": "2017-04-01",
+ "name": "[parameters('alertName')]",
+ "location": "Global",
+ "tags": {
+ "_deployed_by_amba": true
+ },
+ "properties": {
+ "description": "[parameters('alertDescription')]",
+ "scopes": [
+ "[subscription().id]"
+ ],
+ "enabled": "[parameters('isEnabled')]",
+ "condition": {
+ "allOf": [
+ {
+ "field": "category",
+ "equals": "Administrative"
+ },
+ {
+ "field": "operationName",
+ "equals": "##OPERATION_NAME##"
+ },
+ {
+ "field": "status",
+ "containsAny": ##STATUS##
+ }
+ ]
+ }
+ }
+ },
+ {
+ "condition": "[equals(parameters('telemetryOptOut'), 'No')]",
+ "apiVersion": "2020-06-01",
+ "name": "[variables('pidDeploymentName')]",
+ "type": "Microsoft.Resources/deployments",
+ "properties": {
+ "mode": "Incremental",
+ "template": {
+ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "resources": []
+ }
+ }
+ }
+ ]
+}
diff --git a/tooling/generate-templates/templates/arm/activity-resourcehealth.json b/tooling/generate-templates/templates/arm/activity-resourcehealth.json
new file mode 100644
index 000000000..a25574c0f
--- /dev/null
+++ b/tooling/generate-templates/templates/arm/activity-resourcehealth.json
@@ -0,0 +1,95 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "alertName": {
+ "type": "string",
+ "metadata": {
+ "description": "Unique name (within the Resource Group) for the Activity log alert."
+ }
+ },
+ "alertDescription": {
+ "type": "string",
+ "defaultValue": "##DESCRIPTION##",
+ "metadata": {
+ "description": "Description of alert"
+ }
+ },
+ "isEnabled": {
+ "type": "bool",
+ "defaultValue": true,
+ "metadata": {
+ "description": "Indicates whether or not the alert is enabled."
+ }
+ },
+ "currentDateTimeUtcNow": {
+ "type": "string",
+ "defaultValue": "[utcNow()]",
+ "metadata": {
+ "description": "The current date and time using the utcNow function. Used for deployment name uniqueness"
+ }
+ },
+ "telemetryOptOut": {
+ "type": "string",
+ "defaultValue": "No",
+ "allowedValues": [
+ "Yes",
+ "No"
+ ],
+ "metadata": {
+ "description": "The customer usage identifier used for telemetry purposes. The default value of False enables telemetry. The value of True disables telemetry."
+ }
+ }
+ },
+ "variables": {
+ "pidDeploymentName": "[take(concat('##TELEMETRY_PID##-', uniqueString(resourceGroup().id, parameters('alertName'), parameters('currentDateTimeUtcNow'))), 64)]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Insights/activityLogAlerts",
+ "apiVersion": "2017-04-01",
+ "name": "[parameters('alertName')]",
+ "location": "Global",
+ "tags": {
+ "_deployed_by_amba": true
+ },
+ "properties": {
+ "description": "[parameters('alertDescription')]",
+ "scopes": [
+ "[subscription().id]"
+ ],
+ "enabled": "[parameters('isEnabled')]",
+ "condition": {
+ "allOf": [
+ {
+ "field": "category",
+ "equals": "ResourceHealth"
+ },
+ {
+ "anyOf": [##CAUSES##
+ ]
+ },
+ {
+ "anyOf": [##CURRENT_HEALTH_STATUS##
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "condition": "[equals(parameters('telemetryOptOut'), 'No')]",
+ "apiVersion": "2020-06-01",
+ "name": "[variables('pidDeploymentName')]",
+ "type": "Microsoft.Resources/deployments",
+ "properties": {
+ "mode": "Incremental",
+ "template": {
+ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "resources": []
+ }
+ }
+ }
+ ]
+}
diff --git a/tooling/generate-templates/templates/arm/activity-servicehealth.json b/tooling/generate-templates/templates/arm/activity-servicehealth.json
new file mode 100644
index 000000000..796bd3784
--- /dev/null
+++ b/tooling/generate-templates/templates/arm/activity-servicehealth.json
@@ -0,0 +1,91 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "alertName": {
+ "type": "string",
+ "metadata": {
+ "description": "Unique name (within the Resource Group) for the Activity log alert."
+ }
+ },
+ "alertDescription": {
+ "type": "string",
+ "defaultValue": "##DESCRIPTION##",
+ "metadata": {
+ "description": "Description of alert"
+ }
+ },
+ "isEnabled": {
+ "type": "bool",
+ "defaultValue": true,
+ "metadata": {
+ "description": "Indicates whether or not the alert is enabled."
+ }
+ },
+ "currentDateTimeUtcNow": {
+ "type": "string",
+ "defaultValue": "[utcNow()]",
+ "metadata": {
+ "description": "The current date and time using the utcNow function. Used for deployment name uniqueness"
+ }
+ },
+ "telemetryOptOut": {
+ "type": "string",
+ "defaultValue": "No",
+ "allowedValues": [
+ "Yes",
+ "No"
+ ],
+ "metadata": {
+ "description": "The customer usage identifier used for telemetry purposes. The default value of False enables telemetry. The value of True disables telemetry."
+ }
+ }
+ },
+ "variables": {
+ "pidDeploymentName": "[take(concat('##TELEMETRY_PID-', uniqueString(resourceGroup().id, parameters('alertName'), parameters('currentDateTimeUtcNow'))), 64)]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Insights/activityLogAlerts",
+ "apiVersion": "2017-04-01",
+ "name": "[parameters('alertName')]",
+ "location": "Global",
+ "tags": {
+ "_deployed_by_amba": true
+ },
+ "properties": {
+ "description": "[parameters('alertDescription')]",
+ "scopes": [
+ "[subscription().id]"
+ ],
+ "enabled": "[parameters('isEnabled')]",
+ "condition": {
+ "allOf": [
+ {
+ "field": "category",
+ "equals": "ServiceHealth"
+ },
+ {
+ "field": "properties.incidentType",
+ "equals": "##INCIDENT_TYPE##"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "condition": "[equals(parameters('telemetryOptOut'), 'No')]",
+ "apiVersion": "2020-06-01",
+ "name": "[variables('pidDeploymentName')]",
+ "type": "Microsoft.Resources/deployments",
+ "properties": {
+ "mode": "Incremental",
+ "template": {
+ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "resources": []
+ }
+ }
+ }
+ ]
+}
diff --git a/tooling/generate-templates/templates/arm/log.json b/tooling/generate-templates/templates/arm/log.json
new file mode 100644
index 000000000..c2a583ca8
--- /dev/null
+++ b/tooling/generate-templates/templates/arm/log.json
@@ -0,0 +1,256 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "alertName": {
+ "type": "string",
+ "minLength": 1,
+ "metadata": {
+ "description": "Name of the alert"
+ }
+ },
+ "alertDescription": {
+ "type": "string",
+ "defaultValue": "##DESCRIPTION##",
+ "metadata": {
+ "description": "Description of alert"
+ }
+ },
+ "isEnabled": {
+ "type": "bool",
+ "defaultValue": true,
+ "metadata": {
+ "description": "Specifies whether the alert is enabled"
+ }
+ },
+ "checkWorkspaceAlertsStorageConfigured": {
+ "type": "bool",
+ "defaultValue": false,
+ "metadata": {
+ "description": "Specifies whether to check linked storage and fail creation if the storage was not found"
+ }
+ },
+ "resourceId": {
+ "type": "string",
+ "minLength": 1,
+ "metadata": {
+ "description": "Full Resource ID of the resource emitting the metric that will be used for the comparison. For example /subscriptions/00000000-0000-0000-0000-0000-00000000/resourceGroups/ResourceGroupName/providers/Microsoft.compute/virtualMachines/VM_xyz"
+ }
+ },
+ "muteActionsDuration": {
+ "type": "string",
+ "allowedValues": [
+ "PT1M",
+ "PT5M",
+ "PT15M",
+ "PT30M",
+ "PT1H",
+ "PT6H",
+ "PT12H",
+ "PT24H"
+ ],
+ "metadata": {
+ "description": "Mute actions for the chosen period of time (in ISO 8601 duration format) after the alert is fired."
+ }
+ },
+ "alertSeverity": {
+ "type": "int",
+ "defaultValue": ##SEVERITY##,
+ "allowedValues": [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4
+ ],
+ "metadata": {
+ "description": "Severity of alert {0,1,2,3,4}"
+ }
+ },
+ "autoMitigate": {
+ "type": "bool",
+ "defaultValue": ##AUTO_MITIGATE##,
+ "metadata": {
+ "description": "Specifies whether the alert will automatically resolve"
+ }
+ },
+ "query": {
+ "type": "string",
+ "minLength": 1,
+ "defaultValue": ##QUERY##,
+ "metadata": {
+ "description": "Name of the metric used in the comparison to activate the alert."
+ }
+ },
+ "metricMeasureColumn": {
+ "type": "string",
+ "defaultValue": "##METRIC_MEASURE_COLUMN##",
+ "metadata": {
+ "description": "Name of the measure column used in the alert evaluation."
+ }
+ },
+ "resourceIdColumn": {
+ "type": "string",
+ "defaultValue": "##RESOURCE_ID_COLUMN##",
+ "metadata": {
+ "description": "Name of the resource ID column used in the alert targeting the alerts."
+ }
+ },
+ "operator": {
+ "type": "string",
+ "defaultValue": "##OPERATOR##",
+ "allowedValues": [
+ "Equals",
+ "GreaterThan",
+ "GreaterThanOrEqual",
+ "LessThan",
+ "LessThanOrEqual"
+ ],
+ "metadata": {
+ "description": "Operator comparing the current value with the threshold value."
+ }
+ },
+ "threshold": {
+ "type": "string",
+ "defaultValue": "##THRESHOLD##",
+ "metadata": {
+ "description": "The threshold value at which the alert is activated."
+ }
+ },
+ "numberOfEvaluationPeriods": {
+ "type": "int",
+ "defaultValue": ##FAILING_PERIODS_NUMBER_OF_EVALUATION_PERIODS##,
+ "metadata": {
+ "description": "The number of periods to check in the alert evaluation."
+ }
+ },
+ "minFailingPeriodsToAlert": {
+ "type": "int",
+ "defaultValue": ##FAILING_PERIODS_MIN_FAILING_PERIODS_TO_ALERT##,
+ "metadata": {
+ "description": "The number of unhealthy periods to alert on (must be lower or equal to numberOfEvaluationPeriods)."
+ }
+ },
+ "timeAggregation": {
+ "type": "string",
+ "defaultValue": "##TIME_AGGREGATION##",
+ "allowedValues": [
+ "Average",
+ "Minimum",
+ "Maximum",
+ "Total",
+ "Count"
+ ],
+ "metadata": {
+ "description": "How the data that is collected should be combined over time."
+ }
+ },
+ "windowSize": {
+ "type": "string",
+ "defaultValue": "##WINDOW_SIZE##",
+ "allowedValues": [
+ "PT1M",
+ "PT5M",
+ "PT15M",
+ "PT30M",
+ "PT1H",
+ "PT6H",
+ "PT12H",
+ "PT24H",
+ "PT1D"
+ ],
+ "metadata": {
+ "description": "Period of time used to monitor alert activity based on the threshold. Must be between one minute and one day. ISO 8601 duration format."
+ }
+ },
+ "evaluationFrequency": {
+ "type": "string",
+ "defaultValue": "##EVALUATION_FREQUENCY##",
+ "allowedValues": [
+ "PT5M",
+ "PT15M",
+ "PT30M",
+ "PT1H"
+ ],
+ "metadata": {
+ "description": "how often the metric alert is evaluated represented in ISO 8601 duration format"
+ }
+ },
+ "currentDateTimeUtcNow": {
+ "type": "string",
+ "defaultValue": "[utcNow()]",
+ "metadata": {
+ "description": "The current date and time using the utcNow function. Used for deployment name uniqueness"
+ }
+ },
+ "telemetryOptOut": {
+ "type": "string",
+ "defaultValue": "No",
+ "allowedValues": [
+ "Yes",
+ "No"
+ ],
+ "metadata": {
+ "description": "The customer usage identifier used for telemetry purposes. The default value of False enables telemetry. The value of True disables telemetry."
+ }
+ }
+ },
+ "variables": {
+ "pidDeploymentName": "[take(concat('##TELEMETRY_PID##-', uniqueString(resourceGroup().id, parameters('alertName'), parameters('currentDateTimeUtcNow'))), 64)]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Insights/scheduledQueryRules",
+ "apiVersion": "2021-08-01",
+ "name": "[parameters('alertName')]",
+ "location": "[resourceGroup().location]",
+ "tags": {
+ "_deployed_by_amba": true
+ },
+ "properties": {
+ "description": "[parameters('alertDescription')]",
+ "severity": "[parameters('alertSeverity')]",
+ "enabled": "[parameters('isEnabled')]",
+ "scopes": [
+ "[parameters('resourceId')]"
+ ],
+ "evaluationFrequency": "[parameters('evaluationFrequency')]",
+ "windowSize": "[parameters('windowSize')]",
+ "criteria": {
+ "allOf": [
+ {
+ "query": "[parameters('query')]",
+ "metricMeasureColumn": "[parameters('metricMeasureColumn')]",
+ "resourceIdColumn": "[parameters('resourceIdColumn')]",
+ "dimensions": ##DIMENSIONS##,
+ "operator": "[parameters('operator')]",
+ "threshold": "[parameters('threshold')]",
+ "timeAggregation": "[parameters('timeAggregation')]",
+ "failingPeriods": {
+ "numberOfEvaluationPeriods": "[parameters('numberOfEvaluationPeriods')]",
+ "minFailingPeriodsToAlert": "[parameters('minFailingPeriodsToAlert')]"
+ }
+ }
+ ]
+ },
+ "muteActionsDuration": "[parameters('muteActionsDuration')]",
+ "autoMitigate": "[parameters('autoMitigate')]",
+ "checkWorkspaceAlertsStorageConfigured": "[parameters('checkWorkspaceAlertsStorageConfigured')]"
+ }
+ },
+ {
+ "condition": "[equals(parameters('telemetryOptOut'), 'No')]",
+ "apiVersion": "2020-06-01",
+ "name": "[variables('pidDeploymentName')]",
+ "type": "Microsoft.Resources/deployments",
+ "properties": {
+ "mode": "Incremental",
+ "template": {
+ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "resources": []
+ }
+ }
+ }
+ ]
+}
diff --git a/tooling/generate-templates/templates/arm/metric-dynamic.json b/tooling/generate-templates/templates/arm/metric-dynamic.json
new file mode 100644
index 000000000..f7184178f
--- /dev/null
+++ b/tooling/generate-templates/templates/arm/metric-dynamic.json
@@ -0,0 +1,219 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "alertName": {
+ "type": "string",
+ "minLength": 1,
+ "metadata": {
+ "description": "Name of the alert"
+ }
+ },
+ "alertDescription": {
+ "type": "string",
+ "defaultValue": "##DESCRIPTION##",
+ "metadata": {
+ "description": "Description of alert"
+ }
+ },
+ "targetResourceId": {
+ "type": "string",
+ "minLength": 1,
+ "metadata": {
+ "description": "List of Azure resource Ids seperated by a comma. For example - /subscriptions/00000000-0000-0000-0000-0000-00000000/resourceGroup/resource-group-name/Microsoft.compute/virtualMachines/vm-name"
+ }
+ },
+ "targetResourceRegion": {
+ "type": "string",
+ "metadata": {
+ "description": "Azure region in which target resources to be monitored are in (without spaces). For example: EastUS"
+ }
+ },
+ "targetResourceType": {
+ "type": "string",
+ "minLength": 1,
+ "metadata": {
+ "description": "Resource type of target resources to be monitored."
+ }
+ },
+ "isEnabled": {
+ "type": "bool",
+ "defaultValue": true,
+ "metadata": {
+ "description": "Specifies whether the alert is enabled"
+ }
+ },
+ "alertSeverity": {
+ "type": "int",
+ "defaultValue": ##SEVERITY##,
+ "allowedValues": [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4
+ ],
+ "metadata": {
+ "description": "Severity of alert {0,1,2,3,4}"
+ }
+ },
+ "operator": {
+ "type": "string",
+ "defaultValue": "##OPERATOR##",
+ "allowedValues": [
+ "GreaterThan",
+ "LessThan",
+ "GreaterOrLessThan"
+ ],
+ "metadata": {
+ "description": "Operator comparing the current value with the threshold value."
+ }
+ },
+ "alertSensitivity": {
+ "type": "string",
+ "defaultValue": "##ALERT_SENSITIVITY##",
+ "allowedValues": [
+ "High",
+ "Medium",
+ "Low"
+ ],
+ "metadata": {
+ "description": "Tunes how 'noisy' the Dynamic Thresholds alerts will be: 'High' will result in more alerts while 'Low' will result in fewer alerts."
+ }
+ },
+ "numberOfEvaluationPeriods": {
+ "type": "int",
+ "defaultValue": ##FAILING_PERIODS_NUMBER_OF_EVALUATION_PERIODS##,
+ "metadata": {
+ "description": "The number of periods to check in the alert evaluation."
+ }
+ },
+ "minFailingPeriodsToAlert": {
+ "type": "int",
+ "defaultValue": ##FAILING_PERIODS_MIN_FAILING_PERIODS_TO_ALERT##,
+ "metadata": {
+ "description": "The number of unhealthy periods to alert on (must be lower or equal to numberOfEvaluationPeriods)."
+ }
+ },
+ "timeAggregation": {
+ "type": "string",
+ "defaultValue": "##TIME_AGGREGATION##",
+ "allowedValues": [
+ "Average",
+ "Minimum",
+ "Maximum",
+ "Total",
+ "Count"
+ ],
+ "metadata": {
+ "description": "How the data that is collected should be combined over time."
+ }
+ },
+ "windowSize": {
+ "type": "string",
+ "defaultValue": "##WINDOW_SIZE##",
+ "allowedValues": [
+ "PT1M",
+ "PT5M",
+ "PT15M",
+ "PT30M",
+ "PT1H",
+ "PT6H",
+ "PT12H",
+ "PT24H",
+ "PT1D"
+ ],
+ "metadata": {
+ "description": "Period of time used to monitor alert activity based on the threshold. Must be between five minutes and one hour. ISO 8601 duration format."
+ }
+ },
+ "evaluationFrequency": {
+ "type": "string",
+ "defaultValue": "##EVALUATION_FREQUENCY##",
+ "allowedValues": [
+ "PT5M",
+ "PT15M",
+ "PT30M",
+ "PT1H"
+ ],
+ "metadata": {
+ "description": "how often the metric alert is evaluated represented in ISO 8601 duration format"
+ }
+ },
+ "currentDateTimeUtcNow": {
+ "type": "string",
+ "defaultValue": "[utcNow()]",
+ "metadata": {
+ "description": "The current date and time using the utcNow function. Used for deployment name uniqueness"
+ }
+ },
+ "telemetryOptOut": {
+ "type": "string",
+ "defaultValue": "No",
+ "allowedValues": [
+ "Yes",
+ "No"
+ ],
+ "metadata": {
+ "description": "The customer usage identifier used for telemetry purposes. The default value of False enables telemetry. The value of True disables telemetry."
+ }
+ }
+ },
+ "variables": {
+ "pidDeploymentName": "[take(concat('##TELEMETRY_PID##-', uniqueString(resourceGroup().id, parameters('alertName'), parameters('currentDateTimeUtcNow'))), 64)]",
+ "varTargetResourceId": "[split(parameters('targetResourceId'), ',')]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Insights/metricAlerts",
+ "apiVersion": "2018-03-01",
+ "name": "[parameters('alertName')]",
+ "location": "global",
+ "tags": {
+ "_deployed_by_amba": true
+ },
+ "properties": {
+ "description": "[parameters('alertDescription')]",
+ "scopes": "[variables('varTargetResourceId')]",
+ "targetResourceType": "[parameters('targetResourceType')]",
+ "targetResourceRegion": "[parameters('targetResourceRegion')]",
+ "severity": "[parameters('alertSeverity')]",
+ "enabled": "[parameters('isEnabled')]",
+ "evaluationFrequency": "[parameters('evaluationFrequency')]",
+ "windowSize": "[parameters('windowSize')]",
+ "criteria": {
+ "odata.type": "Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria",
+ "allOf": [
+ {
+ "criterionType": "DynamicThresholdCriterion",
+ "name": "1st criterion",
+ "metricName": "##METRIC_NAME##",
+ "dimensions": ##DIMENSIONS##,
+ "operator": "[parameters('operator')]",
+ "alertSensitivity": "[parameters('alertSensitivity')]",
+ "failingPeriods": {
+ "numberOfEvaluationPeriods": "[parameters('numberOfEvaluationPeriods')]",
+ "minFailingPeriodsToAlert": "[parameters('minFailingPeriodsToAlert')]"
+ },
+ "timeAggregation": "[parameters('timeAggregation')]"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "condition": "[equals(parameters('telemetryOptOut'), 'No')]",
+ "apiVersion": "2020-06-01",
+ "name": "[variables('pidDeploymentName')]",
+ "type": "Microsoft.Resources/deployments",
+ "properties": {
+ "mode": "Incremental",
+ "template": {
+ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "resources": []
+ }
+ }
+ }
+ ]
+}
diff --git a/tooling/generate-templates/templates/arm/metric-static.json b/tooling/generate-templates/templates/arm/metric-static.json
new file mode 100644
index 000000000..01d14e539
--- /dev/null
+++ b/tooling/generate-templates/templates/arm/metric-static.json
@@ -0,0 +1,199 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "alertName": {
+ "type": "string",
+ "minLength": 1,
+ "metadata": {
+ "description": "Name of the alert"
+ }
+ },
+ "alertDescription": {
+ "type": "string",
+ "defaultValue": "##DESCRIPTION##",
+ "metadata": {
+ "description": "Description of alert"
+ }
+ },
+ "targetResourceId": {
+ "type": "string",
+ "minLength": 1,
+ "metadata": {
+ "description": "List of Azure resource Ids seperated by a comma. For example - /subscriptions/00000000-0000-0000-0000-0000-00000000/resourceGroup/resource-group-name/Microsoft.compute/virtualMachines/vm-name"
+ }
+ },
+ "targetResourceRegion": {
+ "type": "string",
+ "metadata": {
+ "description": "Azure region in which target resources to be monitored are in (without spaces). For example: EastUS"
+ }
+ },
+ "targetResourceType": {
+ "type": "string",
+ "minLength": 1,
+ "metadata": {
+ "description": "Resource type of target resources to be monitored."
+ }
+ },
+ "isEnabled": {
+ "type": "bool",
+ "defaultValue": true,
+ "metadata": {
+ "description": "Specifies whether the alert is enabled"
+ }
+ },
+ "alertSeverity": {
+ "type": "int",
+ "defaultValue": ##SEVERITY##,
+ "allowedValues": [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4
+ ],
+ "metadata": {
+ "description": "Severity of alert {0,1,2,3,4}"
+ }
+ },
+ "operator": {
+ "type": "string",
+ "defaultValue": "##OPERATOR##",
+ "allowedValues": [
+ "Equals",
+ "GreaterThan",
+ "GreaterThanOrEqual",
+ "LessThan",
+ "LessThanOrEqual"
+ ],
+ "metadata": {
+ "description": "Operator comparing the current value with the threshold value."
+ }
+ },
+ "threshold": {
+ "type": "string",
+ "defaultValue": "##THRESHOLD##",
+ "metadata": {
+ "description": "The threshold value at which the alert is activated."
+ }
+ },
+ "timeAggregation": {
+ "type": "string",
+ "defaultValue": "##TIME_AGGREGATION##",
+ "allowedValues": [
+ "Average",
+ "Minimum",
+ "Maximum",
+ "Total",
+ "Count"
+ ],
+ "metadata": {
+ "description": "How the data that is collected should be combined over time."
+ }
+ },
+ "windowSize": {
+ "type": "string",
+ "defaultValue": "##WINDOW_SIZE##",
+ "allowedValues": [
+ "PT1M",
+ "PT5M",
+ "PT15M",
+ "PT30M",
+ "PT1H",
+ "PT6H",
+ "PT12H",
+ "PT24H",
+ "PT1D"
+ ],
+ "metadata": {
+ "description": "Period of time used to monitor alert activity based on the threshold. Must be between one minute and one day. ISO 8601 duration format."
+ }
+ },
+ "evaluationFrequency": {
+ "type": "string",
+ "defaultValue": "##EVALUATION_FREQUENCY##",
+ "allowedValues": [
+ "PT1M",
+ "PT5M",
+ "PT15M",
+ "PT30M",
+ "PT1H"
+ ],
+ "metadata": {
+ "description": "how often the metric alert is evaluated represented in ISO 8601 duration format"
+ }
+ },
+ "currentDateTimeUtcNow": {
+ "type": "string",
+ "defaultValue": "[utcNow()]",
+ "metadata": {
+ "description": "The current date and time using the utcNow function. Used for deployment name uniqueness"
+ }
+ },
+ "telemetryOptOut": {
+ "type": "string",
+ "defaultValue": "No",
+ "allowedValues": [
+ "Yes",
+ "No"
+ ],
+ "metadata": {
+ "description": "The customer usage identifier used for telemetry purposes. The default value of False enables telemetry. The value of True disables telemetry."
+ }
+ }
+ },
+ "variables": {
+ "pidDeploymentName": "[take(concat('##TELEMETRY_PID##-', uniqueString(resourceGroup().id, parameters('alertName'), parameters('currentDateTimeUtcNow'))), 64)]",
+ "varTargetResourceId": "[split(parameters('targetResourceId'), ',')]"
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Insights/metricAlerts",
+ "apiVersion": "2018-03-01",
+ "name": "[parameters('alertName')]",
+ "location": "global",
+ "tags": {
+ "_deployed_by_amba": true
+ },
+ "properties": {
+ "description": "[parameters('alertDescription')]",
+ "scopes": "[variables('varTargetResourceId')]",
+ "targetResourceType": "[parameters('targetResourceType')]",
+ "targetResourceRegion": "[parameters('targetResourceRegion')]",
+ "severity": "[parameters('alertSeverity')]",
+ "enabled": "[parameters('isEnabled')]",
+ "evaluationFrequency": "[parameters('evaluationFrequency')]",
+ "windowSize": "[parameters('windowSize')]",
+ "criteria": {
+ "odata.type": "Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria",
+ "allOf": [
+ {
+ "name": "1st criterion",
+ "metricName": "##METRIC_NAME##",
+ "dimensions": ##DIMENSIONS##,
+ "operator": "[parameters('operator')]",
+ "threshold": "[parameters('threshold')]",
+ "timeAggregation": "[parameters('timeAggregation')]",
+ "criterionType": "StaticThresholdCriterion"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "condition": "[equals(parameters('telemetryOptOut'), 'No')]",
+ "apiVersion": "2020-06-01",
+ "name": "[variables('pidDeploymentName')]",
+ "type": "Microsoft.Resources/deployments",
+ "properties": {
+ "mode": "Incremental",
+ "template": {
+ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "resources": []
+ }
+ }
+ }
+ ]
+}
diff --git a/tooling/generate-templates/templates/bicep/activity-administrative.bicep b/tooling/generate-templates/templates/bicep/activity-administrative.bicep
new file mode 100644
index 000000000..53c404616
--- /dev/null
+++ b/tooling/generate-templates/templates/bicep/activity-administrative.bicep
@@ -0,0 +1,68 @@
+@description('Unique name (within the Resource Group) for the Activity log alert.')
+@minLength(1)
+param alertName string
+
+@description('Description of alert')
+param alertDescription string = '##DESCRIPTION##'
+
+@description('Indicates whether or not the alert is enabled.')
+param isEnabled bool = true
+
+@description('"The current date and time using the utcNow function. Used for deployment name uniqueness')
+param currentDateTimeUtcNow string = utcNow()
+
+@description('The customer usage identifier used for telemetry purposes. The default value of False enables telemetry. The value of True disables telemetry.')
+@allowed([
+ 'Yes'
+ 'No'
+])
+param telemetryOptOut string = 'No'
+
+resource symbolicname 'Microsoft.Insights/activityLogAlerts@2023-01-01-preview' = {
+ name: alertName
+ location: 'Global'
+ tags: {
+ _deployed_by_amba: 'true'
+ }
+ properties: {
+ description: alertDescription
+ scopes: [
+ subscription().id
+ ]
+ enabled: isEnabled
+ condition: {
+ allOf: [
+ {
+ {
+ field: 'category'
+ equals: 'Administrative'
+ }
+ {
+ field: 'operationName'
+ equals: '##OPERATION_NAME##'
+ }
+ {
+ field: 'status'
+ containsAny: ##STATUS##
+ }
+ }
+ ]
+ }
+ }
+}
+
+var ambaTelemetryPidName = '##TELEMETRY_PID##-${uniqueString(resourceGroup().id, alertName, currentDateTimeUtcNow)}'
+resource ambaTelemetryPid 'Microsoft.Resources/deployments@2020-06-01' = if (telemetryOptOut == 'No') {
+ name: ambaTelemetryPidName
+ tags: {
+ _deployed_by_amba: 'true'
+ }
+ properties: {
+ mode: 'Incremental'
+ template: {
+ '$schema': 'https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#'
+ contentVersion: '1.0.0.0'
+ resources: []
+ }
+ }
+}
diff --git a/tooling/generate-templates/templates/bicep/activity-resourcehealth.bicep b/tooling/generate-templates/templates/bicep/activity-resourcehealth.bicep
new file mode 100644
index 000000000..e993691b9
--- /dev/null
+++ b/tooling/generate-templates/templates/bicep/activity-resourcehealth.bicep
@@ -0,0 +1,66 @@
+@description('Unique name (within the Resource Group) for the Activity log alert.')
+@minLength(1)
+param alertName string
+
+@description('Description of alert')
+param alertDescription string = '##DESCRIPTION##'
+
+@description('Indicates whether or not the alert is enabled.')
+param isEnabled bool = true
+
+@description('"The current date and time using the utcNow function. Used for deployment name uniqueness')
+param currentDateTimeUtcNow string = utcNow()
+
+@description('The customer usage identifier used for telemetry purposes. The default value of False enables telemetry. The value of True disables telemetry.')
+@allowed([
+ 'Yes'
+ 'No'
+])
+param telemetryOptOut string = 'No'
+
+resource symbolicname 'Microsoft.Insights/activityLogAlerts@2023-01-01-preview' = {
+ name: alertName
+ location: 'Global'
+ tags: {
+ _deployed_by_amba: 'true'
+ }
+ properties: {
+ description: alertDescription
+ scopes: [
+ subscription().id
+ ]
+ enabled: isEnabled
+ condition: {
+ allOf: [
+ {
+ field: 'category'
+ equals: 'ResourceHealth'
+ }
+ {
+ anyOf: [##CAUSES##
+ ]
+ }
+ {
+ anyOf: [##CURRENT_HEALTH_STATUS##
+ ]
+ }
+ ]
+ }
+ }
+}
+
+var ambaTelemetryPidName = '##TELEMETRY_PID##-${uniqueString(resourceGroup().id, alertName, currentDateTimeUtcNow)}'
+resource ambaTelemetryPid 'Microsoft.Resources/deployments@2020-06-01' = if (telemetryOptOut == 'No') {
+ name: ambaTelemetryPidName
+ tags: {
+ _deployed_by_amba: 'true'
+ }
+ properties: {
+ mode: 'Incremental'
+ template: {
+ '$schema': 'https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#'
+ contentVersion: '1.0.0.0'
+ resources: []
+ }
+ }
+}
diff --git a/tooling/generate-templates/templates/bicep/activity-servicehealth.bicep b/tooling/generate-templates/templates/bicep/activity-servicehealth.bicep
new file mode 100644
index 000000000..36e9470f7
--- /dev/null
+++ b/tooling/generate-templates/templates/bicep/activity-servicehealth.bicep
@@ -0,0 +1,64 @@
+@description('Unique name (within the Resource Group) for the Activity log alert.')
+@minLength(1)
+param alertName string
+
+@description('Description of alert')
+param alertDescription string = '##DESCRIPTION##'
+
+@description('Indicates whether or not the alert is enabled.')
+param isEnabled bool = true
+
+@description('"The current date and time using the utcNow function. Used for deployment name uniqueness')
+param currentDateTimeUtcNow string = utcNow()
+
+@description('The customer usage identifier used for telemetry purposes. The default value of False enables telemetry. The value of True disables telemetry.')
+@allowed([
+ 'Yes'
+ 'No'
+])
+param telemetryOptOut string = 'No'
+
+resource symbolicname 'Microsoft.Insights/activityLogAlerts@2023-01-01-preview' = {
+ name: alertName
+ location: 'Global'
+ tags: {
+ _deployed_by_amba: 'true'
+ }
+ properties: {
+ description: alertDescription
+ scopes: [
+ subscription().id
+ ]
+ enabled: isEnabled
+ condition: {
+ allOf: [
+ {
+ {
+ field: 'category'
+ equals: 'ServiceHealth'
+ }
+ {
+ field: 'properties.incidentType'
+ equals: '##INCIDENT_TYPE##'
+ }
+ }
+ ]
+ }
+ }
+}
+
+var ambaTelemetryPidName = '##TELEMETRY_PID##-${uniqueString(resourceGroup().id, alertName, currentDateTimeUtcNow)}'
+resource ambaTelemetryPid 'Microsoft.Resources/deployments@2020-06-01' = if (telemetryOptOut == 'No') {
+ name: ambaTelemetryPidName
+ tags: {
+ _deployed_by_amba: 'true'
+ }
+ properties: {
+ mode: 'Incremental'
+ template: {
+ '$schema': 'https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#'
+ contentVersion: '1.0.0.0'
+ resources: []
+ }
+ }
+}
diff --git a/tooling/generate-templates/templates/bicep/log.bicep b/tooling/generate-templates/templates/bicep/log.bicep
new file mode 100644
index 000000000..7387bc999
--- /dev/null
+++ b/tooling/generate-templates/templates/bicep/log.bicep
@@ -0,0 +1,168 @@
+@description('Name of the alert')
+@minLength(1)
+param alertName string
+
+@description('Description of alert')
+param alertDescription string = '##DESCRIPTION##'
+
+@description('Specifies whether the alert is enabled')
+param isEnabled bool = true
+
+@description('Specifies whether to check linked storage and fail creation if the storage was not found')
+param checkWorkspaceAlertsStorageConfigured bool = false
+
+@description('Full Resource ID of the resource emitting the metric that will be used for the comparison. For example /subscriptions/00000000-0000-0000-0000-0000-00000000/resourceGroups/ResourceGroupName/providers/Microsoft.compute/virtualMachines/VM_xyz')
+@minLength(1)
+param resourceId string
+
+@description('Mute actions for the chosen period of time (in ISO 8601 duration format) after the alert is fired.')
+@allowed([
+ 'PT1M'
+ 'PT5M'
+ 'PT15M'
+ 'PT30M'
+ 'PT1H'
+ 'PT6H'
+ 'PT12H'
+ 'PT24H'
+])
+param muteActionsDuration string
+
+@description('Severity of alert {0,1,2,3,4}')
+@allowed([
+ 0
+ 1
+ 2
+ 3
+ 4
+])
+param alertSeverity int = ##SEVERITY##
+
+@description('Specifies whether the alert will automatically resolve')
+param autoMitigate bool = ##AUTO_MITIGATE##
+
+@description('Name of the metric used in the comparison to activate the alert.')
+@minLength(1)
+param query string = '##QUERY##'
+
+@description('Name of the measure column used in the alert evaluation.')
+param metricMeasureColumn string = '##METRIC_MEASURE_COLUMN##'
+
+@description('Name of the resource ID column used in the alert targeting the alerts.')
+param resourceIdColumn string = '##RESOURCE_ID_COLUMN##'
+
+@description('Operator comparing the current value with the threshold value.')
+@allowed([
+ 'Equals'
+ 'GreaterThan'
+ 'GreaterThanOrEqual'
+ 'LessThan'
+ 'LessThanOrEqual'
+])
+param operator string = '##OPERATOR##'
+
+@description('The threshold value at which the alert is activated.')
+param threshold int = ##THRESHOLD##
+
+@description('The number of periods to check in the alert evaluation.')
+param numberOfEvaluationPeriods int = ##FAILING_PERIODS_NUMBER_OF_EVALUATION_PERIODS##
+
+@description('The number of unhealthy periods to alert on (must be lower or equal to numberOfEvaluationPeriods).')
+param minFailingPeriodsToAlert int = ##FAILING_PERIODS_MIN_FAILING_PERIODS_TO_ALERT##
+
+@description('How the data that is collected should be combined over time.')
+@allowed([
+ 'Average'
+ 'Minimum'
+ 'Maximum'
+ 'Total'
+ 'Count'
+])
+param timeAggregation string = '##TIME_AGGREGATION##'
+
+@description('Period of time used to monitor alert activity based on the threshold. Must be between one minute and one day. ISO 8601 duration format.')
+@allowed([
+ 'PT1M'
+ 'PT5M'
+ 'PT15M'
+ 'PT30M'
+ 'PT1H'
+ 'PT6H'
+ 'PT12H'
+ 'PT24H'
+ 'P1D'
+])
+param windowSize string = '##WINDOW_SIZE##'
+
+@description('how often the metric alert is evaluated represented in ISO 8601 duration format')
+@allowed([
+ 'PT5M'
+ 'PT15M'
+ 'PT30M'
+ 'PT1H'
+])
+param evaluationFrequency string = '##EVALUATION_FREQUENCY##'
+
+@description('"The current date and time using the utcNow function. Used for deployment name uniqueness')
+param currentDateTimeUtcNow string = utcNow()
+
+@description('The customer usage identifier used for telemetry purposes. The default value of False enables telemetry. The value of True disables telemetry.')
+@allowed([
+ 'Yes'
+ 'No'
+])
+param telemetryOptOut string = 'No'
+
+resource alert 'Microsoft.Insights/scheduledQueryRules@2021-08-01' = {
+ name: alertName
+ location: resourceGroup().location
+ tags: {
+ _deployed_by_amba: 'true'
+ }
+ properties: {
+ description: alertDescription
+ severity: alertSeverity
+ enabled: isEnabled
+ scopes: [
+ resourceId
+ ]
+ evaluationFrequency: evaluationFrequency
+ windowSize: windowSize
+ criteria: {
+ allOf: [
+ {
+ query: query
+ metricMeasureColumn: metricMeasureColumn
+ resourceIdColumn: resourceIdColumn
+ dimensions: [##DIMENSIONS##]
+ operator: operator
+ threshold: threshold
+ timeAggregation: timeAggregation
+ failingPeriods: {
+ numberOfEvaluationPeriods: numberOfEvaluationPeriods
+ minFailingPeriodsToAlert: minFailingPeriodsToAlert
+ }
+ }
+ ]
+ }
+ muteActionsDuration: muteActionsDuration
+ autoMitigate: autoMitigate
+ checkWorkspaceAlertsStorageConfigured: checkWorkspaceAlertsStorageConfigured
+ }
+}
+
+var ambaTelemetryPidName = '##TELEMETRY_PID##-${uniqueString(resourceGroup().id, alertName, currentDateTimeUtcNow)}'
+resource ambaTelemetryPid 'Microsoft.Resources/deployments@2020-06-01' = if (telemetryOptOut == 'No') {
+ name: ambaTelemetryPidName
+ tags: {
+ _deployed_by_amba: 'true'
+ }
+ properties: {
+ mode: 'Incremental'
+ template: {
+ '$schema': 'https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#'
+ contentVersion: '1.0.0.0'
+ resources: []
+ }
+ }
+}
diff --git a/tooling/generate-templates/templates/bicep/metric-dynamic.bicep b/tooling/generate-templates/templates/bicep/metric-dynamic.bicep
new file mode 100644
index 000000000..77a4a28da
--- /dev/null
+++ b/tooling/generate-templates/templates/bicep/metric-dynamic.bicep
@@ -0,0 +1,147 @@
+@description('Name of the alert')
+@minLength(1)
+param alertName string
+
+@description('Description of alert')
+param alertDescription string = '##DESCRIPTION##'
+
+@description('array of Azure resource Ids. For example - /subscriptions/00000000-0000-0000-0000-0000-00000000/resourceGroup/resource-group-name/Microsoft.compute/virtualMachines/vm-name')
+@minLength(1)
+param targetResourceId array
+
+@description('Azure region in which target resources to be monitored are in (without spaces). For example: EastUS')
+param targetResourceRegion string
+
+@description('Resource type of target resources to be monitored.')
+@minLength(1)
+param targetResourceType string
+
+@description('Specifies whether the alert is enabled')
+param isEnabled bool = true
+
+@description('Severity of alert {0,1,2,3,4}')
+@allowed([
+ 0
+ 1
+ 2
+ 3
+ 4
+])
+param alertSeverity int = ##SEVERITY##
+
+@description('Operator comparing the current value with the threshold value.')
+@allowed([
+ 'GreaterThan'
+ 'LessThan'
+ 'GreaterOrLessThan'
+])
+param operator string = '##OPERATOR##'
+
+@description('Tunes how \'noisy\' the Dynamic Thresholds alerts will be: \'High\' will result in more alerts while \'Low\' will result in fewer alerts.')
+@allowed([
+ 'High'
+ 'Medium'
+ 'Low'
+])
+param alertSensitivity string = '##ALERT_SENSITIVITY##'
+
+@description('The number of periods to check in the alert evaluation.')
+param numberOfEvaluationPeriods int = ##FAILING_PERIODS_NUMBER_OF_EVALUATION_PERIODS##
+
+@description('The number of unhealthy periods to alert on (must be lower or equal to numberOfEvaluationPeriods).')
+param minFailingPeriodsToAlert int = ##FAILING_PERIODS_MIN_FAILING_PERIODS_TO_ALERT##
+
+@description('How the data that is collected should be combined over time.')
+@allowed([
+ 'Average'
+ 'Minimum'
+ 'Maximum'
+ 'Total'
+ 'Count'
+])
+param timeAggregation string = '##TIME_AGGREGATION##'
+
+@description('Period of time used to monitor alert activity based on the threshold. Must be between five minutes and one hour. ISO 8601 duration format.')
+@allowed([
+ 'PT1M'
+ 'PT5M'
+ 'PT15M'
+ 'PT30M'
+ 'PT1H'
+ 'PT6H'
+ 'PT12H'
+ 'PT24H'
+ 'P1D'
+])
+param windowSize string = '##WINDOW_SIZE##'
+
+@description('how often the metric alert is evaluated represented in ISO 8601 duration format')
+@allowed([
+ 'PT5M'
+ 'PT15M'
+ 'PT30M'
+ 'PT1H'
+])
+param evaluationFrequency string = '##EVALUATION_FREQUENCY##'
+
+@description('"The current date and time using the utcNow function. Used for deployment name uniqueness')
+param currentDateTimeUtcNow string = utcNow()
+
+@description('The customer usage identifier used for telemetry purposes. The default value of False enables telemetry. The value of True disables telemetry.')
+@allowed([
+ 'Yes'
+ 'No'
+])
+param telemetryOptOut string = 'No'
+
+resource metricAlert 'Microsoft.Insights/metricAlerts@2018-03-01' = {
+ name: alertName
+ location: 'global'
+ tags: {
+ _deployed_by_amba: 'true'
+ }
+ properties: {
+ description: alertDescription
+ scopes: targetResourceId
+ targetResourceType: targetResourceType
+ targetResourceRegion: targetResourceRegion
+ severity: alertSeverity
+ enabled: isEnabled
+ evaluationFrequency: evaluationFrequency
+ windowSize: windowSize
+ criteria: {
+ 'odata.type': 'Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria'
+ allOf: [
+ {
+ criterionType: 'DynamicThresholdCriterion'
+ name: '1st criterion'
+ metricName: '##METRIC_NAME##'
+ dimensions: [##DIMENSIONS##]
+ operator: operator
+ alertSensitivity: alertSensitivity
+ failingPeriods: {
+ numberOfEvaluationPeriods: numberOfEvaluationPeriods
+ minFailingPeriodsToAlert: minFailingPeriodsToAlert
+ }
+ timeAggregation: timeAggregation
+ }
+ ]
+ }
+ }
+}
+
+var ambaTelemetryPidName = '##TELEMETRY_PID##-${uniqueString(resourceGroup().id, alertName, currentDateTimeUtcNow)}'
+resource ambaTelemetryPid 'Microsoft.Resources/deployments@2020-06-01' = if (telemetryOptOut == 'No') {
+ name: ambaTelemetryPidName
+ tags: {
+ _deployed_by_amba: 'true'
+ }
+ properties: {
+ mode: 'Incremental'
+ template: {
+ '$schema': 'https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#'
+ contentVersion: '1.0.0.0'
+ resources: []
+ }
+ }
+}
diff --git a/tooling/generate-templates/templates/bicep/metric-static.bicep b/tooling/generate-templates/templates/bicep/metric-static.bicep
new file mode 100644
index 000000000..b4511d07d
--- /dev/null
+++ b/tooling/generate-templates/templates/bicep/metric-static.bicep
@@ -0,0 +1,135 @@
+@description('Name of the alert')
+@minLength(1)
+param alertName string
+
+@description('Description of alert')
+param alertDescription string = '##DESCRIPTION##'
+
+@description('Array of Azure resource Ids. For example - /subscriptions/00000000-0000-0000-0000-0000-00000000/resourceGroup/resource-group-name/Microsoft.compute/virtualMachines/vm-name')
+@minLength(1)
+param targetResourceId array
+
+@description('Azure region in which target resources to be monitored are in (without spaces). For example: EastUS')
+param targetResourceRegion string
+
+@description('Resource type of target resources to be monitored.')
+@minLength(1)
+param targetResourceType string
+
+@description('Specifies whether the alert is enabled')
+param isEnabled bool = true
+
+@description('Severity of alert {0,1,2,3,4}')
+@allowed([
+ 0
+ 1
+ 2
+ 3
+ 4
+])
+param alertSeverity int = ##SEVERITY##
+
+@description('Operator comparing the current value with the threshold value.')
+@allowed([
+ 'Equals'
+ 'GreaterThan'
+ 'GreaterThanOrEqual'
+ 'LessThan'
+ 'LessThanOrEqual'
+])
+param operator string = '##OPERATOR##'
+
+@description('The threshold value at which the alert is activated.')
+param threshold int = ##THRESHOLD##
+
+@description('How the data that is collected should be combined over time.')
+@allowed([
+ 'Average'
+ 'Minimum'
+ 'Maximum'
+ 'Total'
+ 'Count'
+])
+param timeAggregation string = '##TIME_AGGREGATION##'
+
+@description('Period of time used to monitor alert activity based on the threshold. Must be between one minute and one day. ISO 8601 duration format.')
+@allowed([
+ 'PT1M'
+ 'PT5M'
+ 'PT15M'
+ 'PT30M'
+ 'PT1H'
+ 'PT6H'
+ 'PT12H'
+ 'PT24H'
+ 'P1D'
+])
+param windowSize string = '##WINDOW_SIZE##'
+
+@description('how often the metric alert is evaluated represented in ISO 8601 duration format')
+@allowed([
+ 'PT1M'
+ 'PT5M'
+ 'PT15M'
+ 'PT30M'
+ 'PT1H'
+])
+param evaluationFrequency string = '##EVALUATION_FREQUENCY##'
+
+@description('"The current date and time using the utcNow function. Used for deployment name uniqueness')
+param currentDateTimeUtcNow string = utcNow()
+
+@description('The customer usage identifier used for telemetry purposes. The default value of False enables telemetry. The value of True disables telemetry.')
+@allowed([
+ 'Yes'
+ 'No'
+])
+param telemetryOptOut string = 'No'
+
+resource metricAlert 'Microsoft.Insights/metricAlerts@2018-03-01' = {
+ name: alertName
+ location: 'global'
+ tags: {
+ _deployed_by_amba: 'true'
+ }
+ properties: {
+ description: alertDescription
+ scopes: targetResourceId
+ targetResourceType: targetResourceType
+ targetResourceRegion: targetResourceRegion
+ severity: alertSeverity
+ enabled: isEnabled
+ evaluationFrequency: evaluationFrequency
+ windowSize: windowSize
+ criteria: {
+ 'odata.type': 'Microsoft.Azure.Monitor.MultipleResourceMultipleMetricCriteria'
+ allOf: [
+ {
+ name: '1st criterion'
+ metricName: '##METRIC_NAME##'
+ dimensions: [##DIMENSIONS##]
+ operator: operator
+ threshold: threshold
+ timeAggregation: timeAggregation
+ criterionType: 'StaticThresholdCriterion'
+ }
+ ]
+ }
+ }
+}
+
+var ambaTelemetryPidName = '##TELEMETRY_PID##-${uniqueString(resourceGroup().id, alertName, currentDateTimeUtcNow)}'
+resource ambaTelemetryPid 'Microsoft.Resources/deployments@2020-06-01' = if (telemetryOptOut == 'No') {
+ name: ambaTelemetryPidName
+ tags: {
+ _deployed_by_amba: 'true'
+ }
+ properties: {
+ mode: 'Incremental'
+ template: {
+ '$schema': 'https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#'
+ contentVersion: '1.0.0.0'
+ resources: []
+ }
+ }
+}