Creating and Deploying Azure Function App for Dynamic Backend
Todd Bernson, CTO, guides readers through deploying a dynamic backend using an Azure Function App for a serverless web app. This post details setting up the Function App with Terraform, configuring HTTP triggers, and deploying Node.js code, allowing seamless integration of dynamic content alongside static assets on Azure CDN.

Todd Bernson
2024-10-30

A serverless architecture is only complete with a dynamic backend capable of handling API requests and generating responses on demand. In this article, I’ll walk through setting up an Azure Function App using Terraform to handle dynamic requests, deploy Node.js code, and configure an HTTP trigger. This function app will be a fundamental part of my serverless web app, allowing us to serve dynamic content alongside the static assets served by Azure CDN.
Step 1: Configuring the Azure Function App with Terraform
The Azure Function App is built on top of a Linux-based service plan, configured with Node.js, and deployed in a way that allows it to serve requests over HTTPS. Let's go over the essential Terraform code for creating the Function App.
Terraform Code - Function App Configuration
This Terraform setup includes creating a function app, configuring a system-assigned identity, and setting up CORS to restrict access to specific origins. Here, I also define a storage account that will host the function code.
data "archive_file" "function_code" {
type = "zip"
output_path = "${path.module}/${local.function_code_directory}/${local.function_zip_file}"
source_dir = "${path.module}/${local.function_code_directory}/"
excludes = ["*.zip"]
}
locals {
app_function_os_type = title(var.function_app_os_type)
function_code_directory = "function-code"
function_zip_file = "function_code.zip"
}
resource "azurerm_linux_function_app" "this" {
name = "${local.project}-functions"
resource_group_name = azurerm_resource_group.this.name
location = azurerm_resource_group.this.location
storage_account_name = azurerm_storage_account.this.name
storage_account_access_key = azurerm_storage_account.this.primary_access_key
service_plan_id = azurerm_service_plan.this.id
identity {
type = "SystemAssigned"
}
site_config {
application_stack {
node_version = "20"
}
cors {
allowed_origins = [
"https://${local.site_domain}"
]
}
}
app_settings = {
"WEBSITE_RUN_FROM_PACKAGE" = "${azurerm_storage_account.this.primary_blob_endpoint}${local.function_code_directory}/${local.function_zip_file}"
}
}
This code configures a Linux-based function app with Node.js version 20 and restricts CORS to requests originating from the specified domain.
Screenshot Placeholder: Azure portal view showing the Function App setup, identity, and CORS settings.
Step 2: Creating the Service Plan and Role Assignment
I need a service plan to run my function app, and the function app requires access to the storage account where the function code will be hosted. The following Terraform code provisions these resources.
Terraform Code - Service Plan and Role Assignment
resource "azurerm_service_plan" "this" {
name = "${local.project}-service-plan"
location = azurerm_resource_group.this.location
resource_group_name = azurerm_resource_group.this.name
os_type = local.app_function_os_type
sku_name = "B1"
}
resource "azurerm_role_assignment" "function_storage_access" {
scope = azurerm_storage_account.this.id
role_definition_name = "Storage Blob Data Reader"
principal_id = azurerm_linux_function_app.this.identity[0].principal_id
}
Screenshot Placeholder: Azure portal view of the service plan and role assignment configuration.
Step 3: Preparing and Uploading Function Code
My function code will be a simple Node.js app that returns a random fun fact. I archive the code and upload it to a storage blob for deployment.
Node.js Function Code - App.js
The following Node.js function, App.js, generates a random fun fact and sends it as a response.
module.exports = async function (context, req) {
const facts = [
"Bananas are berries, but strawberries aren't.",
"A group of flamingos is called a 'flamboyance'.",
"Octopuses have three hearts.",
"Honey never spoils.",
"A cow-bison hybrid is called a beefalo."
];
const randomFact = facts[Math.floor(Math.random() * facts.length)];
context.res = {
body: randomFact
};
};
Terraform Code - Uploading Function Code as a Blob
This code zips the function code and uploads it as a blob, setting it as the deployment package for the Function App.
resource "azurerm_storage_blob" "function_code" {
name = local.function_zip_file
content_md5 = data.archive_file.function_code.output_md5
source = data.archive_file.function_code.output_path
storage_account_name = azurerm_storage_account.this.name
storage_container_name = azurerm_storage_container.function_code.name
type = "Block"
}
Screenshot Placeholder: Deployment view showing the uploaded function code blob in Azure Storage.
Step 4: Setting Up an HTTP Trigger
My function app uses an HTTP trigger to process requests and return responses. Once deployed, the function can be called via a simple HTTPS request.
Screenshot Placeholder: Azure Function App with HTTP trigger configured in the Azure portal.
With my Azure Function App in place, I now have a serverless backend capable of handling dynamic requests. This function app, combined with the CDN-hosted static assets, provides a seamless experience for users and demonstrates the power of serverless architectures.
Stay tuned for more in this series as I continue to dive into best practices, deployment techniques, and optimizations for building robust serverless applications on Azure.
Read More
View all posts
AI/ML
Why Enterprise AI Must Be Application-Led, Not Agent-Led
A deep dive by Todd Bernson, CTO and Chief AI Officer, on why enterprise AI systems should be architected as application-led, deterministic platforms with embedded agentic AI—not fully autonomous agents. This article explains how API-first, governed, multi-channel architectures deliver higher reliability, compliance, scalability, and business value in real-world Fortune-500 environments.

Todd Bernson
2025-12-02

AI/ML
Application-First Agentic AI
Application-first agentic AI is emerging as the only reliable path to real enterprise ROI. In this in-depth analysis, Todd Bernson, CTO & CAIO, breaks down why most generative AI initiatives stall in production—and how disciplined enterprise architecture, deterministic workflows, and narrowly scoped AI agents can finally unlock repeatable business value. Using a real sprint-intelligence system as a case study, the article shows how organizations can combine serverless engineering, structured orchestration, and constrained LLM reasoning to reduce reporting effort, increase trust, eliminate hallucinations, and deliver actionable insights across engineering, operations, compliance, and customer experience.

Todd Bernson
2025-11-28
AI/ML
Why 95% of AI Projects Fail and How to Be Among the 5% That Succeed

Lee Hylton
2025-08-22