Skip to main content

Deployment Script with Bicep - Part 1

· 3 min read
Hasan Gural

When you are working on a project, sometimes you need to deploy your resources to Azure using a script. In this blog post, we will try to cover if we need to execute script for the pre and post deployment how we can achieve this with Bicep while we are deploying our resources to Azure using Bicep.

👉 What are deployment scripts?

DeploymentScripts are a powerful feature that allows you to run either PowerShell or Bash scripts as part of your Bicep deployment. These scripts execute in a Docker container, providing a flexible way to add custom behavior to your deployment process. With either Azure CLI or Azure PowerShell at your disposal, so you can automate almost anything you need to do in your deployment if you have to execute a script before or after the deployment.

⚙️ Deployment script structure

To integrate custom behavior into your Bicep deployment, you begin with the deploymentScripts resource. Here's what you need to set the stage:

  • A name for the deploymentScripts resource.
  • The type and apiVersion values.
  • The location (location value) where the supporting resources will be created.
  • An empty properties object. You'll get to that shortly

Two deploymentScripts-specific values are required:

kind: The type of script to run (either AzurePowerShell or AzureCLI).


resource helloFriendDeploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = {
name: 'helloFriendDeploymentScript'
location: resourceGroup().location
kind: 'AzurePowerShell'
identity: {
type: 'UserAssigned'
userAssignedIdentities: {
'/subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourcegroups/deploymenttest/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myscriptingid': {}
}
}
}

identity: The managed identity that the container instance will use. There are two options for this property:

info

Pre-created Managed Identity: You can create the managed identity before you even start with your Bicep template and then just point to it when you need it.

Create and Reference in Template: If you prefer to keep everything tied to your deployment, you can also define and assign the managed identity right within your Bicep template.

Now we can add the properties object to the deploymentScripts resource. This object contains the script content and the parameters that the script will use.


properties: {

azPowerShellVersion: '3.0'
scriptContent: '''

$resourceGroupName = 'myResourceGroup'
$networkManagerName = 'myNetworkManager'

$getNetworkManager = Get-AzNetworkManager -ResourceGroupName $resourceGroupName -Name $networkManagerName -ErrorAction Stop
Write-output "Network Manager $networkManagerName exists in resource group." -Level Info

$DeploymentScriptOutputs = @{}
$DeploymentScriptOutputs['Id'] = ($getNetworkManager.id)

'''
retentionInterval: 'P1D'

}
note

Important:

The property that we use in the properties object is azPowerShellVersion. This property is required for the Azure PowerShell script to run successfully. The value must be set to 3.0.

Another important property is retentionInterval. This property specifies how long the logs from the script execution will be retained. The value must be a valid ISO 8601 duration format.

Our full template would look something like:


resource helloFriendDeploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = {
name: 'helloFriendDeploymentScript'
location: resourceGroup().location
kind: 'AzurePowerShell'
identity: {
type: 'UserAssigned'
userAssignedIdentities: {
'/subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourcegroups/deploymenttest/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myscriptingid': {}
}
}
properties: {
azPowerShellVersion: '3.0'
scriptContent: '''

$resourceGroupName = 'myResourceGroup'
$networkManagerName = 'myNetworkManager'

$getNetworkManager = Get-AzNetworkManager -ResourceGroupName $resourceGroupName -Name $networkManagerName -ErrorAction Stop
Write-output "Network Manager $networkManagerName exists in resource group." -Level Info

$DeploymentScriptOutputs = @{}
$DeploymentScriptOutputs['Id'] = ($getNetworkManager.id)

'''
retentionInterval: 'P1D'
}
}

output scriptResult string = myFirstDeploymentScript.properties.outputs.Id

As you can see, the scriptContent property contains the PowerShell script that we want to run. The script is simple: it gets a network manager by name and resource group, then writes a message to the logs. The script also creates an output variable that we can use in our Bicep template.

Next post, we will cover how to access a private virtual network from a deployment script. Stay tuned!