0
votes

We have a number of Azure function apps to deploy, using the same code. In our Azure DevOps pipeline we have an Azure PowerShell (4.*) script to deploy the code and start the function app:

Param (
  [string]   $resourceGroupName,
  [string[]] $funcapps,
  [string]   $filePath
)

Write-Output "Deploying the following function apps: $funcapps";

foreach ($app in $funcapps) 
{ 
  Write-Output "Deploying function app: $app";
  $webapp = Publish-AzWebapp -ResourceGroupName $resourceGroupname -Name $app -ArchivePath $filePath -Force;

  Write-Output "Starting function app: $app";
  $webapp = Start-AzWebApp -ResourceGroupName $resourceGroupName -Name $app;

  Write-Output "Started function app: $app = $($webapp.State)";
}

This works fine (both from local PowerShell and from Azure DevOps), but with the number of apps we're deploying can take a while. To try to make it perform better, we tried to run the publish/start statements in parallel:

Param (
  [string]   $resourceGroupName,
  [string[]] $funcapps,
  [string]   $filePath
)

Workflow Parallel-Deploy {  
    Param (
      [string]   $resourceGroupName,
      [string[]] $funcapps,
      [string]   $filePath
    )

    Write-Output "Deploying the following function apps: $funcapps";

    foreach -parallel($app in $funcapps) 
    { 
      Write-Output "Deploying function app: $app";
      $webapp = Publish-AzWebapp -ResourceGroupName $resourceGroupname -Name $app -ArchivePath $filePath -Force;

      Write-Output "Starting function app: $app";
      $webapp = Start-AzWebApp -ResourceGroupName $resourceGroupName -Name $app;

      Write-Output "Started function app: $app = $($webapp.State)";
    }
}

Parallel-Deploy -resourceGroupName $resourceGroupName -funcapps $funcapps -filePath $filePath

The code is the same, just moved into a Workflow to use "foreach -parallel". If I run the script from a local PowerShell, everything works fine - but from the Azure DevOps pipeline, I get an error, No account found in the context. Please login using Connect-AzAccount.

I've found reference to changes made in the Azure PowerShell DevOps task, that the context needs to be passed explicitly to background tasks. I tried to follow the example listed (Save-AzContext and Import-AzContext - updating from the Save-AzureRmContext/Import-AzureRmContext in the example), but it's still giving me the same error.

Any suggestions on what I'm doing wrong, and how to get the context correctly set inside the "foreach -parallel" block?

Edit 1 I probably should have shown exactly what I did for SaveContext/ImportContext...

Param (
  [string]   $resourceGroupName,
  [string[]] $funcapps,
  [string]   $filePath,
  [string]   $tmpDir
)

$contextPath = "$tmpDir/context.json"
Save-AzContext -Path $contextPath" -Force

Workflow Parallel-Deploy {  
    Param (
      [string]   $resourceGroupName,
      [string[]] $funcapps,
      [string]   $filePath,
      [string]   $contextPath
    )

    foreach -parallel($app in $funcapps) 
    { 
      # Output context - initially not set
      Get-AzContext;

      # Fetch and display context - now set
      Import-AzContext -Path $contextPath;
      Get-AzContext; 

      Write-Output "Deploying function app: $app";
      $webapp = Publish-AzWebapp -ResourceGroupName $resourceGroupname -Name $app -ArchivePath $filePath -Force;
...

This still gave me the error that the account wasn't found in the context.

As per the suggestions, I changed to using a job instead:

foreach ($app in $funcapps) {
  $jobname = "$app-Job";
  Start-Job -Name $jobname -ScriptBlock {
    Param (
      [string]   $resourceGroupName,
      [string[]] $funcapps,
      [string]   $filePath,
      [string]   $contextPath
    )

    # Output context - initially not set
    Get-AzContext;

    # Fetch and display context - now set
    Import-AzContext -Path $contextPath;
    Get-AzContext; 

    Write-Output "Deploying function app: $app";
    $webapp = Publish-AzWebapp -ResourceGroupName $resourceGroupname -Name $app -ArchivePath $filePath -Force;
...

And this too said the context wasn't correct.

1
Oh you're talking about workflows, not powershell 7. Have you tried jobs or threadjobs?js2010
Hi @Bill Turner How was it going with this case? Did you get it working using save/import?Levi Lu-MSFT
Due to other competing priorities (hard to put out fires when the guy with matches is still running around...) I haven't had a chance to try this.Bill Turner
@Bill Turner If you get a chance to try it out, please share how it is going? ThanksLevi Lu-MSFT
No joy on that front - changed script to use Start-Job inside a ForEach loop (not parallel), and still getting "No account found in the context." Using Save-AzContext and Import-AzContext looks it it's getting the right information, but doesn't actually work. Give me a bit and I'll edit my question with what I tried.Bill Turner

1 Answers

2
votes

save\import should work just fine, as well as just allowing the context autosave Enable-AzContextAutosave.

Alternatively you can just a native capability to launch cmdlets as jobs:

Publish-AzWebapp -ResourceGroupName $resourceGroupname -Name $app `
   -ArchivePath $filePath -Force -AsJob

and then just wait for the jobs to finish and start the webapps.