Enhancing Azure Security and Monitoring with Infrastructure-as-Code
Written on
Chapter 1: Introduction to Infrastructure-as-Code in Azure
This article delves into the utilization of Infrastructure-as-Code through the Bicep Language, focusing on the implementation of a tailored monitoring solution within Azure. We will explore the integration of Azure Monitor and Log Analytics, along with the configuration of a virtual machine to facilitate the collection of telemetry and logs.
The deployment process simplifies all configurations outlined in the GitHub repository for the AZ-500 Lab 013 Azure Security Technologies:
Prerequisites
To get started, ensure you have the following:
- An active Azure account, which you can create at no cost.
- Azure Bicep installed on your local machine.
- Azure PowerShell set up. For more details, refer to the Azure PowerShell installation guide.
- A resource group established in your Azure subscription.
Let's dive in!
Solution Overview
We will create a Bicep template that handles the following tasks:
- Deploy an Azure virtual machine.
- Establish a Log Analytics workspace.
- Activate the Log Analytics virtual machine extension.
The solution will consist of these files:
- ๐ main.bicep: The main Bicep template.
- ๐ azuredeploy.parameters.json: This parameter file includes the values necessary for deploying your Bicep template.
Section 1.1: Creating the Azure Bicep Template
To begin, create a new file in your working directory named main.bicep. We will define the following parameters:
@description('Username for the Virtual Machine.')
param adminUsername string = 'localadmin'
@description('Password for the Virtual Machine.')
@minLength(12)
@secure()
param adminPassword string
@description('Unique DNS Name for the Public IP used to access the Virtual Machine.')
param dnsLabelPrefix string = toLower('${vmName}-${uniqueString(resourceGroup().id, vmName)}')
@description('Name for the Public IP used to access the Virtual Machine.')
param publicIpName string = 'myPublicIpAddress'
@description('Allocation method for the Public IP used to access the Virtual Machine.')
@allowed(['Dynamic', 'Static'])
param publicIPAllocationMethod string = 'Static'
@description('SKU for the Public IP used to access the Virtual Machine.')
@allowed(['Basic', 'Standard'])
param publicIpSku string = 'Standard'
@description('The Windows version for the VM. This will pick a fully patched image of this given Windows version.')
@allowed(['2016-Datacenter', '2022-datacenter', '2022-datacenter-azure-edition-core'])
param OSVersion string = '2022-datacenter-azure-edition-core'
@description('Size of the virtual machine.')
param vmSize string = 'Standard_D2s_v5'
@description('Location for all resources.')
param location string = 'eastus'
@description('Name of the virtual machine.')
param vmName string = 'myVM'
param logAnalyticsWorkspaceName string = 'la-${uniqueString(resourceGroup().id)}'
Section 1.2: Defining Variables in Azure Bicep
Next, we will establish the following variables:
var storageAccountName = 'bootdiags${uniqueString(resourceGroup().id)}'
var nicName = 'myVMNic'
var addressPrefix = '192.168.0.0/16'
var subnetName = 'mySubnet'
var subnetPrefix = '192.168.1.0/24'
var virtualNetworkName = 'myVnet'
var networkSecurityGroupName = 'myNetworkSecurityGroup'
var primaryKey = logAnalyticsWorkspace.listKeys().primarySharedKey
Itโs important to note that we utilize the listKeys() function to obtain the primary key of the Log Analytics workspace, which is necessary for the correct configuration of the virtual machine extension.
Chapter 2: Resource Definition in Azure Bicep
In this section, we will define the required resources for our deployment.
// Task 1: Deploy an Azure virtual machine with a public IP address and a network security group
resource stg 'Microsoft.Storage/storageAccounts@2021-04-01' = {
name: storageAccountName
location: location
sku: {
name: 'Standard_LRS'}
kind: 'Storage'
}
// Additional resource definitions for public IP, network security group, virtual network, etc.
The first video titled Flexing Your Security Governance with Azure Policy As Code discusses how to implement security governance in Azure using policy as code. It provides insights on enhancing security measures through automated policies.
// Task 2: Create a Log Analytics workspace
resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' = {
name: logAnalyticsWorkspaceName
location: location
properties: {
retentionInDays: 30
features: {
searchVersion: 1}
sku: {
name: 'PerGB2018'}
}
}
// Task 3: Enable the Log Analytics virtual machine extension
resource vmExtension 'Microsoft.Compute/virtualMachines/extensions@2022-11-01' = {
parent: vm
name: 'Microsoft.Insights.LogAnalyticsAgent'
location: location
properties: {
publisher: 'Microsoft.Azure.Monitor'
type: 'AzureMonitorWindowsAgent'
autoUpgradeMinorVersion: true
typeHandlerVersion: '1.14'
settings: {
workspaceId: logAnalyticsWorkspace.id}
protectedSettings: {
workspaceKey: primaryKey}
}
}
The second video titled Azure Master Class v2 - Module 11 - IaC & DevOps covers the principles of Infrastructure-as-Code and DevOps practices in Azure. Itโs a comprehensive guide for developers aiming to implement IaC effectively.
Final Steps and Deployment
To conclude, create a new file called azuredeploy.parameters.json to define the parameters. Hereโs a snippet of what it should contain:
{
"contentVersion": "1.0.0.0",
"parameters": {
"adminPassword": {
"value": "AzureTest01!!"}
}
}
Sensitive information like the virtual machine password should not be hardcoded.
To deploy your Bicep template, use the command below:
az deployment group create --resource-group <your-resource-group> --template-file main.bicep --parameters azuredeploy.parameters.json
You can verify the deployment in the Azure Portal.
Source Code
You can access the complete code for this solution at the following GitHub repository:
๐ Join the AzInsider email list for updates!
- Dave R