Provisioning python function app with Terraform with solutions from common rookie mistakes

Create python function apps with terraform — by Roshada A

A function app is a direct solution to less code and infrastructure with serverless deployment. All these features make it cost efficient. There are no prerequisites to follow through this article except having an azure subscription and terraform installed on your computer.

Deployment of a function in azure requires the following resources to be provisioned as well.

  1. Resource Group
  2. App service plans (sometimes referred as serverfarms)
  3. Storage account
  4. App Insights
  5. And finally, a function app!

First, create a main.tf file and enter below lines in the very beginning.

provider “azurerm” {
features{
}
}

Notice that above line starts with a “tag” that says “provider” as azurerm. This provider represents integration between azure and terraform.

Azure categorizes all resources in logical groups called as resource group. Let’s make sure to provision all resources in the same region to maintain consistency with APIs, primarily to maintain less redundant storage during deployment. Below is how you create a resource group.

resource "azurerm_resource_group" "resource-group" {
name = "my-pythonfa-rg"
location = "westus"
}

Now you have to create a storage account. It manages triggers and contains function execution logs.

resource "azurerm_storage_account" "storage_account" {
name = "pythonfastorage"
resource_group_name = azurerm_resource_group.resource-group.name
location = azurerm_resource_group.resource-group.location
account_tier = "Standard"
account_replication_type = "LRS"
}

Notice that the resource group name and location above contains some tags. The first tag “azurerm_resource_group” refers to the terraform, text followed by “.” i.e. “resource-group” refers to unique identification of resource being referred. That is to say, the second tag (“resource-group”) must be unique for each resource being created of same type. For both resource group name and location of storage account, we are referring the resource group in above snippet.

Additionally, if you refer a resource as we did above, it tells terraform that resource being created has a dependency of resource being referred. In our case, the resource group should be created before storage account. That’s the only way to go in azure. Otherwise, you’ll get some error that says resource group not found. In short, you need to specify all dependencies.

Moving on, create an app insight (provides monitoring and diagnostics for your function app)

resource "azurerm_application_insights" "app-insights" {  
name = "python-fa-app-insights"
resource_group_name = azurerm_resource_group.resource-group.name
location = azurerm_resource_group.resource-group.location
application_type = "web"
}

Create an app service plan (compute resource for function app to run on)

resource "azurerm_app_service_plan" "app-service-plan" {  
name = "python-app-service"
resource_group_name = azurerm_resource_group.resource-group.name
location = azurerm_resource_group.resource-group.location
kind = "linux"
reserved = true
sku {
capacity = 1
tier = "Standard"
size = "S1"
}
is_xenon = false
maximum_elastic_worker_count = 1
}

NOTICE:

  1. App service plan’s (ASP) dependency on resource group.
  2. Kind of ASP is linux as deployment of python function apps in not supported in windows OS.
  3. Heads up, windows and linux app service cannot be in same location under same resource group.

Above all are mandatory configurations for python function apps. The app service is created in Standard tier, you can go up a notch to premium tier depending on compute units required.

And finally, we are good to create function app. Here’s the code.

resource "azurerm_function_app" "func-app" {  
name = "my-python-fucntion"
resource_group_name = azurerm_resource_group.resource-group.name
location = azurerm_resource_group.resource-group.location
app_service_plan_id = azurerm_app_service_plan.app-service-plan.id
storage_account_name = azurerm_storage_account.storage_account.name
storage_account_access_key = azurerm_storage_account.storage_account.primary_access_key
version = "~3"
os_type = "linux"
app_settings = {
APPINSIGHTS_INSTRUMENTATIONKEY = azurerm_application_insights.app-insights.instrumentation_key
APPLICATIONINSIGHTS_CONNECTION_STRING = azurerm_application_insights.app-insights.connection_string
FUNCTIONS_EXTENSION_VERSION = "~3"
FUNCTIONS_WORKER_RUNTIME = "python"
PROPERTY_FILE_PATH = "property"
SCM_DO_BUILD_DURING_DEPLOYMENT = false
WEBSITE_RUN_FROM_PACKAGE= 1
}
}

In the app_settings block, you can specify your custom app settings also.

Notice that our function app has dependency on resource group, storage account (connection string), app insights and ultimately app service plan.

Your final file should look something like this:

#specify provider
provider “azurerm” {
features{
}
}
#create resource group
resource "azurerm_resource_group" "resource-group" {
name = "my-pythonfa-rg"
location = "westus"
}
#create storage account
resource "azurerm_storage_account" "storage_account" {
name = "pythonfastorage"
resource_group_name = azurerm_resource_group.resource-group.name
location = azurerm_resource_group.resource-group.location
account_tier = "Standard"
account_replication_type = "LRS"
}
#create app insight
resource "azurerm_application_insights" "app-insights" {
name = "python-fa-app-insights"
resource_group_name = azurerm_resource_group.resource-group.name
location = azurerm_resource_group.resource-group.location
application_type = "web"
}
#create app service plan - standard tier
resource "azurerm_app_service_plan" "app-service-plan" {
name = "python-app-service"
resource_group_name = azurerm_resource_group.resource-group.name
location = azurerm_resource_group.resource-group.location
kind = "linux"
reserved = true
sku {
capacity = 1
tier = "Standard"
size = "S1"
}
is_xenon = false
maximum_elastic_worker_count = 1
}
#create function app
resource "azurerm_function_app" "func-app" {
name = "my-python-fucntion"
resource_group_name = azurerm_resource_group.resource-group.name
location = azurerm_resource_group.resource-group.location
app_service_plan_id = azurerm_app_service_plan.app-service-plan.id
storage_account_name = azurerm_storage_account.storage_account.name
storage_account_access_key = azurerm_storage_account.storage_account.primary_access_key
version = "~3"
os_type = "linux"
app_settings = {
https_only = true
APPINSIGHTS_INSTRUMENTATIONKEY = azurerm_application_insights.app-insights.instrumentation_key
APPLICATIONINSIGHTS_CONNECTION_STRING = azurerm_application_insights.app-insights.connection_string
FUNCTIONS_EXTENSION_VERSION = "~3"
FUNCTIONS_WORKER_RUNTIME = "python"
PROPERTY_FILE_PATH = "property"
SCM_DO_BUILD_DURING_DEPLOYMENT = false
WEBSITE_RUN_FROM_PACKAGE= 1
}
}

Name above file main.tf. To execute it, run the following set of commands:

terraform init 

Initializes all modules/provider plugins/backend configurations.

terraform plan -out=function_app_plan

Specify a plan name (function_app_plan) that is to be applied in terraform apply command.

terraform validate

Validates configuration syntactically

terraform apply

Adds infrastructure to platform after successful authentication is done.

Hope this article helped you! Thanks for reading :)

--

--

--

DevOps Engineer by day, developer by dawn.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

From CSV to Buxfer: an unexpected journey — Goxfer

5 minutes to secure an API with the Gravitee.io’s stack

Galaxy Shooter 2D — Heat Seeking Lasers #20

The Alphabassador Programme

Cross platform video calling!

Cross Platform Mobile Apps with .NET and Uno

How To Decide If a Company Is Right for You

Flowchart. Title: Deciding if a company is right for you.

Why we refuse fixed bid projects

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Roshada A

Roshada A

DevOps Engineer by day, developer by dawn.

More from Medium

Calling an external API in PowerApps through power Automate

Power BI, Power Apps, Power Automate, Power Virtual Agnets

Received notifications in Slack when a change happen on a GitHub repository or organization account

Which Process ID?

Modernizing SAP: From RICEFW to BEANS — Part 4

Google Web UI