Skip to main content

Posts

Azure Automation variables in Bicep

If you want to create an Azure Automation variable in Bicep you will use a resource definition like this. resource existingAutomationAccountResource 'Microsoft.Automation/automationAccounts@2023-11-01' existing = { name: 'automationAccountName' } resource variablesResource 'Microsoft.Automation/automationAccounts/variables@2023-11-01' = { name: 'variableName' parent: existingAutomationAccountResource properties: { description: 'description' isEncrypted: 'false' value: 'value' } } For variables Azure Automation supports different types: String , Boolean , DateTime , Integer and Not Specified . Below you can find some examples how to define these values in Bicep format. String values should be put between double quotes. resource stringVariablesResource 'Microsoft.Automation/automationAccounts/variables@2023-11-01' = { name: 'stringVariable' parent: existingAutomationAccountResource ...

Solving Azure DevOps Workload Identity Federation service connection 50 minute time-out error

 When connecting to external resources like Azure Resource Manager you will need a service connection in Azure DevOps. Normally I utilize a service principal for this purpose. The certificate issued by Microsoft Entra ID was normally valid for two years but Microsoft changed this to three months in the release of January 18th and is promoting the usage of Workload identity federation  (WIF). When testing this WIF based service connection I noticed that the OIDC token is only valid for about 50 minutes. This time is to short for the PowerShell script I use to monitor the Azure Image Builder image builds. These image build processes can take up to four hours but fail now with an error message like the one below. A configuration issue is preventing authentication - check the error message from the server for details. You can modify the configuration in the application registration portal. See https://aka.ms/msal-net-invalid-client for details.  Original exception: AADSTS700...

Solve code coverage issue with Azure Functions

 I tried to execute code coverage for an Azure Function project with the Coverlet NuGet package. When running the unit test phase I received the following error message and no code coverage file was generated for the Azure Function project. Data collector 'XPlat code coverage' message: [coverlet]System.TypeLoadException: Could not load type 'Microsoft.Extensions.DependencyInjection.ServiceCollection' from assembly 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.    at Coverlet.Collector.DataCollection.CoverletCoverageCollector.GetDefaultServiceCollection(TestPlatformEqtTrace eqtTrace, TestPlatformLogger logger, String testModule)    at Coverlet.Collector.DataCollection.CoverletCoverageCollector.OnSessionStart(Object sender, SessionStartEventArgs sessionStartEventArgs) in /_/src/coverlet.collector/DataCollection/CoverletCoverageCollector.cs:line 135. To solve this issue you have to add the...

How to control the 'Propagate Default Route' setting of a Azure VHub Network Connection from code

 Using Azure Virtual WAN for your hub/spoke network and want to know how to control the 'Propagate Default Route' setting on a Azure VHub Network Connection via code? Modifying this setting via the UI is easy. Go to the specific virtual network connection in the Virtual network connections setting of the Virtual WAN and change the value from Enable into Disable or vice versa. How to do this via code was a mystery for me until I consulted Microsoft support. If you consult the documentation for maintaining the virtual hub network connection you don't find a setting named 'Propogate Default Route' or a mention in the description about it. ARM / Bicep - Hub virtual network connections PowerShell - New-AzVirtualHubVnetConnection Azure CLI - az network vhub connection Microsoft Support explained that the attribute  enableInternetSecurity , with description 'Enable internet security.', is actually controlling the behavior off the option 'Propagate Default Ro...

Azure Login fails with ERR_SSL_PROTOCOL_ERROR

When you try to login to Azure (Azure CLI / Visual Studio Code) it will not succeed in Chrome. After the authentication phase your browser will be redirected to a HTTPS localhost URI. The browser will responded with the following message. This site can’t provide a secure connection localhost sent an invalid response. Try running Windows Network Diagnostics. ERR_SSL_PROTOCOL_ERROR This behavior is caused by a HTTPS policy within Chrome. To remove this policy you will have to do the following:  Go to chrome://net-internals/#hsts Under Delete domain security policies fill in localhost and click Delete .

AdvancedSchedule generates error when using monthDays for new schedule

If I want to deploy a monthly schedule on for example the last day of the month I encounter an error message when I used the REST API or the ARM template. The body of the REST API for creating schedules I used look likes this: { "name": "demoSchedule", "properties": { "startTime": "2022-05-07T22:00:00+02:00", "interval": 1, "frequency": "Month", "advancedSchedule": { "weekDays": [], "monthDays": [ -1 ], "monthlyOccurrences": [] } } } When I execute this REST call I receive the following error message: { "code": "BadRequest", "message": "Argument requestScheduleData with value Orchestrator.Schedules.DataAccess.Models.ScheduleAllData is not valid. Error message: The input value is not valid for Monthly Schedule Type" } After spending a lot of time of trial & error I ...

Assign role assignments by name in ARM templates

When you want to do a role assignment to a principal in an ARM template you will use code like the one below. In this example the role definition is actual the object id of the role. If you want to assign the contributor role you will use the value 'b24988ac-6180-42a0-ab88-20f7382dd24c'. You also have to specify the id of the principal so you will have to retrieve that value yourself upfront. { "type": "Microsoft.Authorization/roleAssignments", "apiVersion": "2020-04-01-preview", "name": "[guid(parameters('roleAssignmentName'))]", "properties": { "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', parameters('roleDefinitionId'))]", "principalId": "[parameters('principalId')]", "scope": "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters(...

Permantly delete an AD object

At the moment I am busy with PowerShell DSC scripts that also create objects within the Active Directory. Because it's work in progress you have to delete those objects regularly. Witin this sandbox environment the recycle bin feature is enabled so the objects are kept 30 days.  To permantly delete such objects (so you have a clean testing situation) you can use the following PowerShell command. Get-ADObject -filter {sAMAccountName -eq "<name of object>$"} -includeDeletedObjects -property * | Remove-ADObject

The command was found in the module PowerShellGet, but the module could not be loaded.

While testing a PowerShell DSC script deployed by Azure Automation on an Azure Virtual Machine I ran against the following error message:  The command <command> was found in the module PowerShellGet, but the module could not be loaded. What I tried to accomplish was automatically installing the PowerShell Az modules with the following PowerShell DSC script. # Import DSC modules Import-DscResource -ModuleName "PowerShellGet" -ModuleVersion 2.2.5 Node $AllNodes.NodeName { PSModule "Az" { Ensure = "Present" Name = "Az" Repository = "PSGallery" InstallationPolicy = "Trusted" AllowClobber = $true Force = $true RequiredVersion = 5.6.0 } } To solve this issue you also have to import the PackageManagement module because PowerShellGet has a dependency on this module. The correct version of the script is thus: # Import DSC modules Import...

Azure Automation: Use a nested ARM template as an user defined function to bypass the start time issue of schedules

Lately I am busy with Azure Automation . In terms of ARM templates I run into a number of issues with this product. See also my previous blog postings about this. This time too I had to look for another workaround. In this case it concerns the start time of a schedule . This must be at least 5 minutes in the future for the product group each time you do an ARM deployment for the schedule object. This resource is also not complying to the idempotency rules of ARM template. My workaround is to mark the date part of the startTime (for daily, weekly, montly recurring schedules) in my parameter file with ' GEN-DATE ' placeholder and my ARM template will generate each time the correct date if I do the deploy. To replace the placeholder with the correct value I first thought to use an user defined function for this purpose. After reading the documentation, I could conclude that this functionality did not match what I needed. An user defined function consist of input parameters and ...

Creating a managed service account with PowerShell DSC fails: The KDS Root Key was not found

At the moment I am busy with automating the creation of a Windows 2019 server with the Active Directory role enabled. My PowerShell DSC script is hosted in Azure Automation wich acts as the pull server. The script is installing the Active Directory role and configuring the domain. During my initial test I got the following error when the script tries to create a Managed Service Account. System.InvalidOperationException: Error adding group account 'gMSA-ADSync'. The KDS Root Key was not found. (MSA0019) Microsoft.ActiveDirectory.Management.ADException: Key does not exist System.ServiceModel.FaultException: Active Directory returned an error processing the operation. After doing some research I found out what the reason for this is. According the Microsoft documentation  the reason for this behavior is as follows: Domain Controllers (DC) require a root key to begin generating gMSA passwords. The domain controllers will wait up to 10 hours from time of creation to allow all dom...

Azure Automation: deploy webhooks with ARM templates

The implementation of Azure Automation in ARM templates has some quirks. The last time I blogged about the lack of idempotency for the jobSchedule resource. In this article I will write about the solution I had to write because the ARM template for webhooks has a little flaw. If you read the template reference documentation you can see that the template format is as follows. { "name": "string", "type": "Microsoft.Automation/automationAccounts/webhooks", "apiVersion": "2015-10-31", "properties": { "isEnabled": "boolean", "uri": "string", "expiryTime": "string", "parameters": {}, "runbook": { "name": "string" }, "runOn": "string" } } Quite straight forward you will think but there is one catch: there are some properties which are defined as not required ...

Azure Automation: Solve the 'A job schedule for the specified runbook and schedule already exists' issue

This week I was busy with writing ARM templates for deploying a runbook within an Azure Automation account. One of the parts you need for this is the jobSchedule object. The first time I created the object the deployment went succesful but when I deployed the same template a second time the deployment fails with the error message "A job schedule for the specified runbook and schedule already exists".  After doing some research I found out that I was not the only one. In Azure Feedback I found a bug item from Yulun Zeng dated January 24, 2018 who encountered the same issue. The bug is under review since January 7, 2020 but is still not solved. Some of the Azure Automation resources are conflicting with a fundamental rule of ARM templates documented by Microsoft. Repeatable results: Repeatedly deploy your infrastructure throughout the development lifecycle and have confidence your resources are deployed in a consistent manner. Templates are idempotent, which means you can ...

Make steps conditional in multi-stage YAML pipelines

To make the switch from the graphical release pipelines in Azure DevOps I am missing two features. The first one is to be able to defer a deploy and the second one is to exclude certain deployment steps without the need for editing the YAML file.  The defer option is something Microsoft has to solve in their Azure DevOps proposition. It's a feature which you have in the graphical release pipeline but what they have not implemented yet in their YAML pipeline replacement. Approvals and certain gate conditions are implemented on the environment but the defer option is still missing .  Pipeline The conditional deployment option can be implemented with the help of runtime parameters and expressions . In the parameter section you define boolean parameters which will control the deploy behavior. With the expressions you can control which stage/job/task should be executed when the pipeline runs. In the below YAML sample I experimented with conditions in the azure-pipelines.yml ...

Azure DevOps YAML based CD pipeline with multiple artifacts

In my post called " Switch from Azure DevOps release pipeline to YAML based CI/CD pipeline " I explained how to implement a combined CI/CD pipeline based on YAML templates. Because most of the deployments in my daily work are consuming multiple artifacts I had to do some additional R&D to find a solution for those releases in Azure DevOps. Base structure In the first post about the transition to YAML CI/CD pipelines I introduced the base structure. The templates I want to reuse are added to the yaml-template folders in the root of my GIT repo. For the CD pipelines which lack a CI phase I introduce a new folder called yaml-releases which will contain the YAML files for releases which are based on multiple artifacts. The folder structure within my GIT repo is thus: yaml-releases releaseArea myMultipleArtifactsRelease azure-pipelines.yml cd-job.yml yaml-templates jobs ... templates ......

Switch from Azure DevOps release pipeline to YAML based CI/CD pipeline

It has been years ago I started applying continuous integration (CI) and continuous deployment (CD) principles at work. Around 2005, it was the time of Visual Studio 2005 Team System, we started using a build server in our daily development process. From then on it was no longer more: "it works on my machine". With every check-in of code changes a CI build was started which compiled your code and run unit tests which verified the quality of your code.  Deployment was in the beginning still a process of manually copying build artifacts and script files to servers and doing the installation process based on the instructions from the deployment manual (if available). Gradually it migrated to scripts (mix of batch/PowerShell/VBScript files) that our release automatically ran from the build server. In 2016 we migrated from our on-premise TFS 2008 based environment to the cloud solution nowadays known as Azure DevOps . We upgraded our MSBuild driven CI/CD pipelines to the new vis...