Skip to main content
Jorge Bernhardt Jorge Bernhardt
  1. Posts/

Bicep - Deploying Log Analytics Workspaces

·853 words·5 mins· 100 views · 5 likes ·
Bicep Microsoft Azure IaC Azure CLI

Hello! This week, I wanted to share a new post about biceps - As you know, Infrastructure as Code (IaC) has become a critical aspect of any successful and scalable deployment. Azure Bicep is a tool that enables us to provision and manage Azure resources with reliability and conciseness.

In this blog post, I will guide you through deploying Log Analytics Workspaces using a Bicep template. We will define the Workspaces and their properties in a Bicep file. After that, we will implement them using a parameter file and finally deploy the resource using Azure CLI.


Prerequisites #

Before you start, you’ll need the following to deploy and manage resources with Bicep:

  • You need Azure CLI version 2.20.0 or later to deploy Bicep files on your local machine.
  • A text editor or IDE of your choice (Visual Studio Code with Bicep extension is my recommendation)
Create the Bicep file>

Create the Bicep file #

The first step in deploying a Bicep template is to create the Bicep file that defines your resources. Create a new file named law.bicep. This file will contain the code necessary to define and configure your Log Analytics Workspaces.

@description('An array of objects, each representing the configuration for a Log Analytics workspace to be deployed.')
param workspaces array = []

@description('The tags to be associated with the resources.')
param tags object = {
  bicep: 'true'
  environment: ''

var workspaceIds = [for workspace in workspaces: {
  id: resourceId('Microsoft.OperationalInsights/workspaces',

resource law 'Microsoft.OperationalInsights/workspaces@2022-10-01' = [for workspace in workspaces: {
  location: workspace.location
  tags: tags
  identity: {
    type: workspace.identityType
    userAssignedIdentities: workspace.identityType == 'UserAssigned' ? workspace.userAssignedIdentities : null
  properties: {
    defaultDataCollectionRuleResourceId: workspace.defaultDataCollectionRuleResourceId
    features: {
      clusterResourceId: workspace.clusterResourceId
      disableLocalAuth: workspace.disableLocalAuth
      enableDataExport: workspace.enableDataExport
      enableLogAccessUsingOnlyResourcePermissions: workspace.enableLogAccessUsingOnlyResourcePermissions
      immediatePurgeDataOn30Days: workspace.immediatePurgeDataOn30Days
    forceCmkForQuery: workspace.forceCmkForQuery
    publicNetworkAccessForIngestion: workspace.publicNetworkAccessForIngestion
    publicNetworkAccessForQuery: workspace.publicNetworkAccessForQuery
    retentionInDays: workspace.retentionDays
    sku: {
      capacityReservationLevel: workspace.capacityReservationLevel
      name: workspace.skuName
    workspaceCapping: {
      dailyQuotaGb: workspace.dailyQuotaGb

output workspaceIds array = workspaceIds

Important: The line of code workspace.identityType == ‘UserAssigned’ ? workspace.userAssignedIdentities : null is critical in determining the type of identity to be assigned to the Log Analytics workspace. This code ensures that the correct type of identity is assigned to each Log Analytics workspace while preventing errors that could occur if userAssignedIdentities were set incorrectly.

Deployment scope>

Deployment scope #

You can target your deployment to a resource group, subscription, management group, or tenant. In this case, you will need an Azure resource group to house all the necessary resources.

Important:By default, when deploying a Bicep template, the scope where the resource should be deployed is a resource group.

You can use an existing Resource Group, or you can create a new Resource Group. If you want to know how to create a Resource Group using Azure CLI, check out this link.

Deploy the Bicep template using the Azure CLI>

Deploy the Bicep template using the Azure CLI #

Once your Bicep template is prepared, and you’ve selected your desired scope, you can proceed to deploy the template through the Azure CLI.


Parameters #

Personalization is key to making your template reusable. With parameters, you can easily tailor the template to your specific needs. You can use either inline parameters or a parameter file to pass parameter values. In my case, I’ll use a file to pass the parameters; here’s an example.

  "$schema": "",
  "contentVersion": "",
  "parameters": {
    "workspaces": {
      "value": [
          "name": "law-demo-we",
          "location": "westeurope",
          "identityType": "SystemAssigned",
          "userAssignedIdentities": null,
          "defaultDataCollectionRuleResourceId": null,
          "clusterResourceId": null,
          "disableLocalAuth": false,
          "enableDataExport": false,
          "enableLogAccessUsingOnlyResourcePermissions": false,
          "immediatePurgeDataOn30Days": true,
          "forceCmkForQuery": false,
          "publicNetworkAccessForIngestion": "Disabled",
          "publicNetworkAccessForQuery": "Disabled",
          "retentionDays": 30,
          "capacityReservationLevel": null,
          "skuName": "PerGB2018",
          "dailyQuotaGb": 1
          "name": "law-demo-ne",
          "location": "northeurope",
          "identityType": "UserAssigned",
          "userAssignedIdentities": {
            "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identityName}": {}
          "defaultDataCollectionRuleResourceId": null,
          "clusterResourceId": null,
          "disableLocalAuth": false,
          "enableDataExport": false,
          "enableLogAccessUsingOnlyResourcePermissions": false,
          "immediatePurgeDataOn30Days": false,
          "forceCmkForQuery": true,
          "publicNetworkAccessForIngestion": "Enabled",
          "publicNetworkAccessForQuery": "Enabled",
          "retentionDays": 60,
          "capacityReservationLevel": null,
          "skuName": "PerGB2018",
          "dailyQuotaGb": 2
    "tags": {
      "value": {
        "environment": "dev",
        "bicep": "true"

Important: Please note that the parameter file stores parameter values in plain text format. If you need to include a parameter with sensitive data, it’s recommended to store the value in a secure key vault.

Preview changes>

Preview changes #

Before deploying a Bicep file, you can preview the changes that will occur to your resources. Using what-if operations doesn’t change existing resources; it simply shows you an output that includes color-coded results that allow you to see different changes.

az deployment group what-if \
--resource-group <resource-group-name> \
--template-file <filename>.bicep \
--parameters @<filename>.parameters.json 
Deploy the Azure resource>

Deploy the Azure resource #

Finally, to deploy the template, run the following command.

az deployment group create \
--resource-group <resource-group-name> \
--template-file <filename>.bicep \
--parameters @<filename>.parameters.json 
Validate the deployment>

Validate the deployment #

To verify that the Log Analytics Workspaces were created correctly, you can either use the Azure Portal or Azure CLI to check the created resources and their configurations.

az monitor log-analytics workspace list \
--resource-group <resource-group-name> \
--output table

References and useful links #

Thank you for taking the time to read my post. I sincerely hope that you find it helpful.