Skip to content

Deploying Logic App Standard with Bicep: A Simple Step-by-Step Guide

deploy logic app bicep verified modules

Azure Verified Modules (AVM) for Bicep is an initiative aimed at consolidating and setting standards for what a good Infrastructure-as-Code (IaC) module should look like. Modules that align with these standards are classified as AVMs and are available from their respective language-specific registries. Supported by Microsoft, AVM is intended to standardise and accelerate the deployment of Azure resources with Bicep and architectural patterns.

In this blog post, we will explore how to deploy a Logic App Standard using Azure Bicep Verified Modules.

How to Use Azure Bicep Verified Modules

The entire project open source is hosted on GitHub: https://github.com/Azure/bicep-registry-modules

There is also an official website available here: Azure Verified Modules for Bicep. However, their GitHub repository is essentially the most interesting part.

The Azure Bicep Verified Modules are hosted in a public repository, so you can easily use them across multiple projects. The modules are also versioned, so remember to upgrade them from time to time, especially if you want to use newer features.

Using them is straightforward. I use:

  • Visual Studio Code
  • Bicep extension
  • Bicep Registry extension

Open a new .bicep file and start typing. IntelliSense will provide suggestions for public modules right out of the box. Below is an example where I typed “sto” and the IDE comes up with suggestions and a link to the documentation.

bicep azure verified modules visual studio

Deploy Logic App Standard Using Azure Bicep Verified Modules

The setup we’ll create is a fairly complete environment for a Logic App Standard, including Key Vault, Managed Identity, Storage Account, Log Analytics Workspace, and Application Insights.

Below is an architectural overview of the application landscape and release process:

deploy logic app standard bicep verified modules

Step 1: Create a Resource Group

We begin by creating a resource group and setting the target scope to the subscription level.

targetScope = 'subscription'

@description('Optional. The location to deploy resources to.')
param location string = deployment().location

resource appResourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = {
  name: 'rg-avm-bicep'
  location: location
}

Step 2: Create the Hosting Plan (App Service Plan)

Next, we create the hosting plan or server farm:

module serverFarm 'br/public:avm/res/web/serverfarm:0.3.0' = {
  scope: appResourceGroup
  name: 'appfarm-logicapp01-${uniqueString(deployment().name, location)}'
  params: {
    name: 'appfarm-logicapp01'
    kind: 'Elastic'
    maximumElasticWorkerCount: 3
    skuName: 'WS1'
  }
}

Step 3: Create a Managed Identity

We create a new User-Assigned Managed Identity to be used by the Logic App Standard:

module mgmtIdentity 'br/public:avm/res/managed-identity/user-assigned-identity:0.4.0' = {
  scope: appResourceGroup
  name: 'mgmtidentity-${uniqueString(deployment().name, location)}'
  params: {
    name: 'Identity-Logicapp01'
  }
}

Step 4: Create the Storage Account and Key Vault

We create a Storage Account and a Key Vault. We will export the Storage Account connection string directly into the Key Vault as a secret for enhanced security.

Additionally, we’ll assign the Logic App’s Managed Identity access to read secrets from the Key Vault. If you don’t already have access to create Key Vault values by default, make sure to add yourself here, or the pipeline that executes this.

module keyvault 'br/public:avm/res/key-vault/vault:0.11.0' = {
  scope: appResourceGroup
  name: 'kv-${uniqueString(deployment().name, location)}'
  params: {
    name: 'keyvault01'
    sku: 'standard'
    roleAssignments: [
      { principalId: mgmtIdentity.outputs.principalId, roleDefinitionIdOrName: 'Key Vault Secrets User' }
      { principalId: '<your-principal-id>', roleDefinitionIdOrName: 'Key Vault Secrets User' } // Assign yourself access to Key Vault to create secrets (optional)
    ]
  }
}

module storageAccount 'br/public:avm/res/storage/storage-account:0.14.3' = {
  scope: appResourceGroup
  name: 'stologicapp01-${uniqueString(deployment().name, location)}'
  params: {
    name: 'stologicapp01'
    secretsExportConfiguration: { //this exports the connectionstring to a keyvault secret
      keyVaultResourceId: keyvault.outputs.resourceId
      connectionString1: 'stologicapp01-connectionstring'
    }
    networkAcls: {
      defaultAction: 'Allow'
      bypass: 'AzureServices'
    }
    publicNetworkAccess: 'Enabled'
  }
}

Step 5: Create Log Analytics and Application Insights

We proceed to create a Log Analytics Workspace and an Application Insights instance:

module logAnalytics 'br/public:avm/res/operational-insights/workspace:0.9.0' = {
  scope: appResourceGroup
  name: 'log-webshop-${uniqueString(deployment().name, location)}'
  params: {
    name: 'loganaly01'
  }
}

module appInsights 'br/public:avm/res/insights/component:0.4.2' = {
  scope: appResourceGroup
  name: 'appinsights-${uniqueString(deployment().name, location)}'
  params: {
    name: 'appinsights01'
    workspaceResourceId: logAnalytics.outputs.resourceId
  }
}

Step 6: Create the Logic App Standard

Lastly, we create the Logic App:

module logicapp 'br/public:avm/res/web/site:0.11.1' = {
  scope: appResourceGroup
  name: 'las-logicapp01-${uniqueString(deployment().name, location)}'
  params: {
    name: 'las-webshop01'
    kind: 'functionapp,workflowapp'
    serverFarmResourceId: serverFarm.outputs.resourceId
    appInsightResourceId: appInsights.outputs.resourceId
    siteConfig: {
      alwaysOn: true
      netFrameworkVersion: 'v8.0'
    }
    managedIdentities: {
      userAssignedResourceIds: [
        mgmtIdentity.outputs.resourceId
      ]
    }
    keyVaultAccessIdentityResourceId: mgmtIdentity.outputs.resourceId
    appSettingsKeyValuePairs: {
      FUNCTIONS_EXTENSION_VERSION: '~4'
      FUNCTIONS_WORKER_RUNTIME: 'dotnet'
      WEBSITE_CONTENTSHARE: 'las-logicapp01'
      APP_KIND: 'workflowApp'
      WEBSITE_CONTENTAZUREFILECONNECTIONSTRING: '@Microsoft.KeyVault(VaultName=${keyvault.outputs.name};SecretName=stologicapp01-connectionstring)'
    }
  }
}

Bicep Logic App Module

Logic App Consumption has a separate module in Azure Bicep Verified Modules because, in Azure, it is actually a different resource. However, for Logic App Standard, there is no such different resource since it’s defined as a “site” with a specific kind: ‘functionapp,workflowapp’.

Currently, there is no separate module yet for Logic App Standard in Azure Bicep Verified Modules. However, this seems to be on the list of ongoing discussions. See this GitHub proposal: Azure-Verified-Modules Issue #647.

The current module is missing a bit of magic to populate the mandatory settings for Logic App automatically, which is actually present if you use this for Azure Functions.

Conclusion

Deploying a Logic App Standard with Azure Bicep Verified Modules is actually quite straightforward. It’s been a pleasant experience, and the modules are built on standards and best practices. I highly recommend everyone to follow this project and consider upgrading your deployment scripts to use these verified modules.