Build Your First Azure Function
Create a serverless streaming backend that scales automatically with Azure Functions.
Introduction
This project has been archived
We're no longer updating this project - we recommend checking out our active projects instead!
If you've already completed this project, don't worry! Your documentation is still available for you to check out and share.
If you have any questions, leave a question in our Discord and we'll get back to you ASAP!
⚡️ 30 second Summary
Twitch processes over 30 million chat messages every day. Discord handles billions. When a popular streamer goes live, and thousands of viewers start chatting at once, the backend needs to handle that traffic without breaking.
How do they do it? These platforms use serverless architecture - code that runs only when needed and scales automatically. No servers to manage, no capacity planning, no 3am calls when traffic spikes.
You'll build the same foundation using Azure Functions. By the end of this project, you'll have a streaming backend that receives messages, stores them, and retrieves them on demand - the core of any real-time chat application.
What you'll build
In this project, you'll create a serverless streaming backend using Azure Functions and Cosmos DB.
By the end of this project, you'll have:
- 💼 A Resource Group for organizing all your Azure resources.
- 👷 An Azure Function app running serverless Python code.
- 📭 A POST endpoint for saving incoming messages in your app.
- A GET endpoint for retrieving messages from storage and displaying them to the user.
- 💎 Secret Mission: Cosmos DB integration for persistent message storage.
Want a complete demo of how to do this project, from start to finish? Check out our 🎬 walkthrough with Kahu
Not sure if this project is right for you? Check if it matches your goals
If you're up for a bit of a challenge, quiz yourself on the key concepts up ahead in this project.
This project is part of a series:
- Part 1: You are here!
- Part 2: Build AI Chat Moderator with Gemini
- Part 3: Orchestrating Parallel Event Streams with Azure
- Part 4: GitHub to Azure DevOps Pipeline
Set Up Your Azure Environment
First things first - we need to get your Azure environment ready for building serverless apps.
In this step you'll create a resource group to organize your cloud resources and install the tools needed to develop Azure Functions locally.
In this step, get ready to:
- Create an Azure account (if you don't have one)
- Create a Resource Group for your streaming backend
- Install Azure Functions Core Tools
Create an Azure Account
First, let's make sure you have an Azure account set up.
✔️ I already have an Azure account
Fantastic! If you already have an Azure account, you can get started even faster.
- Make sure you can log in to the Azure Portal with your existing account.
ⓧ I need to create an Azure account
No problem at all. Let's get you set up with a free Azure account.
- Go to azure.microsoft.com/free.
- Click Start free.
- Sign in with your Microsoft account (or create one).
- Complete the sign-up process (you'll need a phone number and credit card for verification).
Does this cost?
Nope! Azure gives you $200 in free credits for 30 days, plus 12 months of free services.
- Once you can access the Azure Portal, you'll see the dashboard.
Alright! Now that we have an Azure account, let's make something in it.
Create a Resource Group
Resource Groups are containers that hold related Azure resources. Everything for your streaming backend will go in one group.
- Make sure you are logged in and can see the Azure Portal.
- Click Create a resource in the top left.
- Search for Resource group and select it.
- Click Create > Resource group.
Fill in the details:
- Subscription: Select your subscription.
- Resource group: Name it something catchy and informative, like streaming-backend-rg.
- Region: Select a region close to you (e.g., East US, West Europe).
- Click Review + create.
- Click Create.
Very nice - we've successfully created an Azure resource group. Only problem...it's empty! Let's change that.
Install Azure Functions Core Tools
Why do we need Azure Functions Core Tools?
We know that to build this serverless app, we're going to create some Azure Functions (it's literally in the title of the project).
To create Azure Functions, we need some specialist equipment. Azure Functions Core Tools let you develop and test functions locally before deploying to Azure. Absolutely essential piece of kit.
First, check if you already have Azure Functions Core Tools installed.
🍎 macOS
- Press Cmd+Space and type Terminal
🪟 Windows
- Press Win key and type PowerShell
- Run the following command:
func --version
- What do you see?
✔️ I see a version number
Great! You already have Azure Functions Core Tools installed.
- Make sure you have version 4.x or higher.
- If you have an older version, you can update it using the 'Command not found' installation instructions in the other tab.
ⓧ Command not found
Not to worry - let's get Azure Functions Core Tools installed.
🍎 macOS
- Jump back into your Terminal.
- Run the following commands:
brew tap azure/functions
brew install azure-functions-core-tools@4
- Verify the installation:
func --version
You should see a version number like 4.x.x.
🪟 Windows
- Jump back into PowerShell.
- Make sure you have Node.js installed (download from nodejs.org if needed).
- Run the following command:
npm install -g azure-functions-core-tools@4 --unsafe-perm true
- Verify the installation:
func --version
Epic. Azure Functions Core Tools are ready for use.
Install the Azure CLI
Let's recap; Azure account created. Resource Groups created. Core tools installed.
What more could we possibly want to install?! Turns out we're still missing one critical piece. We can't access any of these tools without the Azure CLI.
- First things first - let's check if you already have Azure CLI installed.
- In your terminal, run the following command
az --version
- What do you see?
✔️ I see version info
Too easy! You already have the Azure CLI installed.
ⓧ Command not found
Let's install the Azure CLI for your operating system.
🍎 macOS
- Open Terminal.
- Run the following command:
brew install azure-cli
- Verify the installation:
az --version
🪟 Windows
- Download the MSI installer from aka.ms/installazurecliwindows.
- Run the installer and follow the prompts.
- Restart your terminal after installation.
- Verify the installation:
az --version
- Fantastic. We're all setup with our Azure CLI.
Onto the final setup piece...
Log in to Azure
The last piece of your setup is to connect the CLI to your Azure account.
- Run the following command:
az login
- Look for a browser window to open.
- Sign in with your Azure account.
- What do you see?
✔️ Login succeeded
- If your login succeeded, you'll see a JSON response with your subscription details.
- You're ready to continue!
ⓧ I got an error
Nothing working? No problem.
Do any of these look familiar?
- Browser didn't open: Run az login --use-device-code and enter the code at microsoft.com/devicelogin.
- No subscriptions found: Make sure you completed Azure signup and are using the correct Microsoft account.
- Still stuck? Ask for help! or check out the NextWork Community.
Nice work getting your Azure environment set up! Now let's build your first function.
Build Your First Azure Function
Time to write some code! You'll create your first Azure Function - an HTTP endpoint that receives messages just like Twitch or Discord would. This is the foundation of your streaming backend.
In this step, get ready to:
- Create a new Azure Functions project
- Write an HTTP trigger function for receiving messages
- Test the function locally
Create the Project Folder
- Create a new folder on your desktop called streaming-backend.
- Open the folder in Cursor (or your preferred editor):
cursor .
- Open the terminal in Cursor (View > Terminal or Ctrl+`).
Initialize the Azure Functions Project
- Run the following command to create a new Functions project:
func init --python
✅ Project created
You should see output confirming the project was created with host.json, local.settings.json, and requirements.txt.
❌ I got an error
- Python not found: Install Python 3.8+ from python.org or run brew install python on macOS.
- func command not found: Complete the Azure Functions Core Tools installation in Step 1, then restart your terminal.
Still stuck? Ask for help! or check out the NextWork Community.
Your project folder should now contain these files:
Create the Message Endpoint
- Create a new HTTP trigger function:
func new --name message --template "HTTP trigger" --authlevel "anonymous"
This creates a function_app.py file (or updates it) with your function.
- Open function_app.py in your editor.
- Use Cursor (or your AI assistant) to generate the code with this prompt:
Create an Azure Function app with three HTTP endpoints:
1. POST /message - receives JSON with "content" and optional "username", stores in an in-memory list, returns the created message with a UUID and timestamp
2. GET /messages - returns all stored messages as JSON
3. GET /health - returns "Healthy" status
Use the azure.functions SDK with @app.route decorators. Include proper error handling for invalid JSON and missing fields.
Note: Don't include "/api/" in the route paths - Azure Functions adds that prefix automatically.
Test Locally
- Start the function locally:
func start
✅ Functions are running
You should see your function URLs listed. Keep this terminal running - you'll test from a new terminal.
❌ I got an error
- Port 7071 in use: Stop other Azure Functions or run func start --port 7072 (use 7072 in test commands).
- Import error: Run pip install -r requirements.txt then try again.
Still stuck? Ask for help! or check out the NextWork Community.
- Open a new terminal and test the POST endpoint:
🍎 macOS
curl -X POST http://localhost:7071/api/message \
-H "Content-Type: application/json" \
-d '{"content": "Hello from the stream!", "username": "testuser"}'
🪟 Windows
In PowerShell:
Invoke-WebRequest -Uri http://localhost:7071/api/message `
-Method POST `
-Headers @{"Content-Type"="application/json"} `
-Body '{"content": "Hello from the stream!", "username": "testuser"}'
Or if you have curl installed:
curl -X POST http://localhost:7071/api/message -H "Content-Type: application/json" -d "{\"content\": \"Hello from the stream!\", \"username\": \"testuser\"}"
✅ I got a JSON response
You should see "success": true with your message object. Your function is working!
❌ I got an error
- Connection refused: Make sure func start is still running in the other terminal.
- curl not found: On Windows, use PowerShell:
`Invoke-WebRequest -Uri http://localhost:7071/api/message -Method POST -Headers @{"Content-Type"="application/json"} -Body '{"content": "Hello!", "username": "test"}'`
Still stuck? Ask for help! or check out the NextWork Community.
- Test the GET endpoint:
curl http://localhost:7071/api/messages
You should see the message you just posted.
- Press Ctrl+C in the first terminal to stop the function.
Step 2 Complete!
Your function works locally - that's the hard part done! Time to deploy it to the cloud.
Deploy to Azure
Your function works locally - but that's just your laptop. Let's deploy it to Azure so it's accessible from anywhere in the world, and can scale to handle thousands of concurrent users.
In this step, get ready to:
- Create a Function App in Azure
- Deploy your function
- Test the live endpoint
Create a Storage Account
Azure Functions requires a Storage Account for internal operations.
- In the Azure Portal, click Create a resource.
- Search for Storage account and select it.
- Click Create.
- Fill in the details:
- Resource group: Select streaming-backend-rg.
- Storage account name: streamingbackendstorage (must be globally unique, lowercase, no hyphens).
- Region: Same as your resource group.
- Primary workload: Cloud native.
- Preferred storage type: Azure Blob Storage or Azure Data Lake Storage Gen 2.
- Performance: Standard.
- Redundancy: Locally-redundant storage (LRS).
- Click Review + create, then Create.
- Wait for deployment to complete.
Upgrade Your Subscription (Required)
Azure Functions requires a Pay-As-You-Go subscription. Don't worry - you still only pay for what you use, and Azure Functions has a free tier of 1 million executions per month.
- Search for Subscriptions in the Azure Portal.
- Select your subscription.
- Click Upgrade subscription.
- Select Basic and click Upgrade to pay as you go.
- Wait for the upgrade to complete. You'll see a confirmation message when it's done.
Create the Function App
- Search for Function App and select it.
- Click Create.
- Select the Consumption hosting option (pay only when your functions run, scales to zero).
- Fill in the details:
- Resource group: Select streaming-backend-rg.
- Function App name: streaming-backend (must be globally unique).
- Runtime stack: Python.
- Version: 3.11.
- Region: Same as your resource group.
- Operating System: Linux.
- Click Next: Storage.
- Select the storage account you just created.
- Click Review + create, then Create.
- Wait for deployment to complete (this takes 1-2 minutes).
Deploy Your Function
- Open Cursor and open the terminal (Ctrl+`).
- Deploy using the Azure Functions Core Tools:
func azure functionapp publish streaming-backend
✅ Deployment succeeded
You should see your function URLs in the terminal output:
Ctrl+click the Invoke URL to copy it:
Paste your Function App URL here (just the base URL, without /api/message):
[[FUNCTION_URL="https://streaming-backend-abc123.azurewebsites.net"]]
❌ I got an error
- Authentication error: Run az login to log in, then try again.
- Function App not found: Verify the exact name from Azure Portal and check az account show for correct subscription.
- Deployment failed: Check requirements.txt is correct and try again.
Still stuck? Ask for help! or check out the NextWork Community.
Test the Live Endpoint
- Test the POST endpoint:
🍎 macOS
curl -X POST [[FUNCTION_URL="https://streaming-backend-abc123.azurewebsites.net"]]/api/message \
-H "Content-Type: application/json" \
-d '{"content": "Hello from Azure!", "username": "clouduser"}'
🪟 Windows
In PowerShell:
Invoke-WebRequest -Uri [[FUNCTION_URL="https://streaming-backend-abc123.azurewebsites.net"]] `
-Method POST `
-Headers @{"Content-Type"="application/json"} `
-Body '{"content": "Hello from Azure!", "username": "clouduser"}'
Or if you have curl installed:
curl -X POST [[FUNCTION_URL="https://streaming-backend-abc123.azurewebsites.net"]]/api/message -H "Content-Type: application/json" -d "{\"content\": \"Hello from Azure!\", \"username\": \"clouduser\"}"
- Test the GET endpoint:
curl [[FUNCTION_URL="https://streaming-backend-abc123.azurewebsites.net"]]/api/messages
✅ I got a response
Your streaming backend is now live! Congratulations - you've deployed a serverless API to Azure!
❌ I got an error
- Timeout: This might be a "cold start" - wait 10-20 seconds and try again.
- 500 error: Check Function App logs in Azure Portal under Monitor > Log stream.
Still stuck? Ask for help! or check out the NextWork Community.
Step 3 Complete!
You did it! Your serverless API is live and can scale to handle thousands of requests automatically.
Secret mission
Right now, your messages are stored in memory. When the function restarts, they're gone. Real streaming platforms need persistent storage that can handle millions of messages.
How do companies like Netflix, Xbox, and Coca-Cola handle millions of data points per second? They use globally distributed databases that scale automatically. Azure Cosmos DB powers Netflix's entire catalog and many gaming platforms' real-time player data.
In this secret mission, you'll connect your streaming backend to Cosmos DB - giving your messages persistent storage that survives restarts and scales to handle any traffic load.
Add Persistent Storage with Cosmos DB
Clean Up Your Resources
Clean Up Your Resources
Before you close your laptop, let's make sure you're not paying for resources you don't need.
Azure Functions on the Consumption plan only charge when your function runs, so costs are minimal. However, if you created a Cosmos DB account, it has a small ongoing cost.
What would you like to do with your Azure resources?
🟢 Keep my resources
No action needed! Serverless resources only charge when used (~$0 when idle). Your resources will be ready for the next project.
🔴 Delete everything
Go to Azure Portal → Resource groups → streaming-backend-rg → Delete resource group → Type the name to confirm → Delete.
This is irreversible - you'll need to recreate resources for future projects.
That's a wrap!
That's a wrap!
You did it! You've built a serverless streaming backend with Azure Functions - the same architecture that powers Coca-Cola's AI campaigns and the NFL's scouting platform.
In this project, you:
- 🛠️ Set up an Azure development environment with Functions Core Tools and Azure CLI.
- 🚀 Created HTTP endpoints for receiving and retrieving streaming messages.
- ✨ Deployed a serverless Python function to Azure.
- 📈 Built an architecture that scales automatically to handle any traffic load.
- 💎 Connected your backend to Cosmos DB for persistent storage (secret mission).
Ready to quiz yourself? 💪
Next steps:
Ready to take your streaming backend further? Here's what you can build next:
- Add AI Moderation with Azure & Gemini
- Handle Streaming Events at Scale
- Deploy Your Streaming App with Azure DevOps
p.s. Does it say "Still tasks to complete!" at the bottom of the screen?
This means you still have screenshots left to upload, or questions left to answer!
- Press Ctrl+F (Windows) or Command+F (Mac) on your keyboard.
- Search for the text Return to later.
- Jump straight to your incomplete tasks!
- 🙋♀️ Still stuck? Ask the community!