Configure Az Module when running Azure Script

I am new to Octopus and I have created a runbook with a single step to execute “Azure Script”. From the online documentation Running Azure PowerShell - Octopus Deploy, it recommends the user to configure its own Azure CLI and Azure Az module version by setting to “Use Azure Tools pre-installed on the worker”. However, the documentation is not clear how or where I can set my own version of the CLI or Az module. Do I install the CLI and Az module on the worker? How can this be accomplished? Include the Install-Module cmdlet inside the Azure Script that I want to deploy? Thanks.

Hi @lawrence.t,

Thanks for getting in touch!

There are a few ways this can be done.

The first would be to do as you mention, add the installation and loading of the Az module to your script and let this run every time the script runs. The downside is that the dynamic worker you use will change, so, the script runtime may increase due to having to download the module each time.

Another way would be to make use of Execution Containers. This feature allows you to select a container image that will be run within the worker that can contain and tools that you require. We do have a base image referenced within the docs.

The final way would be to create a static worker within your own environment and install the required tools on that and assign any necessary steps to run on that worker instead of the dynamic workers.

Regards,
Paul

Paul,

Thanks for the prompt reply. For option #1, I have tried to add the following two lines in he beginning of the Azure script.

  • Invoke-WebRequest -Uri https://aka.ms/installazurecliwindows -OutFile .\AzureCLI.msi; Start-Process msiexec.exe -Wait -ArgumentList ‘/I AzureCLI.msi /quiet’; rm .\AzureCLI.msi
  • Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force

But I am still getting the same error I had before complaining about the az command is not being recognized.

Obtained worker lease successfully.
The version 11.0.0 of the Calamari.AzureScripting.win-x64 tool has not been extracted, it will be extracted automatically.
Version 11.0.0 of the Calamari.AzureScripting.win-x64 tool has been extracted successfully
ObjectNotFound: The term ‘az’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\Octopus\Tentacle\Work\20210703015518-4384-6\Octopus.AzureContext.ps1:205 char:13

  •         az logout 2>$null 3>$null 
    
  •         ~~ 
    

at , C:\Octopus\Tentacle\Work\20210703015518-4384-6\Octopus.AzureContext.ps1: line 205
at , C:\Octopus\Tentacle\Work\20210703015518-4384-6\Bootstrap.Octopus.AzureContext.ps1: line 1469
at , : line 1
at , : line 1
Running rollback behaviours…
Script returned non-zero exit code: 1.
The remote script failed with exit code 1
The action Run an Azure Script on a Worker failed

What is the timing of when AzureContext.ps1 is being executed?

Hi @lawrence.t,

Apologies, I hadn’t considered that you were running an Azure step. This will attempt to setup the Azure connection before running any custom scripts which explains the error you’re receiving.

You may need to try adding the Az install commands to a standard script step that runs before the Azure step.

If that still doesn’t work then it will be a case of using the other options I mentioned.

Regards,
Paul

Paul,

This is what I have observed so far:

  • Using Execution Container
    I have tried to use octopusdeploy/worker-tools:3.0-windows.ltsc2019 container from Docker. The interesting thing is that if my script is simply like

Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force
Get-AzContext

It can be run successfully but if the Get-AzContext is change to Get-AzSubscription, I got an error

InvalidOperation: Run Connect-AzAccount to login.

  • Add install-module in the script
    First of all, I do not think “adding the Az install commands to a standard script step that runs before the Azure step.” will work since I am using dynamic worker unless there is a workaround which can allow me to use the same worker for two different steps. Anyway, I did come across this Azure PowerShell ‘Az’ Module version 1.0 - #4 by Iain_Brown and one of the change is that I have to create a “Run a Script” step instead of “Run Azure Script”. With this change I am able to successfully run the script with Az Powershell module. One concern is that occasionally the run book will fail with an error:

ObjectNotFound: The term ‘Get-AzEnvironment’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
July 9th 2021 20:02:28Error
At C:\Octopus\Tentacle\Work\20210710005326-4581-6\Script.ps1:8 char:10
July 9th 2021 20:02:28Error

  • $azEnv = Get-AzEnvironment -Name $azEnv

The Get-AzEnvironment is the first Az cmdlet to be used in the script. However, the subsequent run will be successful. I am using the default worker pool. I might try to limit the runbook to Win2019 worker pool. Any comments?

When you were running this within the execution container were you using a normal Script step or the Azure script step?
The Azure script step should set up the subscription information based on the Azure account defined within the step or target.

Regarding the intermittent failure, it feels like maybe the Az module setup isn’t fully completing before it moves on to the next part of the script. I’m wondering if adding a wait or similar may help there.

I am just able to get back to my testing today.

  • When you were running this within the execution container were you using a normal Script step or the Azure script step?
    ==> It is an Azure script step

About the failure I am seeing, I did try to put like a minute timer after the Install-Module but it did not really help. Here is the test script I was using.

Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force
Write-Output “Installing Az”
Start-Sleep -Seconds 60

Authenticate via Service Principal

$securePassword = ConvertTo-SecureString $OctopusParameters[“Platform_Deploy.Password”] -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential ($OctopusParameters[“Platform_Deploy.Client”], $securePassword)
$azEnv = if($OctopusParameters[“Platform_Deploy.AzureEnvironment”]) { $OctopusParameters[“Platform_Deploy.AzureEnvironment”] } else { “AzureCloud” }

$azEnv = Get-AzEnvironment -Name $azEnv
if (!$azEnv) {
Write-Error “No Azure environment could be matched given the name $($OctopusParameters[“Platform_Deploy.AzureEnvironment”])”
exit -2
}

Write-Verbose “Authenticating with Service Principal”

Force any output generated to be verbose in Octopus logs.

Login-AzAccount -Credential $creds -TenantId $OctopusParameters[“Platform_Deploy.TenantId”] -SubscriptionId $OctopusParameters[“Platform_Deploy.SubscriptionNumber”] -Environment $azEnv -ServicePrincipal

Get-AzSubscription -subscriptionname ri-ops-dev
Write-Output “I am DONE!!!”

The error I am getting in the first try is:

Leasing WindowsDefault dynamic worker…
July 21st 2021 23:15:51Info
Worker not ready, trying again in 10 seconds
July 21st 2021 23:16:02Info
Worker not ready, trying again in 5 seconds
July 21st 2021 23:16:07Info
Worker not ready, trying again in 5 seconds
July 21st 2021 23:16:13Info
Worker not ready, trying again in 5 seconds
July 21st 2021 23:16:19Info
Obtained worker lease successfully.
July 21st 2021 23:16:22Info
The version 18.1.2 of the Calamari.win-x64 tool has not been extracted, it will be extracted automatically.
July 21st 2021 23:17:11Info
Version 18.1.2 of the Calamari.win-x64 tool has been extracted successfully
July 21st 2021 23:55:41Info
Installing Az
July 21st 2021 23:56:46Error
ObjectNotFound: The term ‘Get-AzEnvironment’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
July 21st 2021 23:56:46Error
At C:\Octopus\Tentacle\Work\20210722041711-4878-6\Script.ps1:9 char:10
July 21st 2021 23:56:46Error

  • $azEnv = Get-AzEnvironment -Name $azEnv
    July 21st 2021 23:56:46Error
  •      ~~~~~~~~~~~~~~~~~ 
    

July 21st 2021 23:56:46Error
at , C:\Octopus\Tentacle\Work\20210722041711-4878-6\Script.ps1: line 9
July 21st 2021 23:56:46Error
at , : line 1
July 21st 2021 23:56:46Error
at , C:\Octopus\Tentacle\Work\20210722041711-4878-6\Octopus.FunctionAppenderContext.ps1: line 185
July 21st 2021 23:56:46Error
at , C:\Octopus\Tentacle\Work\20210722041711-4878-6\Bootstrap.Octopus.FunctionAppenderContext.ps1: line 1464
July 21st 2021 23:56:46Error
at , : line 1
July 21st 2021 23:56:46Error
at , : line 1
July 21st 2021 23:56:47Fatal
The remote script failed with exit code 1
July 21st 2021 23:56:47Fatal
The action Run a Script With Az Module on a Worker failed

The second or subsequent try are usually successful. One of things I am
concerned is that it does take quite a long time to complete a simple script
like this. The failure run takes 40 minutes to return the error and the
successful run takes about 20 minutes to complete. Is this something being
expected?

This is the drawback of installing the tools on the worker each time. It will take some time for the download and install, and it does open it up to errors during the install process.

Using an execution container or creating your own static worker will be more stable options that should also reduce the run time of the deployment.

Hi,

Using the execution container does take away the issue of “having to run the script twice” issue. As far as timing, using the execution container take about 54 minutes to run the script. (The subsequent run is usually faster and my guess is that there is some sort of caching going on in the Octopus cloud). Having a private worker could be faster but there will be a need to maintain the worker ourselves.

The findings should give us enough information what our next step should be. Thanks for your help

1 Like

This topic was automatically closed 31 days after the last reply. New replies are no longer allowed.