Deploying Azure Resources via powershell and bicep
Posted on Wed 06 March 2024 in azure
Deploying Azure Resources via Powershell
Deploying bicep templates
For the purpose of this article, I'm going to assume you already have your bicep templates made and have them stored in a convention which allows you to parameterise the paths to find them along with hosting profiles.
Start your script with any parameters that you might need
Param(
[Parameter(Mandatory = $True)]
[alias("n")][string]$applicationName,
[Parameter(Mandatory)]
[alias("e")][string]$environment
)
Given that most modern applications will look to deploy resources to more than one environment, maybe as many as four or five for larger companies, it's generally a good idea to define these environments within a hosting profile which your script can access to deploy them a generic manner. I'd strongly advise that a hosting profile only contains non-sensitive data or data which it is simply not possible to put in keyvault or an Azure app configuration instance. For my case, I've setup my bicep templates in a folder called Provisioning which then has sub folders for each applications bicep + hosting profile (which is a json file). We can then get the hosting profile and its environment specific data like this...
$root = Get-Location
$applicationName = $applicationName.ToLower()
$environment = $environment.ToLower()
# load our environment settings from our hosting profiles
$hostingProfiles = Get-Content "$root\Provisioning\$applicationName.json" | ConvertFrom-Json;
$hostingProfile = $hostingProfiles.$environment
My assumption here is that your hosting profile looks something like this...
"dev": {},
"qa": {},
"live": {}
And you should never trust parameters, check the environment actually exists before you go any further with something like this
if ($null -eq $hostingProfiles.$environment) {
Write-Host "No profile is configured for environment $environment. Profile: $hostingProfiles"
exit 1;
}
Once we're a bit more sure that our hosting profile probably contains what we need, we should try to authenticate with azure.
$tenantId = $hostingProfile.tenantId
$subscriptionId = $hostingProfile.subscriptionId
$resourceGroup = $hostingProfile.resourceGroup
Connect-AzAccount -Tenant $tenantId -Subscription $subscriptionId
From there we simply get our template variable referenced and call the azure powershell module to deploy.
# run templated deployment
$templateFile = "$root\Provisioning\$applicationName.bicep"
$deployment = New-AzResourceGroupDeployment `
-ResourceGroupName $resourceGroup `
-TemplateFile $templateFile `
-applicationName $applicationName `
-environment $environment
If our bicep templates gives us any output, we can iterate through it and display it.
Foreach($output in $deployment.Outputs.Keys)
{
$keyValue = $deployment.Outputs.$output.Value
if ($null -eq $keyValue)
{
Write-Host "Output from key : $output is null - this suggests strongly that the deployment failed."
exit 1;
}
Write-Host $output " : " $keyValue
}
We can also check if anything appears to have gone wrong with the bicep template and we want to exit with a code of 1, which would generally get picked up as a failed script.