1

I created a Resource Manager Project in Visual Studio 2017 and as result got Deploy-AzureResourceGroup.ps1 that deploys the template to Azure. But I have multiple templates and would like to be able to deploy them in parallel with PowerShell. My current approach iterates over each template and deploys them sequentially what takes a lot of time.

How can I achieve that?

Edit: taking the response from @4c74356b41 into account. I need to execute some more logic as part of the job. Therefore it is not enough just to execute the ResourceGroupDeployment in parallel.

1
  • If you're interested, Terraform can greatly simplify deployments. The day we moved from PowerShell to Terraform was a beautiful day. Commented Aug 28, 2018 at 17:13

2 Answers 2

2
  • First of all get all relevant templates e.g. via

$armTemplateFiles = Get-ChildItem -Path $PSScriptRoot -Include *.JobTemplate.json -Recurse;

  • Now iterate over each template file and create a job for each one (these jobs are then executed in parallel)

Code:

foreach ($armTemplateFile in $armTemplateFiles) {
    $logic = {
        Param(
            [object] 
            [Parameter(Mandatory=$true)]
            $ctx,

            [object] 
            [Parameter(Mandatory=$true)]
            $armTemplateFile,

            [string] 
            [Parameter(Mandatory=$true)]
            $resourceGroupName
        )

        function Format-ValidationOutput {
            param ($ValidationOutput, [int] $Depth = 0)
            Set-StrictMode -Off
            return @($ValidationOutput | Where-Object { $_ -ne $null } | ForEach-Object { @('  ' * $Depth + ': ' + $_.Message) + @(Format-ValidationOutput @($_.Details) ($Depth + 1)) })
        }

        # Get related parameters file
        $paramTemplateFile = Get-ChildItem -Path $armTemplateFile.FullName.Replace("JobTemplate.json", "JobTemplate.parameters.json")

        # Test Deployment
        $ErrorMessages = Format-ValidationOutput (Test-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName `
                                                                                        -TemplateFile $armTemplateFile.FullName `
                                                                                        -TemplateParameterFile $paramTemplateFile.FullName `
                                                                                        -DefaultProfile $ctx)
        if ($ErrorMessages) {
            Write-Host '', 'Validation returned the following errors:', @($ErrorMessages), '', 'Template is invalid.'
        }
        else { # Deploy

            New-AzureRmResourceGroupDeployment -Name (($armTemplateFile.Name).Split(".")[0] + ((Get-Date).ToUniversalTime()).ToString('MMddHHmm')) `
                                                -ResourceGroupName $resourceGroupName `
                                                -TemplateFile $armTemplateFile.FullName `
                                                -TemplateParameterFile $paramTemplateFile.FullName `
                                                -Force `
                                                -ErrorVariable ErrorMessages `
                                                -DefaultProfile $ctx
            if ($ErrorMessages) {
                Write-Host '', 'Template deployment returned the following errors:', @(@($ErrorMessages) | ForEach-Object { $_.Exception.Message.TrimEnd("`r`n") })
            }
        }
    }
    Start-Job $logic -ArgumentList (Get-AzureRmContext), $armTemplateFile, $ResourceGroupName
}

While (Get-Job -State "Running")
{
    Start-Sleep 10
    Write-Host "Jobs still running..."
}

Get-Job | Receive-Job
Sign up to request clarification or add additional context in comments.

Comments

1

Extremely bad solution, a lot of overcomplication.

New-AzureRmResourceGroupDeployment -ResourceGroup xxx -TemplateFile xxx -AsJob

and you need a loop on top of this

1 Comment

good to know when there is a better way :) I will test if what you proposed works the way I need it. But what I have shown is only part of the total story. I have some more logic in the code that is not relevant to the question and these steps also need to be parallized. Therefore my approach could make sense ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.