In this post, Iβll walk you through a complete, working mini project where we deploy an Azure Linux Function App using Terraform and then deploy a Node.js QR Code Generator function using Azure Functions Core Tools.
This is not just theory β this is exactly what I built, debugged, fixed, and verified end-to-end. Iβll also call out the gotchas I hit (especially in Step 2), so you donβt lose hours troubleshooting the same issues.
Table of Contents
- πΉ What We Are Building
- π§± Step 1: Create Core Azure Infrastructure with Terraform
- βοΈ Step 2: Create the Linux Function App (Most Important Step)
- π¦ Step 3: Prepare the QR Code Generator App
- π Add local.settings.json (Local Only)
- π« Add .funcignore
- π Install Azure Functions Core Tools (Windows)
- π Deploy the Function Code
- π§ͺ Step 4: Test the Function End-to-End
- β What This Demo Proves
- π§ Final Notes
- π― Conclusion
πΉ What We Are Building
- Azure Resource Group
- Azure Storage Account
- Azure App Service Plan (Linux)
- Azure Linux Function App (Node.js 18)
- A Node.js HTTP-triggered Azure Function that:
- Accepts a URL
- Generates a QR code
- Stores the QR image in Azure Blob Storage
- Returns the QR image URL as JSON
π§± Step 1: Create Core Azure Infrastructure with Terraform
In this step, we create the base infrastructure required for Azure Functions.
Resource Group (rg.tf)
resource "azurerm_resource_group" "rg" {
name = "rgminipro767676233"
location = "Central US"
}
Storage Account (sa.tf)
Azure Functions require a storage account for:
- Function state
- Logs
- Triggers
- Blob output (our QR codes)
resource "azurerm_storage_account" "sa" {
name = "saminipro7833430909"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
account_tier = "Standard"
account_replication_type = "LRS"
}
β οΈ Storage account names must be globally unique and lowercase.
App Service Plan (splan.tf)
This defines the compute for the Function App.
resource "azurerm_service_plan" "splan" {
name = "splanminipro8787"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
os_type = "Linux"
sku_name = "B1"
}
Apply Terraform
terraform apply
β Verify in Azure Portal:
- Resource Group created
- Storage Account exists
- App Service Plan is Linux (B1)
βοΈ Step 2: Create the Linux Function App (Most Important Step)
This step required multiple fixes for the app to actually run, so pay close attention.
Linux Function App (linuxfa.tf)
resource "azurerm_linux_function_app" "linuxfa" {
name = "linuxfaminipro8932340"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
storage_account_name = azurerm_storage_account.sa.name
storage_account_access_key = azurerm_storage_account.sa.primary_access_key
service_plan_id = azurerm_service_plan.splan.id
app_settings = {
FUNCTIONS_WORKER_RUNTIME = "node"
# Required by Azure Functions runtime
AzureWebJobsStorage = azurerm_storage_account.sa.primary_connection_string
# Used by our application code
STORAGE_CONNECTION_STRING = azurerm_storage_account.sa.primary_connection_string
# Ensures package-based deployment
WEBSITE_RUN_FROM_PACKAGE = "1"
}
site_config {
application_stack {
node_version = 18
}
}
}
Why Each Setting Matters
- FUNCTIONS_WORKER_RUNTIME
- Tells Azure this is a Node.js function app
- AzureWebJobsStorage
- Mandatory for Azure Functions to start
- STORAGE_CONNECTION_STRING
- Used by our QR code logic to upload images
- WEBSITE_RUN_FROM_PACKAGE
- Ensures consistent zip/package deployment
- node_version = 18
- Must match your app runtime
Apply Terraform Again
terraform apply
β Verify in Azure Portal:
- Function App is Running
- Runtime stack shows Node.js 18
- No startup errors
π¦ Step 3: Prepare the QR Code Generator App
Download the App
Clone or download the QR code generator repository:
git clone https://github.com/rishabkumar7/azure-qr-code
Navigate to the function root directory (where host.json exists).
Run npm install
npm install
This creates the node_modules folder β without this, the function will fail at runtime.
Expected Folder Structure
qrCodeGenerator/
β
βββ GenerateQRCode/
β βββ index.js
β βββ function.json
β
βββ host.json
βββ package.json
βββ package-lock.json
βββ node_modules/
π Add local.settings.json (Local Only)
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "<Storage Account Connection String>",
"FUNCTIONS_WORKER_RUNTIME": "node"
}
}
β This file is NOT deployed to Azure and should never be committed.
π« Add .funcignore
This controls what gets deployed.
.git*
.vscode
local.settings.json
test
getting_started.md
*.js.map
*.ts
node_modules/@types/
node_modules/azure-functions-core-tools/
node_modules/typescript/
β We keep
node_modulesbecause this project depends on native Node packages.
π Install Azure Functions Core Tools (Windows)
winget install Microsoft.Azure.FunctionsCoreTools
Restart PowerShell and verify:
func -v
π Deploy the Function Code
Navigate to the directory where host.json exists:
cd path/to/qrCodeGenerator
Publish the function:
func azure functionapp publish linuxfaminipro8932340 --javascript --force
Successful Output Looks Like This
Upload completed successfully.
Deployment completed successfully.
Functions in linuxfaminipro8932340:
GenerateQRCode - [httpTrigger]
Invoke url: https://linuxfaminipro8932340.azurewebsites.net/api/generateqrcode
π§ͺ Step 4: Test the Function End-to-End
Invoke the Function
https://linuxfaminipro8932340.azurewebsites.net/api/generateqrcode?url=https://example.com
Sample Response
{
"qr_code_url": "https://saminipro7833430909.blob.core.windows.net/qr-codes/example.com.png"
}
Download the QR Code
Open the returned Blob URL in your browser:
https://saminipro7833430909.blob.core.windows.net/qr-codes/example.com.png
π Youβll see the QR code image stored in Azure Blob Storage.
β What This Demo Proves
- Terraform successfully provisions Azure Functions infrastructure
- App settings are critical for runtime stability
- Azure Functions Core Tools deploy code from the current directory
- Missing
npm installcauses runtime failures - Blob Storage integration works end-to-end
- Azure Functions can be tested via simple HTTP requests
π§ Final Notes
- Warnings about extension bundle versions were intentionally ignored
- This demo focuses on learning Terraform + Azure Functions, not production hardening
- In real projects, code deployment is usually handled via CI/CD pipelines
π― Conclusion
This mini project demonstrates how Infrastructure as Code (Terraform) and Serverless (Azure Functions) work together in a practical, real-world scenario.
If you can build and debug this, youβre well on your way to mastering Azure + Terraform.
Happy learning π

Leave a Reply