Deploy Azure Function for HTTP trigger
    • Dark
      Light
    • PDF

    Deploy Azure Function for HTTP trigger

    • Dark
      Light
    • PDF

    Article Summary

    #ServerlessTips - Azure Bicep
    Author: Dave Rendon Microsoft MVP

    This article aims to help you deploy Azure Functions in your environment using Infrastructure-as-Code with Azure Bicep.

    Azure Bicep is a domain-specific language (DSL) that uses a declarative syntax to deploy Azure resources.

    The Bicep is an abstraction on top of Azure Resource Manager (ARM) templates to define Azure resources using declarative Infrastructure as Code

    About the Azure Function HTTP trigger

    The HTTP trigger lets you invoke a function with an HTTP request. You can use an HTTP trigger to build serverless APIs and respond to webhooks.

    The default return value for an HTTP-triggered function is:

    • HTTP 204 No Content with an empty body in Functions 2.x and higher
    • HTTP 200 OK with an empty body in Functions 1.x

    Prerequisites

    • An Active Azure account: You can create an account for free.
    Azure Bicep is installed on your local machine.
    • Azure PowerShell. See: Install Azure PowerShell.
    • A resource group in your Azure subscription

    Let's get started!

    1. Solution Overview

    We will author a Bicep template that creates an Azure Function HTTP trigger
    The solution will include the following files:

    • 📄 main.bicep: This is the Bicep template
    • 📄 azuredeploy.parameters.json: This parameter file contains the values to use for deploying your Bicep template.
    .zip file: This zip file contains the actual Azure Function code.

    2. Create an Azure resource group

    First, let's create a new Azure resource group by using the command below:

    Az group create --name azinsider_demo - -location eastus
    Picture130

    3. Azure Bicep Template — parameters

    Create a new file in your working directory and name it main. Bicep . We will define the following parameters:

    @description('The name of the Azure Function app.')
    param functionAppName string = 'func-${uniqueString(resourceGroup().id)}'
    
    @description('Storage Account type')
    @allowed([
      'Standard_LRS'
      'Standard_GRS'
      'Standard_RAGRS'
    ])
    param storageAccountType string = 'Standard_LRS'
    
    @description('Location for all resources.')
    param location string = resourceGroup().location
    
    @description('Location for Application Insights')
    param appInsightsLocation string = resourceGroup().location
    
    @description('The language worker runtime to load in the function app.')
    @allowed([
      'dotnet'
      'node'
      'python'
      'java'
    ])
    param functionWorkerRuntime string = 'node'
    
    @description('Specifies the OS used for the Azure Function hosting plan.')
    @allowed([
      'Windows'
      'Linux'
    ])
    param functionPlanOS string = 'Windows'
    
    @description('Specifies the Azure Function hosting plan SKU.')
    @allowed([
      'S1'
      'S2'
      'S3'
    ])
    param functionAppPlanSku string = 'S1'
    
    @description('The zip content url.')
    param packageUri string
    
    @description('Only required for Linux app to represent runtime stack in the format of \'runtime|runtimeVersion\'. For example: \'python|3.9\'')
    param linuxFxVersion string = ''
    
    

    4. Azure Bicep Template — variables

    We will define the following variables:

    var hostingPlanName = functionAppName
    var applicationInsightsName = functionAppName
    var storageAccountName = '${uniqueString(resourceGroup().id)}azfunctions'
    var isReserved = ((functionPlanOS == 'Linux') ? true : false)
    
    

    5. Azure Bicep Template — resources

    We will define the following resources:

    resource storageAccount 'Microsoft.Storage/storageAccounts@2021-02-01' = {
      name: storageAccountName
      location: location
      sku: {
        name: storageAccountType
      }
      kind: 'Storage'
    }
    
    resource hostingPlan 'Microsoft.Web/serverfarms@2021-02-01' = {
      name: hostingPlanName
      location: location
      sku: {
        tier: 'Standard'
        name: functionAppPlanSku
        family: 'S'
        capacity: 1
      }
      properties: {
        reserved: isReserved
      }
    }
    
    resource applicationInsights 'microsoft.insights/components@2020-02-02' = {
      name: applicationInsightsName
      location: appInsightsLocation
      tags: {
        'hidden-link:${resourceId('Microsoft.Web/sites', applicationInsightsName)}': 'Resource'
      }
      properties: {
        Application_Type: 'web'
      }
      kind: 'web'
    }
    
    resource functionApp 'Microsoft.Web/sites@2021-02-01' = {
      name: functionAppName
      location: location
      kind: (isReserved ? 'functionapp,linux' : 'functionapp')
      properties: {
        reserved: isReserved
        serverFarmId: hostingPlan.id
        siteConfig: {
          alwaysOn: true
          linuxFxVersion: (isReserved ? linuxFxVersion : json('null'))
          appSettings: [
            {
              name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
              value: reference(applicationInsights.id, '2015-05-01').InstrumentationKey
            }
            {
              name: 'AzureWebJobsStorage'
              value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccountName};EndpointSuffix=${environment().suffixes.storage};AccountKey=${listKeys(storageAccount.id, '2019-06-01').keys[0].value}'
            }
            {
              name: 'FUNCTIONS_EXTENSION_VERSION'
              value: '~4'
            }
            {
              name: 'FUNCTIONS_WORKER_RUNTIME'
              value: functionWorkerRuntime
            }
            {
              name: 'WEBSITE_NODE_DEFAULT_VERSION'
              value: '~14'
            }
            {
              name: 'WEBSITE_RUN_FROM_PACKAGE'
              value: '0'
            }
          ]
        }
      }
    }
    
    resource zipDeploy 'Microsoft.Web/sites/extensions@2021-02-01' = {
      parent: functionApp
      name: 'MSDeploy'
      properties: {
        packageUri: packageUri
      }
    }
    
    

    Note we use an extension to deploy the Azure Function using a .zip file.

    6. Parameters file

    Create a new file named azuredeploy.parameters.json. The code below shows the definition of the parameters file:

    {
        "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
        "contentVersion": "1.0.0.0",
        "parameters": {
            "location": {
                "value": "eastus"
            },
            "functionAppName": {
                "value": "azinsider"
            },
            "packageUri": {
                "value": "https://github.com/daveRendon/azinsider/raw/main/application-workloads/azure-function-http-trigger/azFunction.zip"
            }     
        }
    
    }
    
    

    7. Azure Bicep Template — Deployment

    We will use the command below to deploy our Bicep template:

    $date = Get-Date -Format "MM-dd-yyyy"
    $rand = Get-Random -Maximum 1000
    $deploymentName = "AzInsiderDeployment-"+"$date"+"-"+"$rand"
    
    New-AzResourceGroupDeployment -Name $deploymentName -ResourceGroupName azinsider_demo -TemplateFile .\main.bicep -TemplateParameterFile .\azuredeploy.parameters.json -c
    
    

    The image below shows the preview of the deployment:
    Picture229

    Then we will execute the deployment. The image below shows the deployment output:
    Picture324

    You can find the code of this solution in the following URL; feel free to contribute!

    https://github.com/daveRendon/azinsider/tree/main/application-workloads/azure-function-http-trigger

    Conclusion

    This article reviewed leveraging Infrastructure as Code using Bicep Language to deploy your Azure Function. In this case, we deployed the Azure Function from a zip file.


    Was this article helpful?