fbpx

HashiCorp Terraform is great for deploying any Microsoft Azure resource, and the same applies to deploying serverless compute with Azure Function Apps in the Microsoft Azure cloud. Azure Function Apps are a very heavily used compute service in Microsoft Azure, and one that is in high demand for deployment automation by DevOps Engineers and Site Reliability Engineers (SREs). This article will show you the steps and Terraform code necessary for deploying and managing Azure Function Apps using Consumption plan pricing, and will cover both Windows-based and Linux-based hosting options.

Let’s get started!


Prerequisites

Before you start, you’ll need the following in order to deploy and manage Azure Function Apps with Terraform:

  • An Azure Subscription to create resources within.
  • Terraform installed on your machine or where ever your CI/CD DevOps pipelines will be running

Step 1: Create an Azure Resource Group

All Microsoft Azure resources must be placed within an Azure Resource Group. The Resource Group provides a container in your Azure Subscription for organizing related resources together. In this case, when creating the Azure Function App, an Azure Resource Group is needed so we can place all the required resources for the Function App here.

The following snippet is the basic Terraform code for creating an Azure Resource Group:

# Create a resource group
resource "azurerm_resource_group" "primary" {
  name     = "b59_function"
  location = "eastus"
}

Depending on your Azure governance policies, you may create the Azure Resource Group manually or in a different deployment pipeline. This is fine and both are done commonly as needed to meet the team and organizations Azure management and governance policies.

Step 2: Create an Azure Storage Account

Yes, this is the correct step. The next step is to create an Azure Storage Account. The way that Azure Functions are built, each Function App requires an Azure Storage Account to run.

The following snippet is the basic Terraform code for creating an Azure Storage Account:

# Create Azure Storage Account required for Function App
resource azurerm_storage_account "primary" {
  name                     = "
  resource_group_name      = azurerm_resource_group.primary.name
  location                 = azurerm_resource_group.primary.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
}

This snippet is referencing the Azure Resource Group that was configured in the previous snippet, rather than hard coding the resource group name and location.

Step 3: Configure the App Service Plan with Consumption Pricing

Azure Function Apps are a part of the broader PaaS (Platform as a Service) offering in Microsoft Azure called App Service. The base hosting for apps in App Service is an App Service Plan. The plan defines and abstracts away the underling virtual machine infrastructure. For this reason, the App Service Plan is where the initial configuration of using either Windows or Linux hosts.

You’ll need to choose which, since Linux-based Azure Function Apps can only be hosted on Linux-based App Service Plan, and similarly for Windows-based Function Apps and Plans.

Let’s look at the Terraform for creating both Windows and Linux types of App Service Plans using Consumption based pricing!

Configure App Service Plan using a Windows host

When configuring and deploying an App Service Plan in Terraform, the default host used is Windows Server. This makes it easy as you do not have to specify the OS type (via os_type) parameter on the azurerm_app_service_plan resource type.

The following snippet is a basic example of creating an App Service Plan using Consumption pricing, a Windows host, and configured for use by one or more Azure Functions Apps:

# Create Azure App Service Plan using Consumption pricing
resource azurerm_app_service_plan "primary" {
  name                = local.app_service_plan_name
  location            = azurerm_resource_group.primary.location
  resource_group_name = azurerm_resource_group.primary.name
  kind                = "FunctionApp"

  sku {
    tier = "Dynamic"
    size = "Y1"
  }
}

This snippet is referencing the Azure Resource Group that was configured in the previous snippet, rather than hard coding the resource group name and location.

Additionally, this snippet has the following parameters set to configure it accordingly:

  • kind – This is set to FunctionApp to tell Azure that this App Service Plan will be used by Function Apps. This is also what tells Azure to use a Windows Server host underneath with the plan hosting.
  • sku – This is configuring the pricing tier for the App Service Plan. Having tier set to Dynamic and size set to Y1 is what configures the Consumption pricing for the App Service Plan.

Configure App Service Plan using a Linux host

When configuring an App Service Plan in Terraform, the plan can also be configured to use a Linux host instead. To do this, you must configure the kind property of the azurerm_app_service_plan resource type to the value of linux. This tells Azure to host the App Service Plan with Linux virtual machines underneath.

The following snippet is almost identical to the previous snippet, except this snippet is set to use a Linux host underneath for the plan:

# Create Azure App Service Plan using Consumption pricing
resource azurerm_app_service_plan "primary" {
  name                = local.app_service_plan_name
  location            = azurerm_resource_group.primary.location
  resource_group_name = azurerm_resource_group.primary.name
  kind                = "Linux"
  reserved            = true

  sku {
    tier = "Dynamic"
    size = "Y1"
  }
}

This snippet is referencing the Azure Resource Group that was configured in the previous snippet, rather than hard coding the resource group name and location.

Additionally, this snippet has the following parameters set to configure it accordingly:

  • kind – This is set to Linux to configure the App Service Plan to use a Linux host.
  • reserved – This is set to true as is required when configuring the plan to use a Linux host.

When setting kind = "Linux" the reserved property must always be set to true. These two configurations are required to go together when using a Linux host on the App Service Plan.

Step 4: Configure the Azure Function App

Now that all the prerequisite requirements for an Azure Function App have been configured in the HashiCorp Terraform code, the Azure Function App can now be configured. Similarly, to the Azure App Service Plan, the Function App also must be defined to use either a Windows or Linux host. This will configure the Function App with the necessary settings to tell Azure which Azure Functions Runtime will be needed when deploying the app to the host.

Remember, Linux-based Function Apps require a Linux-based App Service Plan, and the same goes for Windows-based Function Apps.

Let’s take a look at configuring an Azure Function App using Terraform!

Configure Azure Function App hosted in Windows

By default, the Azure Function App will be assumed to be using the Windows-based App Service Plan host. So, as a result. there is no need to specify the host on the azurerm_function_app resource type configuration in the Terraform code.

The following snippet is a basic example of configuring an Azure Function App that will be hosted using a “default” Azure App Service Plan:

# Create an Azure Function App
resource azurerm_function_app "primary" {
  name                       = "b59-func-app"
  resource_group_name        = azurerm_resource_group.primary.name
  location                   = azurerm_resource_group.primary.location

  app_service_plan_id        = azurerm_app_service_plan.primary.id
  
  storage_account_name       = azurerm_storage_account.primary.name
  storage_account_access_key = azurerm_storage_account.primary.primary_access_key
  
  version                    = "~3"
  
  site_config {
    always_on = true
  }
}

This snippet is referencing the Azure Resource Group that was configured in the previous snippet, rather than hard coding the resource group name and location.

Additionally, this snippet has the following parameters set to configure it accordingly:

  • app_service_plan_id – This configures the id of the azurerm_app_service_plan resource that will host the Function App.
  • storage_account_name – This configures the name of the Azure Storage Account that the Function App requires to run.
  • storage_account_access_key – This configures the access key for the Azure Storage Account that the Function App requires to run.
  • version – This configures the Function App Runtime version that will be used to host the Function App.
  • site_config – This is a configuration block where you will put any additional, supported configuration options for the Azure Function App. This snippet doesn’t include much as that is outside the scope of this article.

Configure Azure Function App hosted on Linux

When configuring the azurerm_function_app resource type for deploying Azure Function Apps using a Linux-based App Service Plan, you must also configure the Function App for Linux too. The Function App and App Service Plan must both match the configuration of using a Linux host, and only Linux-based App Service Plans are able to host Linux-based Function Apps.

The following snippet is a basic example of configuring an Azure Function App that will be hosted using a “default” Azure App Service Plan:

# Create an Azure Function App on Linux
resource azurerm_function_app "primary" {
  name                       = local.function_app_name
  resource_group_name        = azurerm_resource_group.primary.name
  location                   = azurerm_resource_group.primary.location

  app_service_plan_id        = azurerm_app_service_plan.primary.id
  
  storage_account_name       = azurerm_storage_account.primary.name
  storage_account_access_key = azurerm_storage_account.primary.primary_access_key
  
  os_type                    = "linux"
  version                    = "~3"

  site_config {
    always_on = true
  }
}

This snippet is referencing the Azure Resource Group that was configured in the previous snippet, rather than hard coding the resource group name and location.

Additionally, this snippet has the following parameters set to configure it accordingly:

  • app_service_plan_id – This configures the id of the azurerm_app_service_plan resource that will host the Function App.
  • storage_account_name – This configures the name of the Azure Storage Account that the Function App requires to run.
  • storage_account_access_key – This configures the access key for the Azure Storage Account that the Function App requires to run.
  • os_type – This is set to the value of linux which configures the Azure Function App that is requires a Linux host. Remember that the App Service Plan will need to be a Linux-based App Service Plan when setting this value.
  • version – This configures the Function App Runtime version that will be used to host the Function App.
  • site_config – This is a configuration block where you will put any additional, supported configuration options for the Azure Function App. This snippet doesn’t include much as that is outside the scope of this article.

Conclusion

In this article, you learned about what Azure resources are required in order to deploy an Azure Function App, and how to deploy both Windows-based and Linux-based Azure Function Apps. Make sure when configuring Azure Function App deployment in Terraform that both the Function App and App Service Plan must be configured for the same host (either Windows or Linux) for your deployments to succeed. Hopefully this helps clarify what Terraform resource types and code is necessary to deploy and manage Azure Function Apps using Consumption plan pricing.

Microsoft MVP

Chris Pietschmann is a Microsoft MVP, HashiCorp Ambassador, and Microsoft Certified Trainer (MCT) with 20+ years of experience designing and building Cloud & Enterprise systems. He has worked with companies of all sizes from startups to large enterprises. He has a passion for technology and sharing what he learns with others to help enable them to learn faster and be more productive.
HashiCorp Ambassador Microsoft Certified Trainer (MCT) Microsoft Certified: Azure Solutions Architect