How to Setup Azure Functions with Terraform
Terraform is a powerful Infrastructure as Code (IaC) tool that can used to provision cloud resources in Azure.
In this tutorial, we will cover how to provision the Azure resources we require in order to publish an Node.js Azure Function using both Terraform and Azure Function Core Tools.
This content is available in video form on the Cloud Engineer Skills YouTube channel.
How to Deploy Azure Functions to Azure Resources Provisioned by Terraform
Prerequisites
Before we get started for this tutorial you will need to have Terraform installed on your local machine as well as Azure Function Core Tools.
Creating the Terraform Configuration File
We will use main.tf
as our Terraform configuration file to define what Azure Resources we want to create to enable us to deploy our Azure Functions.
The main.tf
file will be responsible for provisioning the following Azure Resources:
- Azure Resource Group
- Azure Blob Storage Account
- App Service Plan
- Azure Function App
- Application Insights
- Log Analytics Workspace
Here is the main.tf
in full.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "=3.110.0"
}
}
}
provider "azurerm" {
features {
resource_group {
prevent_deletion_if_contains_resources = false
}
}
}
resource "azurerm_resource_group" "rg" {
name = "ces-af-terraform-rg"
location = "West US 2"
tags = {
environment = "dev"
source = "terraform"
owner = "cloudengineerskills"
}
}
resource "azurerm_storage_account" "func_storage" {
name = "cloudengineerskillstfsa"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
account_tier = "Standard"
account_replication_type = "LRS"
tags = {
environment = "dev"
source = "terraform"
owner = "cloudengineerskills"
}
}
resource "azurerm_service_plan" "func_consumption_plan" {
name = "cloudengineerskillstfconsumptionplan"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
os_type = "Linux"
sku_name = "Y1"
tags = {
environment = "dev"
source = "terraform"
owner = "cloudengineerskills"
}
}
resource "azurerm_linux_function_app" "func_app" {
name = "cloudengineerskillstffuncapp"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
storage_account_name = azurerm_storage_account.func_storage.name
storage_account_access_key = azurerm_storage_account.func_storage.primary_access_key
service_plan_id = azurerm_service_plan.func_consumption_plan.id
site_config {
application_stack {
node_version = 20
}
application_insights_connection_string = azurerm_application_insights.insights.connection_string
application_insights_key = azurerm_application_insights.insights.instrumentation_key
}
tags = {
environment = "dev"
source = "terraform"
owner = "cloudengineerskills"
}
}
resource "azurerm_log_analytics_workspace" "logs" {
name = "cloudengineerskillstf-workspace"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
sku = "PerGB2018"
retention_in_days = 30
tags = {
environment = "dev"
source = "terraform"
owner = "cloudengineerskills"
}
}
resource "azurerm_application_insights" "insights" {
name = "cloudengineerskillstf-appinsights"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
workspace_id = azurerm_log_analytics_workspace.logs.id
application_type = "Node.JS"
tags = {
environment = "dev"
source = "terraform"
owner = "cloudengineerskills"
}
}
Copy the file contents into a main.tf
file, then run terraform init
to download the providers required to provision the Azure Resources.
1
terraform init
Next you will need to log in to your Azure account and subscription via the Azure CLI, these credentials will be used by Terraform to provision your resources.
1
az login
Next run terraform apply
and enter Yes
to provision the resources in Azure.
1
terraform apply
Deploying your Azure Functions to Azure
Next we will initialize an Azure Function Project locallly and add an Azure Function inside it using Azure Function Core Tools.
To learn more about this process follow this previous tutorial.
Run the Azure Function Core Tools func init
command to create the Azure Function Project.
1
func init
- Select
node
- Select
javascript
Run the Azure Function Core Tools func new
command to add a HTTP Trigger Node.js Azure Function to the Azure Function Project.
1
func new
- Select
HTTP Trigger
- Provide a
Function name
and hit enter
Update the .funcignore
to also exclude any Terraform files from getting added into the Azure Function App on deployment.
See the .funcignore
below.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
*.js.map
*.ts
.git*
.vscode
local.settings.json
test
getting_started.md
node_modules/@types/
node_modules/azure-functions-core-tools/
node_modules/typescript/
.terraform/
.terraform.lock.hcl
*.tfstate
*.tfstate*
*.tf
*.tfvars
Now you can publish your Azure Function to the Azure Function App with the Azure Function Core Tools func azure functionapp publish
command.
1
func azure functionapp publish cloudengineerskillstffuncapp
Once the deployment has completed, the command should output the Invoke url
for the httpTrigger
Azure function you have just deployed which should be accessible by a web browser.
Clean up resources provisioned by Terraform
One note before you clean up your resources using terraform destroy
, Application Insights will automatically create an Application Insights Smart Detection resource inside your Azure Resource Group which is out of Terraform’s control preventing it from deleting the resource group on a terraform destroy
In the main.tf
file you will see that the feature flag prevent_deletion_if_contains_resources
for the Azure Resource Group has been set to false
, by default this is set to true
.
This flag will ensure that the Resource Group including the Application Insights Smart Detection resource will all be deleted in full on terraform destroy
.
You may now run the terraform destroy
command to remove all of those resources.
1
terraform destroy