1
votes

I'm setting up an Azure DevOps self hosted pipeline agent. We have some legacy cloud services, so we need the "old" Azure powershell module that targets the service management API. We also obviously use Azure Resource Manager, so either the AzureRM or the new Az module is also required.

We currently have the Azure module version 5.3.0 and AzureRM module version 6.13.1 being installed using the following commands:

Install-Module -Name Azure -RequiredVersion 5.3.0 -AllowClobber -Scope AllUsers -Force
Install-Module -Name AzureRM -RequiredVersion 6.13.1 -AllowClobber -Scope AllUsers -Force

The problem we're encountering is that, depending on the order these modules are imported, we will get script failures. If, for example, the order of import is Azure followed by AzureRM, we get the following error:

Import-Module : The following error occurred while loading the extended type data file: Error in TypeData "Microsoft.Azure.Commands.Common.Authentication.Abstractions.IAzureContextContainer": The TypeConverter was ignored because it already occurs. Error in TypeData "Microsoft.Azure.Commands.Common.Authentication.Abstractions.IAzureContextContainer": The member SerializationDepth is already present. Error in TypeData "Microsoft.Azure.Commands.Common.Authentication.ProtectedFileTokenCache": The member PropertySerializationSet is already present. Error in TypeData "Microsoft.Azure.Commands.Common.Authentication.ProtectedFileTokenCache": The member SerializationMethod is already present. Error in TypeData "Microsoft.Azure.Commands.Common.Authentication.AuthenticationStoreTokenCache": The member PropertySerializationSet is already present. Error in TypeData "Microsoft.Azure.Commands.Common.Authentication.AuthenticationStoreTokenCache": The member SerializationMethod is already present. Error in TypeData "Microsoft.Azure.Commands.Profile.Models.PSAzureContext": The member SerializationDepth is already present. Error in TypeData "Microsoft.Azure.Commands.Profile.Models.PSAzureProfile": The member SerializationDepth is already present. At C:\Program Files\WindowsPowerShell\Modules\AzureRm\6.13.1\AzureRM.psm1:81 char:1 + Import-Module AzureRM.Profile -RequiredVersion 5.8.2 -Global + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [Import-Module], RuntimeException + FullyQualifiedErrorId : FormatXmlUpdateException,Microsoft.PowerShell.Commands.ImportModuleCommand

You can see this in the following screen shot:

Import Failure

But if import AzureRm first, followed by Azure, it appears to work fine:

Import Success

The problem is, we don't control the order of the imports when using existing pipeline tasks built by Microsoft and others. We're getting failures deploying our cloud services due to the fact the cloud service deployment task built by MS happens to import Azure first.

Lastly, I tried simply not installing the old Azure module, hoping that AzureRM "came with" what it would need to handle some service management API tasks, but it does not. If I try do a deployment without the Azure module installed, we get the error:

Certificate based authentication is not supported. Azure PowerShell module is not found.

So it appears the legacy module is required, and yet it conflicts.

1
just divide those into 2 jobs so they have separate environments?4c74356b41
This is not an option. A single Azure DevOps Pipeline task references both modules - one written by Microsoft.RMD
not sure what do you mean? a single task cannot reference them unless its a script that, in that case nothing prevents you from having 2 script tasks in the same build\release pipeline just under different agent groups\jobs4c74356b41
There is a built in ADO Task called "Azure Cloud Service Deployment". This task references both the Azure and the AzureRM modules. Executing this task results in the error I'm seeing. I have no way to "break" this apart unless you mean re-writing Microsoft task. Here is a link to the tasks source code if you're interested. github.com/microsoft/azure-pipelines-tasks/tree/master/Tasks/…RMD
oh, ic. never used that task. you probably need to raise this on azure powershell gh.4c74356b41

1 Answers

1
votes

This appears to be caused by the order of installation. Flipping the order from Azure then AzureRm to AzureRm then Azure resolved the issue. So the following install commands do not result in the problem:

Install-Module -Name AzureRM -RequiredVersion 6.13.1 -AllowClobber -Scope AllUsers -Force
Install-Module -Name Azure -RequiredVersion 5.3.0 -AllowClobber -Scope AllUsers -Force

It appears the root cause is that the Azure module, if installed first, will always install the most recent version of AzureRm.profile. This appears to be caused by the Azure.Storage module, which has a dependency on AzureRm.profile.

If you install the Azure module first, it will install AzureRm.profile version 5.8.3. When you then install AzureRm, it has a dependency of AzureRm.profile as well, but it will ignore the fact that you already have AzureRm.profile v5.8.3 installed and install AzureRm.profile v5.8.2. I believe this is because while the Azure module has a dependency on AzureRm.profile, the AzureRm module includes AzureRm.profile.

When Import-Module is called for Azure first, it loads v5.8.3 of the AzureRm.profile module, as it will always load the most recent version by design. When, however, AzureRm itself is loaded, it tries to load the version IT came with (v5.8.2), and this fails due to the type error noted in the question.

If you install AzureRM before Azure, it prevents this from happening. Since when the Azure module is being installed it sees there is already a version of AzureRm.profile that satisfies its dependency (or, more specifically, satisfies the dependency that Azure.Storage has), it doesn't install AzureRm.profile again. This leaves only the version that AzureRm was packaged with, and everything is fine.

Lastly, for an existing "broken" environment, running this command resolved the problem:

Uninstall-Module -Name AzureRM.profile -RequiredVersion 5.8.3