Skip to main content

Managing Azure VM Guest and host updates (Azure DevOps)

Howdy folks,

Back again with a new blog post. This time it's about Azure VM Guest and VM host update management during the VM deployment process. I'm writing this blog assuming you have a good understanding of how to manage Azure VM updates from Azure

In a recent project, there was a requirement to create an environment for a software deployment solution. And as part of the solution, automatic VM update is among one of the requirements.

There are great articles from Microsoft and as well as other consultants on how to manage windows update in Azure, this article is slightly different and explain how to achieve this via pipeline

Without further due following are the key component we need to set up.


ComponentDeployment Method
Log Analytics WorkspaceBICEP
Automation AccountBICEP
Link Automation to WorkspaceBICEP
Update SolutionBICEP
Provision Update ScheduleAzure Powershell command in the pipeline
Add enable updates for VMAzure Powershell command in the pipeline

As you can see there is an inter-dependency between automation account and workspace. So during my provisioning process, I followed below


In this situation, I had to provision the log analytics workspace first to capture the automation account logs. And I had to use Powershell to execute the last two stages inside the pipeline

Following are the bicep templates. All 4 components were saved in 4 separate modules and using my main bicep file I have called the 4 modules. During the bicep deployment, I had to set the dependencies to module files. Once the four modules are deployed I have added another stage to run the PowerShell scripts.

Log Analytics Workspace

// Resource Definition
resource loganalytics 'Microsoft.OperationalInsights/workspaces@2020-08-01' = {
name: workspaceName
location: location
tags: !empty(tags) ? tags : json('null')
properties: {
sku: {
name: 'PerGB2018'
capacityReservationLevel: (capacityReservation == 0) ? json('null') : capacityReservation
}
retentionInDays: retentionInDays
features: {
searchVersion: 1
enableLogAccessUsingOnlyResourcePermissions: true
}
}
}

Automation Account

resource automationAccount 'Microsoft.Automation/automationAccounts@2020-01-13-preview' = {
name: autoAccountName
location: location
tags: !empty(tags) ? tags : json('null')
identity: {
type: 'SystemAssigned'
}
properties: {
sku: {
name: sku
}
}
}
// Log Analytics Workspace Automation Link

@description('The name of the resource.')
param workspaceName string

@description('Location of the resource.')
param automationAccountName string


resource logAnalyticsAutomation 'Microsoft.OperationalInsights/workspaces/linkedServices@2020-08-01' = if (!empty(automationAccountName)) {
name: '${workspaceName}/Automation'
properties: {
resourceId: resourceId('Microsoft.Automation/automationAccounts', automationAccountName)
}
}

Enable Update Solution

@description('Log Analytics Workspace ID')
param logAnalyticsId string

@description('Log Analytics Workspace Name')
param logAnalyticsName string

@description('Location')
param location string

var updateManagementName = 'Updates(${logAnalyticsName})'

resource update 'Microsoft.OperationsManagement/solutions@2015-11-01-preview' = {
name: updateManagementName
location: location
properties: {
workspaceResourceId: logAnalyticsId
}
plan: {
name: updateManagementName
publisher: 'Microsoft'
product: 'OMSGallery/Updates'
promotionCode: ''
}
}

#Note : One Special thing to not when deploying the solution. Name of the solution should be in following format 'Updates(${you_log_analytics_workspace_name})'. Otherwise the solution will not deploy and throw an error.

I have used below yml code to deploy the main bicep file.

I have used the below YML part to deploy the main bicep file (Note: my main yml file name is management.main.bicep)

- stage: Build_Management_Services
jobs:
- job: buildManagement
steps:
- checkout: self
- task: AzureCLI@2
displayName: 'Deploy Management Bicep Template File'
inputs:
azureSubscription: ${{ parameters.azureSubscription }}
scriptType: 'pscore'
scriptLocation: 'inlineScript'
inlineScript: |
az deployment sub create --location australiaeast `
--template-file 'main/platform-services/management/management.main.bicep' `
--parameters lzShortName=${{ parameters.lzShortName }} custShortName=${{ parameters.custShortName }} envShortName=${{ variables.envShortName }} `
enablePaaSFirewall=${{ parameters.enablePaaSFirewall }} enableResourceLock=${{ parameters.enableResourceLock }} location=${{ parameters.location }}

Provision Update Schedule and Enable VM Updates (Inside the pipeline)

- stage: Enable_VM_Updates
jobs:
- job: enableVMUpdates
steps:
- checkout: self
- task: AzureCLI@2
name: enableVMBackups
displayName: 'Enable VM Backups'
inputs:
azureSubscription: ${{ parameters.azureSubscription }}
scriptType: 'pscore'
scriptLocation: 'inlineScript'
inlineScript: |
$resourceGroup=Get-AzDeploymentOperation workloads.vm.app --query properties.outputs.rgName.value -o tsv
$AutomationAccountName=Get-AzDeploymentOperation management.main --query properties.outputs.automationName.value -o tsv
$logAnalytics=Get-AzDeploymentOperation subscription.main --query properties.outputs.logWorkspaceName.value -o tsv
echo $AutomationAccountName
echo $resourceGroupName
$duration = New-TimeSpan -Hours 2
$StartTime = (Get-Date "23:00:00").Adddays(1)
Write-Host "Wait Until VM Extensions are enabled"
Start-Sleep -Seconds 180
$Schedule = New-AzAutomationSchedule -AutomationAccountName $AutomationAccountName -Name ${{ parameters.updateScheduleName }} -StartTime $StartTime -MonthInterval 1 -ResourceGroupName $ResourceGroup -DayOfWeekOccurrence ${{ parameters.weektoInstallUpdate }} -DayOfWeek Friday -TimeZone 'AUS Eastern Standard Time'
$VMIDs = (Get-AzVM -ResourceGroupName $resourceGroup).Id
New-AzAutomationSoftwareUpdateConfiguration -ResourceGroupName $resourceGroup -Schedule $Schedule -Windows -AzureVMResourceId $VMIDs -Duration $duration -IncludedUpdateClassification Critical,Security,Definition,UpdateRollup,Updates -AutomationAccountName $AutomationAccountName -Verbose

If you are re-using this code, you may need to fix the tabs accordingly in yml file as per below.

I haven't documented the full bicep deployment and main file creation. I'm guessing If you have come this far you have a good understanding of bicep language.

Finally, there are a few more things to watch out

  1. Update solution Name - The name of the solution should be in the following format 'Updates(${you_log_analytics_workspace_name})'. Otherwise, the solution will not deploy and throw an error.
  2. All 6 components required for this to work properly
  3. Follow the component hierarchy when deploying

As always feel free to reach out to me with any questions that you have. Or let me know If I have done a mistake

Until next time......

For more information

https://docs.microsoft.com/en-us/azure/virtual-machines/automatic-vm-guest-patching

https://docs.microsoft.com/en-us/azure/automation/update-management/enable-from-template










Comments

Popular posts from this blog

Deploying an Automation Account with a Runbook and Schedule Using Bicep

Introduction Automation is a key component in many organizations' cloud strategy. Azure Automation allows you to automate the creation, deployment, and management of resources in your Azure environment. In this post, we will walk through the process of deploying an Automation Account with a Runbook and Schedule using Bicep, a new domain-specific language for deploying Azure resources. Intention My intention at the  end is to run a PowerShell  script to start and shutdown Azure VMs based on tag values. PowerShell  script that I have used is from below l ink.  And two  of me   collogue s ( Michael Turnley   and Saudh Mohomad helped to modify the  PowerShell  script. Prerequisites Before we begin, you will need the following: An Azure subscription The Azure CLI installed on your machine. The Azure Bicep extension for the Azure CLI Creating the Automation Account The first step in deploying an Automation Account with a Runbook and Schedule is to create the Aut

Migrating Azure DevOps Variable Groups

Howdy Folks, I was working on an application modernization project. And there was a requirement to migrate application deployments from one project to another in Azure DevOps. deployment pipelines were heavily dependent on variable groups. So, we wanted to migrate these variables group to the new project. Couldn't find any solutions in internet for this, so came up with the below scripts. You can grab the scripts from the below GitHub URL. DaniduWeerasinghe911/Migrate-Azure-DevOps-Variable-Groups: This Repo Include PowerShell Scripts relating to Migrating Azure DevOps Variable Groups (github.com) Azure DevOps Variable Groups Azure DevOps Variable Groups are a way to store and manage sets of variables that can be used across multiple pipelines in Azure DevOps. These variables can include secrets, connection strings, and other sensitive information that is needed for builds and releases. Variable Groups provide a centralized way to manage these variables and ensure that they are cons

Securing Azure Services with Fetian FIDO

Hey Folks  Here again with another security topic with Fetian Fido. And once again Fetian devices proved their excellent quality and stability. For this I choose Fetian K33 -  AllinPass FIDO Security Key – FEITIAN (ftsafe.com) and  K39 -  Single-button FIDO Security Keys | FEITIAN (ftsafe.com) Use case  In an organization following changes needs to be implemented.  1. Update the password policy 2. Update the user session time out to 30 minutes Once these changes being implemented, the following issues need to be addressed 1. Users' complaint new passwords need to be so long 2. Users complain sessions time out makes them work so much slower with the longer passwords 3. Etc... Solution  One of my friends reached out to me to help solve this problem. All I could think of was using passwordless auth with FIDO devices. We have decided to use Fido2 keys for better security and flexibility for the users. The FIDO (Fast IDentity Online) Alliance helps to promote open authentication stand