Azure Bicep: Using conditional deployments for web applications

7 mins read

Learn how to leverage Bicep’s conditional deployments to provision a Linux or Windows web app based on the parameters passed on during deployment time.

Conditional Deployment in Bicep Language

The objective of this article is to show you how to leverage ‘conditional deployments’ in Bicep.

Think of a scenario where you can deploy two platform types: Windows-based and Linux-based. We can provision a Windows-based or Linux-based web app during deployment time, depending on the platform we choose.

This means we can pass on a parameter value that defines the platform type at deployment time.

In the following Bicep file, we will leverage conditional deployments to provision a Linux-based or Windows-based web application based on the parameters passed on during deployment time.

Let’s analyze the structure of our Bicep file.

1. Bicep file — parameters

We will define the parameters below:

platformwebAppNamelocationskurepoUrlhelloWorld

The code below shows the definition of the parameters:

@allowed([
‘Win’
‘Linux’
])
@description(‘Select the OS type to deploy.’)
param platform string@minLength(2)
@description(‘Web app name.’)
param webAppName string = ‘webApp-${uniqueString(resourceGroup().id)}’@description(‘Location for all resources.’)
param location string = resourceGroup().location@description(‘The SKU of App Service Plan.’)
param sku string = ‘F1’@description(‘Optional Git Repo URL’)
param repoUrl string = ‘ ‘@description(‘true = deploy a sample Hello World app.’)
param helloWorld bool

Now let’s look at the variables that will be used.

2. Bicep file — variables

We will define the following variables:

languagelinuxOfferwindowsOfferappServicePlanPortalNamegitRepoReferencegitRepoUrlconfigReferenceWindowsconfigReferenceLinux

The section below highlights the definition of the variables:

var language = ‘.net’
var configReferenceLinux = {
node: {
appSettings: [
{
name: ‘WEBSITE_NODE_DEFAULT_VERSION’
value: ‘12.15.0’
}
]
}
}
var linuxOffer = ‘linux’
var windowsOffer = ‘windows’
var appServicePlanPortalName_var = ‘AppServicePlan-${webAppName}’
var gitRepoReference = {
‘.net’: ‘https://github.com/Azure-Samples/app-service-web-dotnet-get-started’
node: ‘https://github.com/Azure-Samples/nodejs-docs-hello-world’
php: ‘https://github.com/Azure-Samples/php-docs-hello-world’
html: ‘https://github.com/Azure-Samples/html-docs-hello-world’
}
var gitRepoUrl = (bool(helloWorld) ? gitRepoReference[toLower(language)] : repoUrl)
var configReferenceWindows = {
‘.net’: {
comments: ‘.Net app. No additional configuration needed.’
}
html: {
comments: ‘HTML app. No additional configuration needed.’
}
php: {
phpVersion: ‘7.4’
}
node: {
appSettings: [
{
name: ‘WEBSITE_NODE_DEFAULT_VERSION’
value: ‘12.15.0’
}
]
}
}

Lastly, we will define the resources.

3. Bicep file — resources

We will include the following resources:

App Service PlanApp serviceSource Controls

The code below shows the definition of the resources: the App Service Plan, the App Service, and the Source Control:

resource appServicePlanPortalName ‘Microsoft.Web/serverfarms@2020-06-01’ = {
name: appServicePlanPortalName_var
location: location
sku: {
name: sku
}
kind: ((platform == ‘Linux’) ? linuxOffer : windowsOffer)
}resource webAppName_resource ‘Microsoft.Web/sites@2020-06-01’ = {
name: webAppName
location: location
properties: {
serverFarmId: appServicePlanPortalName.id
siteConfig: ((platform == ‘Linux’) ? configReferenceLinux : configReferenceWindows)
}
}resource webAppName_web ‘Microsoft.Web/sites/sourcecontrols@2020-06-01’ = if (contains(gitRepoUrl, ‘http’)) {
parent: webAppName_resource
name: ‘web’
properties: {
repoUrl: gitRepoUrl
branch: ‘master’
isManualIntegration: true
}
}

Note we use the conditional expression ?: operator to make sure the function is only evaluated for conditions when the resource is deployed.

The code below shows the complete Bicep file.

@allowed([
‘Win’
‘Linux’
])
@description(‘Select the OS type to deploy.’)
param platform string@minLength(2)
@description(‘Web app name.’)
param webAppName string = ‘webApp-${uniqueString(resourceGroup().id)}’@description(‘Location for all resources.’)
param location string = resourceGroup().location@description(‘The SKU of App Service Plan.’)
param sku string = ‘F1’@description(‘Optional Git Repo URL’)
param repoUrl string = ‘ ‘@description(‘true = deploy a sample Hello World app.’)
param helloWorld boolvar language = ‘.net’
var configReferenceLinux = {
node: {
appSettings: [
{
name: ‘WEBSITE_NODE_DEFAULT_VERSION’
value: ‘12.15.0’
}
]
}
}
var linuxOffer = ‘linux’
var windowsOffer = ‘windows’
var appServicePlanPortalName_var = ‘AppServicePlan-${webAppName}’
var gitRepoReference = {
‘.net’: ‘https://github.com/Azure-Samples/app-service-web-dotnet-get-started’
node: ‘https://github.com/Azure-Samples/nodejs-docs-hello-world’
php: ‘https://github.com/Azure-Samples/php-docs-hello-world’
html: ‘https://github.com/Azure-Samples/html-docs-hello-world’
}
var gitRepoUrl = (bool(helloWorld) ? gitRepoReference[toLower(language)] : repoUrl)
var configReferenceWindows = {
‘.net’: {
comments: ‘.Net app. No additional configuration needed.’
}
html: {
comments: ‘HTML app. No additional configuration needed.’
}
php: {
phpVersion: ‘7.4’
}
node: {
appSettings: [
{
name: ‘WEBSITE_NODE_DEFAULT_VERSION’
value: ‘12.15.0’
}
]
}
}resource appServicePlanPortalName ‘Microsoft.Web/serverfarms@2020-06-01’ = {
name: appServicePlanPortalName_var
location: location
sku: {
name: sku
}
kind: ((platform == ‘Linux’) ? linuxOffer : windowsOffer)
}resource webAppName_resource ‘Microsoft.Web/sites@2020-06-01’ = {
name: webAppName
location: location
properties: {
serverFarmId: appServicePlanPortalName.id
siteConfig: ((platform == ‘Linux’) ? configReferenceLinux : configReferenceWindows)
}
}resource webAppName_web ‘Microsoft.Web/sites/sourcecontrols@2020-06-01’ = if (contains(gitRepoUrl, ‘http’)) {
parent: webAppName_resource
name: ‘web’
properties: {
repoUrl: gitRepoUrl
branch: ‘master’
isManualIntegration: true
}
}

Now, we will define a parameters file to include the actual values, and in this file, we will define the preferred platform, Windows or Linux. Based on the parameter values, a different set of resources will be provisioned.

4. Parameters file

The code below shows the definition of the parameter file.

{
“$schema”: “https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#“,
“contentVersion”: “1.0.0.0”,
“parameters”: {
“platform”: {
“value”: “Win”
},
“repoUrl”: {
“value”: “https://github.com/Azure-Samples/app-service-web-dotnet-get-started
},
“helloWorld”: {
“value”: true
}
}
}

Note that we chose the Windows environment and pass on the ‘repoURL’ and the bool to evaluate true. This will provision an App Service Plan Windows-based, an App Service, and it will include a template from a specific repository.

5. Deploy the Bicep file.

To deploy our Bicep file, we will use the command below:

$date = Get-Date -Format “MM-dd-yyyy”
$deploymentName = “AzInsiderDeployment”+”$date”$deploymentName = “AzInsiderDeployment”+”$date”New-AzResourceGroupDeployment -Name $deploymentName -ResourceGroupName AzInsiderBicep -TemplateFile .conditional-deployment.bicep -TemplateParameterFile .azuredeploy.parameters.json

The image below shows the output from this deployment.

Azure Bicep conditional deployment output

You can refer to the URL of the App Service and validate that the application is running:

Azure Bicep App Service deployment

Next Steps

I recommend you check how to build flexible Bicep templates by using conditions and loops:

Build flexible Bicep templates by using conditions and loops – Learn

Join the AzInsider email list here.

-Dave R.

💪 Azure Bicep: Using conditional deployments for web applications was originally published in CodeX on Medium, where people are continuing the conversation by highlighting and responding to this story.

Leave a Reply

Your email address will not be published.

Follow Us