DEV Community

kemurayama
kemurayama

Posted on

Deploying Azure Functions Python with Terraform

This post will focus on deploying Azure Functions Python with Terraform. If you are new to both services, you can start from Prerequisites.

Prerequisites

Overview

Azure Functions is FaaS (function-as-a-service) on Microsoft Azure. It enables you to create your exciting services faster because it is a serverless service. You only need to focus on your code and don't need to care about OS updates and middleware.

In addition, Azure Functions is event-driven that is triggered by external events:

  • Upload images on Azure Blob Storage (Object Storage service)
  • Insert / Update items on Azure Cosmso DB (NoSQL DB service)
  • HTTP incoming requests
  • Timer defined by cron

However, deploying all services and configuring them from Azure Portal take a long time and happens mistakes.

To increase our productivity and deploy safely, I would like to use IaC (Infrastructure as Code) tools, such as ARM Template or Terraform, rather than deploying each resource from Azure Portal. Especially in production environment, managing your infrastructure as code is really important.

Set Up Environment

  • Terraform >= 0.12
  • azurerm provider >= 2.21
  • azure cli

Define Resources

Let's define resources. In Terraform, you define your resources in .tf files.

main.tf

# https://github.com/terraform-providers/terraform-provider-azurerm/issues/7960
provider "azurerm" {
  version = ">=2.21.0"
  features {}
}

resource "azurerm_resource_group" "funcdeploy" {
  name     = "rg-${var.prefix}-function"
  location = var.location
}

resource "azurerm_storage_account" "funcdeploy" {
  name                     = "${var.prefix}storage"
  resource_group_name      = azurerm_resource_group.funcdeploy.name
  location                 = azurerm_resource_group.funcdeploy.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
}

resource "azurerm_storage_container" "funcdeploy" {
  name                  = "contents"
  storage_account_name  = azurerm_storage_account.funcdeploy.name
  container_access_type = "private"
}

resource "azurerm_application_insights" "funcdeploy" {
  name                = "${var.prefix}-appinsights"
  location            = azurerm_resource_group.funcdeploy.location
  resource_group_name = azurerm_resource_group.funcdeploy.name
  application_type    = "web"

  # https://github.com/terraform-providers/terraform-provider-azurerm/issues/1303
  tags = {
    "hidden-link:${azurerm_resource_group.funcdeploy.id}/providers/Microsoft.Web/sites/${var.prefix}func" = "Resource"
  }

}

resource "azurerm_app_service_plan" "funcdeploy" {
  name                = "${var.prefix}-functions-consumption-asp"
  location            = azurerm_resource_group.funcdeploy.location
  resource_group_name = azurerm_resource_group.funcdeploy.name
  kind                = "FunctionApp"
  reserved            = true

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

resource "azurerm_function_app" "funcdeploy" {
  name                       = "${var.prefix}func"
  location                   = azurerm_resource_group.funcdeploy.location
  resource_group_name        = azurerm_resource_group.funcdeploy.name
  app_service_plan_id        = azurerm_app_service_plan.funcdeploy.id
  storage_account_name       = azurerm_storage_account.funcdeploy.name
  storage_account_access_key = azurerm_storage_account.funcdeploy.primary_access_key
  https_only                 = true
  version                    = "~3"
  os_type                    = "linux"
  app_settings = {
      "WEBSITE_RUN_FROM_PACKAGE" = "1"
      "FUNCTIONS_WORKER_RUNTIME" = "python"
      "APPINSIGHTS_INSTRUMENTATIONKEY" = "${azurerm_application_insights.funcdeploy.instrumentation_key}"
      "APPLICATIONINSIGHTS_CONNECTION_STRING" = "InstrumentationKey=${azurerm_application_insights.funcdeploy.instrumentation_key};IngestionEndpoint=https://japaneast-0.in.applicationinsights.azure.com/"
  }

  site_config {
        linux_fx_version= "Python|3.8"        
        ftps_state = "Disabled"
    }

  # Enable if you need Managed Identity
  # identity {
  #   type = "SystemAssigned"
  # }
}
Enter fullscreen mode Exit fullscreen mode

variables.tf

variable "location" {
    type    =   string
    default =   "japaneast"
}

variable "prefix" {
    type    =   string
    default =   "my"

}
Enter fullscreen mode Exit fullscreen mode

Here are some tips for successful deployment.

  • Use azurerm >= 2.21.0
  • Add Hidden Link Tag
  • Set version = ~3 (default is v1)

Deploy Azure Resources

After you created above files, let's deploy !

If you don't want to install Terraform on your local PC, use Azure Cloud Shell as test.

Make sure your each resource name is unique.

$ terraform init

...
Terraform has been successfully initialized!
...

$ terraform plan 
$ terraform apply

...
Apply complete! Resources: 6 added, 0 changed, 0 destroyed.
Enter fullscreen mode Exit fullscreen mode

terraform apply result

Fig.1 The result of terraform apply

Then you see Azure Functions on your Azure Portal.

Azure Resources after deploying

Fig.2 Resources on Azure Portal

Deploy Function

After terrafrom apply, you may upload your code to your Function with Visual Studio Code.

Once deployed your code to Function App, you can see your functions on Azure Portal.

Azure Function

Fig.3 Functions on Azure Portal

You can manage various resources and control versions in .tf file. In production, you should use CI/CD tools such as GitHub Actions or Azure DevOps.

Reference

Top comments (0)