Solution configuration during ARM deployment

Copper Contributor

 Hi,

 

Using different examples online and snippets from previous deployments i am putting together a ARM template for deploying OMS/Log Analytics.

 

I am trying to configure solutions during deployment, in particular Azure Activity logs and 365. In the attached template all solutions are depoyed, but not configured. I have focused on getting Azure activity logs to work using bits from the quick-start-templates, but havent suceeded. Any suggestions?

 

{
    "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json",
    "contentVersion": "1.0.0.0",
    "parameters": {
        
        "customerCode": {
            "type": "string",
            "maxLength": 3,
            "metadata": {
                "description": "Specify  customer code."
            }
        },

        "omsWorkspaceRegion": {
            "type": "string",
            "defaultValue": "West Europe",
            "allowedValues": [
                "East US",
                "West Europe",
                "Southeast Asia",
                "Australia Southeast"
            ],
            "metadata": {
                "description": "Specify the region for your Workspace"
            }
        },
        "omsPricing": {
            "type": "string",
            "defaultValue": "Free",
            "allowedValues": [
                "PerNode",
                "Standalone",
                "Free"           
            ],
            "metadata": {
                "description": "Select OMS pricing. Free, per node or standalone (data driven)"
                    }
            },
        "dataRetention": {
            "type": "int",
            "defaultValue": 30,
            "minValue": 7,
            "maxValue": 730,
            "metadata": {
                "description": "Number of days of retention. Free plans can only have 7 days, Standalone and OMS plans include 30 days for free"
            }
        }
    },

    "variables": {
        "batch1": {
             "solutions": [
                {
                    "name": "[concat('AzureActivity', '(', variables('workspaceName'), ')')]",
                    "marketplaceName": "AzureActivity"
                },
                {
                    "name": "[concat('Office365', '(', variables('workspaceName'), ')')]",
                    "marketplaceName": "Office365"
                },
                {
                    "name": "[concat('AzureWebAppsAnalytics', '(', variables('workspaceName'), ')')]",
                    "marketplaceName": "AzureWebAppsAnalytics"
                }
            ]
        },

        "workspaceName": "[concat(parameters('customerCode'), '-', uniqueString(resourceGroup().id))]",
        
        "alerts": {
            "searches": [
                {
                "searchDisplayName": "Workspace Data Usage Last 24h",
                "searchQuery": "Usage | where QuantityUnit == 'MBytes' and IsBillable == 'True' and TimeGenerated > ago(24h) | summarize AggregatedValue = sum(Quantity) by bin(TimeGenerated, 24h)",
                "searchCategory": "Workspace",
                "searchName": "Workspace-data-usage",
                "alertName": "Billable data usage exceeded threshold",
                "alertDisplayName": "Workspace Data Usage",
                "alertDescription": "Alert when workspace data is more than 400mb per day, free tier includes 500mb",
                "alertSeverity": "Informational",
                "alertThresholdOperator": "gt",
                "alertThresholdValue": "450",
                "scheduleIntervalInMinutes": 15,
                "scheduleQueryTimeSpan": 1440,
                "triggerCondition": "Consecutive",
                "triggerOperator": "gt",
                "triggerValue": 1
                }
            ]
        }
    },      

    "resources": [
        {
            "apiVersion": "2017-03-15-preview",
            "location": "[parameters('omsWorkspaceRegion')]",
            "name": "[variables('workspaceName')]",
            "type": "Microsoft.OperationalInsights/workspaces",
            "tags": {
                "CustomerCode": "[parameters('customerCode')]",
                "displayName": "[concat('Default-Monitoring-Workspace',' (', parameters('customerCode'), ')')]",
                "Environment": "Production"
            },
            "dependsOn": [
            ],
            "comments": " customer default monitoring workspace",
            "properties": {
                "sku": {
                    "name": "[parameters('omsPricing')]"
                },
            "resources": [
                {
                    "name": "AzureActivityLog",
                    "type": "datasources",
                    "apiVersion": "2015-11-01-preview",
                    "dependsOn": [
                        "[concat('Microsoft.OperationalInsights/workspaces/', variables('WorkspaceName'))]"
                    ],
                    "kind": "AzureActivityLog",
                    "properties": {
                        "linkedResourceId": "[concat(subscription().id, '/providers/Microsoft.Insights/eventTypes/management')]"
                    }
                }
            ],
            "retention": "[parameters('dataRetention')]"
            }
        },
   
        {
            "apiVersion": "2015-11-01-preview",
            "type": "Microsoft.OperationsManagement/solutions",
            "name": "[concat(variables('batch1').solutions[copyIndex()].Name)]",
            "location": "[parameters('omsWorkspaceRegion')]",
            "dependsOn": [
                "[concat('Microsoft.OperationalInsights/workspaces/', variables('workspaceName'))]"
            ],
            "copy": {
                "name": "solutionCopy",
                "count": "[length(variables('batch1').solutions)]"
                },
            "properties": {
                "workspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces', variables('workspaceName'))]"
            },
            
            "plan": {
                "name": "[variables('batch1').solutions[copyIndex()].name]",
                "product": "[concat('OMSGallery/', variables('batch1').solutions[copyIndex()].marketplaceName)]",
                "promotionCode": "",
                "publisher": "Microsoft"
            }
        },

        {
            "apiVersion": "2017-03-15-preview",
            "type": "Microsoft.OperationalInsights/workspaces/savedSearches",
            "name": "[concat(variables('workspaceName'), '/', tolower(variables('alerts').searches[copyIndex()].searchCategory), '|', toLower(variables('alerts').searches[copyIndex()].searchName))]",
            "copy": {
                "name": "savedsearchcopy",
                "count": "[length(variables('alerts').searches)]"
                    },
            "dependsOn": [
                "[concat('Microsoft.OperationalInsights/workspaces/', variables('workspaceName'))]"
                    ],
            "properties": {
                "etag": "*",
                "query": "[variables('alerts').searches[copyIndex()].searchQuery]",
                "displayName": "[variables('alerts').searches[copyIndex()].searchName]",
                "category": "[variables('alerts').searches[copyIndex()].searchCategory]"
                    }               
            
        },
    {
        "apiVersion": "2017-03-15-preview",
        "type": "Microsoft.OperationalInsights/workspaces/savedSearches/schedules",
        "name": "[concat(variables('workspaceName'), '/', tolower(variables('alerts').searches[copyIndex()].searchCategory), '|', toLower(variables('alerts').searches[copyIndex()].searchName), '/','schedule-',uniqueString(resourceGroup().id, deployment().name,variables('workspaceName'), '/', variables('alerts').searches[copyIndex()].searchCategory, '|', variables('alerts').searches[copyIndex()].searchName))]",
        "copy": {
            "name": "schedulescopy",
            "count": "[length(variables('alerts').searches)]"
        },
        "dependsOn": [
            "[concat('Microsoft.OperationalInsights/workspaces/', variables('workspaceName'))]",
            "[concat('Microsoft.OperationalInsights/workspaces/', variables('workspaceName'), '/savedSearches/', tolower(variables('alerts').searches[copyIndex()].searchCategory), '|', toLower(variables('alerts').searches[copyIndex()].searchName))]"
        ],
        "properties": {
            "etag": "*",
            "Interval": "[variables('alerts').searches[copyIndex()].scheduleIntervalInMinutes]",
            "QueryTimeSpan": "[variables('alerts').searches[copyIndex()].scheduleQueryTimeSpan]",
            "enabled": true
        }
    },
    {
        "apiVersion": "2017-03-15-preview",
        "type": "Microsoft.OperationalInsights/workspaces/savedSearches/schedules/actions",
        "name": "[concat(variables('workspaceName'), '/', tolower(variables('alerts').searches[copyIndex()].searchCategory), '|', toLower(variables('alerts').searches[copyIndex()].searchName), '/','schedule-',uniqueString(resourceGroup().id, deployment().name,variables('workspaceName'), '/', variables('alerts').searches[copyIndex()].searchCategory, '|', variables('alerts').searches[copyIndex()].searchName), '/', 'alert-',uniqueString(resourceGroup().id, deployment().name,variables('workspaceName'), '/', variables('alerts').searches[copyIndex()].searchCategory, '|', variables('alerts').searches[copyIndex()].searchName))]",
        "copy": {
            "name": "actioncopy",
            "count": "[length(variables('alerts').searches)]"
        },
        "dependsOn": [
            "[concat('Microsoft.OperationalInsights/workspaces/', variables('workspaceName'))]",
            "[concat('Microsoft.OperationalInsights/workspaces/', variables('workspaceName'), '/savedSearches/', tolower(variables('alerts').searches[copyIndex()].searchCategory), '|', toLower(variables('alerts').searches[copyIndex()].searchName))]",
            "[concat('Microsoft.OperationalInsights/workspaces/', variables('workspaceName'), '/savedSearches/', tolower(variables('alerts').searches[copyIndex()].searchCategory), '|', toLower(variables('alerts').searches[copyIndex()].searchName), '/schedules/','schedule-',uniqueString(resourceGroup().id, deployment().name,variables('workspaceName'), '/', variables('alerts').searches[copyIndex()].searchCategory, '|', variables('alerts').searches[copyIndex()].searchName))]"
        ],
        "properties": {
            "etag": "*",
            "Type": "Alert",
            "Name": "[variables('alerts').searches[copyIndex()].alertName]",
            "Description": "[variables('alerts').searches[copyIndex()].alertDescription]",
            "Severity": "[variables('alerts').searches[copyIndex()].alertSeverity]",
            "Threshold": {
                "Operator": "[variables('alerts').searches[copyIndex()].triggerOperator]",
                "Value": "[variables('alerts').searches[copyIndex()].alertThresholdValue]"
            }
        }
    }
    ],
    
    "outputs": {
        "omsWorkspaceName": {
            "type": "string",
            "value": "[variables('workspaceName')]"
        },
        "tenantId": {
            "type": "string",
            "value": "[subscription().tenantId]"
                },

        "tenantSubscription": {
            "type": "string",
            "value": "[subscription().displayName]"
            }
    }
}
1 Reply

Got the Azure Activity Logs working. Seems that i had missed the section where the activity log configuration (subscription id etc) in the worskspace resources.

 

 

           "resources": [
                {
                    "name": "AzureActivityLog",
                    "type": "datasources",
                    "apiVersion": "2015-11-01-preview",
                    "dependsOn": [
                        "[concat('Microsoft.OperationalInsights/workspaces/', variables('workspaceName'))]"
                    ],
                    "kind": "AzureActivityLog",
                    "properties": {
                        "linkedResourceId": "[concat(subscription().id, '/providers/Microsoft.Insights/eventTypes/management')]"
                    }
                }
            ]

 

the whole template now looks like this

 

{
    "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "customerCode": {
            "type": "string",
            "maxLength": 3,
            "metadata": {
                "description": "Specify  customer code."
            }
        },
        "omsWorkspaceRegion": {
            "type": "string",
            "defaultValue": "West Europe",
            "allowedValues": [
                "East US",
                "West Europe",
                "Southeast Asia",
                "Australia Southeast"
            ],
            "metadata": {
                "description": "Specify the region for your Workspace"
            }
        },
        "omsPricing": {
            "type": "string",
            "defaultValue": "Free",
            "allowedValues": [
                "PerNode",
                "Standalone",
                "Free"
            ],
            "metadata": {
                "description": "Select OMS pricing. Free, per node or standalone (data driven)"
            }
        },
        "dataRetention": {
            "type": "int",
            "defaultValue": 30,
            "minValue": 7,
            "maxValue": 730,
            "metadata": {
                "description": "Number of days of retention. Free plans can only have 7 days, Standalone and OMS plans include 30 days for free"
            }
        }
    },
    "variables": {
        "batch1": {
            "solutions": [
                {
                    "name": "[concat('AzureActivity', '(', variables('workspaceName'), ')')]",
                    "marketplaceName": "AzureActivity"
                },
                {
                    "name": "[concat('Office365', '(', variables('workspaceName'), ')')]",
                    "marketplaceName": "Office365"
                },
                {
                    "name": "[concat('AzureWebAppsAnalytics', '(', variables('workspaceName'), ')')]",
                    "marketplaceName": "AzureWebAppsAnalytics"
                }
            ]
        },
        "workspaceName": "[concat(parameters('customerCode'), '-', uniqueString(resourceGroup().id))]",
        "alerts": {
            "searches": [
                {
                    "searchDisplayName": "Workspace Data Usage Last 24h",
                    "searchQuery": "Usage | where QuantityUnit == 'MBytes' and IsBillable == 'True' and TimeGenerated > ago(24h) | summarize AggregatedValue = sum(Quantity) by bin(TimeGenerated, 24h)",
                    "searchCategory": "Workspace",
                    "searchName": "Workspace-data-usage",
                    "alertName": "Billable data usage exceeded threshold",
                    "alertDisplayName": "Workspace Data Usage",
                    "alertDescription": "Alert when workspace data is more than 400mb per day, free tier includes 500mb",
                    "alertSeverity": "Informational",
                    "alertThresholdOperator": "gt",
                    "alertThresholdValue": "450",
                    "scheduleIntervalInMinutes": 15,
                    "scheduleQueryTimeSpan": 1440,
                    "triggerCondition": "Consecutive",
                    "triggerOperator": "gt",
                    "triggerValue": 1
                }
            ]
        }
    },
    "resources": [
        {
            "apiVersion": "2017-03-15-preview",
            "location": "[parameters('omsWorkspaceRegion')]",
            "name": "[variables('workspaceName')]",
            "type": "Microsoft.OperationalInsights/workspaces",
            "tags": {
                "CustomerCode": "[parameters('customerCode')]",
                "displayName": "[concat('Default-Monitoring-Workspace',' (', parameters('customerCode'), ')')]",
                "Environment": "Production"
            },
            "dependsOn": [],
            "comments": " customer default monitoring workspace",
            "properties": {
                "sku": {
                    "name": "[parameters('omsPricing')]"
                },
                "retention": "[parameters('dataRetention')]"
            },
            "resources": [
                {
                    "name": "AzureActivityLog",
                    "type": "datasources",
                    "apiVersion": "2015-11-01-preview",
                    "dependsOn": [
                        "[concat('Microsoft.OperationalInsights/workspaces/', variables('workspaceName'))]"
                    ],
                    "kind": "AzureActivityLog",
                    "properties": {
                        "linkedResourceId": "[concat(subscription().id, '/providers/Microsoft.Insights/eventTypes/management')]"
                    }
                }
            ]
        },
        {
            "apiVersion": "2015-11-01-preview",
            "type": "Microsoft.OperationsManagement/solutions",
            "name": "[concat(variables('batch1').solutions[copyIndex()].Name)]",
            "location": "[parameters('omsWorkspaceRegion')]",
            "dependsOn": [
                "[concat('Microsoft.OperationalInsights/workspaces/', variables('workspaceName'))]"
            ],
            "copy": {
                "name": "solutionCopy",
                "count": "[length(variables('batch1').solutions)]"
            },
            "properties": {
                "workspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces', variables('workspaceName'))]"
            },
            "plan": {
                "name": "[variables('batch1').solutions[copyIndex()].name]",
                "product": "[concat('OMSGallery/', variables('batch1').solutions[copyIndex()].marketplaceName)]",
                "promotionCode": "",
                "publisher": "Microsoft"
            }
        },
        {
            "apiVersion": "2017-03-15-preview",
            "type": "Microsoft.OperationalInsights/workspaces/savedSearches",
            "name": "[concat(variables('workspaceName'), '/', tolower(variables('alerts').searches[copyIndex()].searchCategory), '|', toLower(variables('alerts').searches[copyIndex()].searchName))]",
            "copy": {
                "name": "savedsearchcopy",
                "count": "[length(variables('alerts').searches)]"
            },
            "dependsOn": [
                "[concat('Microsoft.OperationalInsights/workspaces/', variables('workspaceName'))]"
            ],
            "properties": {
                "etag": "*",
                "query": "[variables('alerts').searches[copyIndex()].searchQuery]",
                "displayName": "[variables('alerts').searches[copyIndex()].searchName]",
                "category": "[variables('alerts').searches[copyIndex()].searchCategory]"
            }
        },
        {
            "apiVersion": "2017-03-15-preview",
            "type": "Microsoft.OperationalInsights/workspaces/savedSearches/schedules",
            "name": "[concat(variables('workspaceName'), '/', tolower(variables('alerts').searches[copyIndex()].searchCategory), '|', toLower(variables('alerts').searches[copyIndex()].searchName), '/','schedule-',uniqueString(resourceGroup().id, deployment().name,variables('workspaceName'), '/', variables('alerts').searches[copyIndex()].searchCategory, '|', variables('alerts').searches[copyIndex()].searchName))]",
            "copy": {
                "name": "schedulescopy",
                "count": "[length(variables('alerts').searches)]"
            },
            "dependsOn": [
                "[concat('Microsoft.OperationalInsights/workspaces/', variables('workspaceName'))]",
                "[concat('Microsoft.OperationalInsights/workspaces/', variables('workspaceName'), '/savedSearches/', tolower(variables('alerts').searches[copyIndex()].searchCategory), '|', toLower(variables('alerts').searches[copyIndex()].searchName))]"
            ],
            "properties": {
                "etag": "*",
                "Interval": "[variables('alerts').searches[copyIndex()].scheduleIntervalInMinutes]",
                "QueryTimeSpan": "[variables('alerts').searches[copyIndex()].scheduleQueryTimeSpan]",
                "enabled": true
            }
        },
        {
            "apiVersion": "2017-03-15-preview",
            "type": "Microsoft.OperationalInsights/workspaces/savedSearches/schedules/actions",
            "name": "[concat(variables('workspaceName'), '/', tolower(variables('alerts').searches[copyIndex()].searchCategory), '|', toLower(variables('alerts').searches[copyIndex()].searchName), '/','schedule-',uniqueString(resourceGroup().id, deployment().name,variables('workspaceName'), '/', variables('alerts').searches[copyIndex()].searchCategory, '|', variables('alerts').searches[copyIndex()].searchName), '/', 'alert-',uniqueString(resourceGroup().id, deployment().name,variables('workspaceName'), '/', variables('alerts').searches[copyIndex()].searchCategory, '|', variables('alerts').searches[copyIndex()].searchName))]",
            "copy": {
                "name": "actioncopy",
                "count": "[length(variables('alerts').searches)]"
            },
            "dependsOn": [
                "[concat('Microsoft.OperationalInsights/workspaces/', variables('workspaceName'))]",
                "[concat('Microsoft.OperationalInsights/workspaces/', variables('workspaceName'), '/savedSearches/', tolower(variables('alerts').searches[copyIndex()].searchCategory), '|', toLower(variables('alerts').searches[copyIndex()].searchName))]",
                "[concat('Microsoft.OperationalInsights/workspaces/', variables('workspaceName'), '/savedSearches/', tolower(variables('alerts').searches[copyIndex()].searchCategory), '|', toLower(variables('alerts').searches[copyIndex()].searchName), '/schedules/','schedule-',uniqueString(resourceGroup().id, deployment().name,variables('workspaceName'), '/', variables('alerts').searches[copyIndex()].searchCategory, '|', variables('alerts').searches[copyIndex()].searchName))]"
            ],
            "properties": {
                "etag": "*",
                "Type": "Alert",
                "Name": "[variables('alerts').searches[copyIndex()].alertName]",
                "Description": "[variables('alerts').searches[copyIndex()].alertDescription]",
                "Severity": "[variables('alerts').searches[copyIndex()].alertSeverity]",
                "Threshold": {
                    "Operator": "[variables('alerts').searches[copyIndex()].triggerOperator]",
                    "Value": "[variables('alerts').searches[copyIndex()].alertThresholdValue]"
                }
            }
        }
    ],
    "outputs": {
        "omsWorkspaceName": {
            "type": "string",
            "value": "[variables('workspaceName')]"
        },
        "tenantId": {
            "type": "string",
            "value": "[subscription().tenantId]"
        },
        "tenantSubscription": {
            "type": "string",
            "value": "[subscription().displayName]"
        }
    }
}

 

Now i am planning to configure O365 solution as well, this seems a little different as it doesent connect 'through' the Azure portal, suggestions are welcome :)