Azure Monitor, Security Center, Sentinel Infrastructure as Code with Bicep

When deploying resources to Azure, you have several options, the Azure Portal, PowerShell, Azure Resource Management (ARM) Templates, and now we have Bicep templates. In this post I’ll share a Bicep template I’ve made to help you deploy Log Analytics, the backbone of Azure Monitor, Sentinel and Security Center. For the operations monitoring Application Insights, Azure Monitor for VMs (VMInsights), Azure Monitor for Containers (ContainerInsights), and a linked Azure Automation account for Update Management, Change Tracking & Inventory. For the security side the template also includes Azure security resources Azure Sentinel and Azure Security Center. If you’re not familiar with Bicep:

Bicep is a Domain Specific Language (DSL) for deploying Azure resources declaratively. It aims to drastically simplify the authoring experience with a cleaner syntax, improved type safety, and better support for modularity and code re-use. Bicep is a transparent abstraction over ARM and ARM templates, which means anything that can be done in an ARM Template can be done in Bicep (outside of temporary known limitations). All resource typesapiVersions, and properties that are valid in an ARM template are equally valid in Bicep on day one.

Bicep code is transpiled to standard ARM Template JSON files, which effectively treats the ARM Template as an Intermediate Language (IL).

There is also a tutorial at the above link as well. This post is definitely not a getting started with Bicep post, and you’ll need to have an decent understanding of ARM and Bicep to follow along.

TLDR: template here.


The majority of this template is controlled by the parameters.

Bicep Azure Monitor Sentinel

First we’ll start with the naming, its setup such that the default value is to concatenate the tags you provide with the location and LA for Log Analytics, AI for App Insights. This is more of the DevOps approach of naming resources. You know exactly what type of resource it is, where its located and its purpose, as long as your tagging taxonomy makes sense.

Next you’ll notice a whole bunch of bools with default value of false. If you deployed this template as it sits, you would get a lonely Log Analytics workspace with a retention of 31 days. However, with those bools you can easily have a parameter file for security that enables Azure Security Center and Azure Sentinel on top of your workspace. Alternatively, for operations monitoring you could have a parameter file or object that enables Azure Automation, VMInsights, ContainerInsights and App Insights all on top of your workspace.


We have a handful of variables we’re using. The first two of which use the Ternary operator to evaluate location for EastUS and EastUS2 resources. To link Azure Automation with Log Analytics, it has to be in a supported region. That said to link Log Analytics and Azure Automation in EastUS and EastUS2 they can’t be in the same. So Log Analytics in EastUS, Azure Automation has to be in EastUS2. You can see the full supported regions here.

Bicep Azure Monitor Sentinel

There is a second AutomationLocation variable. This is our final value that we use in the name as well as during the resource deployment. So that EastUS and EastUS2 are correct with Log Analytics. Any other region, Azure Automation needs to be the same region as Log Analytics. Which is why we use the location parameter for the negative evaluation. I know this is kind of complicated but basically it comes out like this.

If location = EastUS then make AutomationLocation EastUS2

If location = EastUS2 then make AutomationLocation EastUS, all else stays the same as resource group location.

Bicep Azure Monitor Sentinel

The rest of these variables exist because at present deploying solutions to log analytics doesn’t support arrays. Ideally I would like to have one resource deployment for solutions that has a bunch of array parameters. So you would have one resource deployment that does all the solutions that you send it in the array values.

Resource Deployment

As noted above Log Analytic is the only one without a bool. Everything else has a Boolean value that controls whether or not it gets deployed.

Bicep Azure Monitor Sentinel

Using if (linkedAutomation) before the curly brace allows the resource deployment to be conditional on the value of the Boolean.

Bicep Azure Monitor Sentinel

We do the same thing with all the other solutions and Application Insights.


You can deploy Bicep files directly in Azure CLI or PowerShell, just assume that you need to be on the latest releases of Bicep, CLI/PowerShell. Bicep is still very new and being updated constantly.

Azure CLI Example for security and change tracking all on one workspace:

az deployment group create --name iactest --resource-group azmon --template-file .\loganalytics.bicep --parameters 'linkedAutomation=true' 'azureSentinelBool=true' 'azureSecurityCenterBool=true' 'changeTrackingBool=true'

Azure CLI Example for Operational monitoring:

az deployment group create --name iactest --resource-group azmoneastus2 --template-file .\loganalytics.bicep --parameters
'linkedAutomation=true' 'vmInsightsBool=true' 'updateManagementBool=true' 'changeTrackingBool=true' 'containerInsightsBool=true' 'appInsightsBool=true'


What good IAC doesn’t have a demo?

through the magic of editing, the deployment is faster. Notice how the Automation Account is in EastUS2 opposite Log Analytics in East US.


This is just the initial deployment of resources. You still need to add things like data collection in Sentinel, or agent deployment, onboarding of agents and more. I’ll cover some further examples like data collection in Log Analytics soon. You can find those and this template on my github.