Proposed Pull Request Change

title description author ms.author ms.date ms.topic ms.service services ms.custom
Deploy Azure Functions as modules - Azure IoT Edge In this tutorial, you develop an Azure Function as an IoT Edge module, then deploy it to an edge device. sethmanheim sethm 06/04/2025 tutorial azure-iot-edge iot-edge mvc, devx-track-csharp
📄 Document Links
GitHub View on GitHub Microsoft Learn View on Microsoft Learn
Content Truncation Detected
The generated rewrite appears to be incomplete.
Original lines: -
Output lines: -
Ratio: -
Raw New Markdown
Generating updated version of doc...
Rendered New Markdown
Generating updated version of doc...
+0 -0
+0 -0
--- title: Deploy Azure Functions as modules - Azure IoT Edge description: In this tutorial, you develop an Azure Function as an IoT Edge module, then deploy it to an edge device. author: sethmanheim ms.author: sethm ms.date: 06/04/2025 ms.topic: tutorial ms.service: azure-iot-edge services: iot-edge ms.custom: "mvc, devx-track-csharp" #Customer intent: As an IoT developer, I want to use Azure Functions to execute logic on edge devices to filter data and communications that are sent to the cloud. --- # Tutorial: Deploy Azure Functions as IoT Edge modules [!INCLUDE [iot-edge-version-all-supported](includes/iot-edge-version-all-supported.md)] Use Azure Functions to deploy code that runs your business logic directly on your Azure IoT Edge devices. This tutorial shows you how to create and deploy an Azure Function that filters sensor data on a simulated IoT Edge device. Use the simulated IoT Edge device you created in the quickstarts. In this tutorial, you learn how to: > [!div class="checklist"] > > * Use Visual Studio Code to create an Azure Function > * Use Visual Studio Code and Docker to create a Docker image and publish it to a container registry > * Deploy the module from the container registry to your IoT Edge device > * View filtered data :::image type="content" source="./media/tutorial-deploy-function/functions-architecture.png" alt-text="Diagram that shows function architecture, including how to stage and deploy a function module."::: The Azure Function you create in this tutorial filters temperature data generated by your device. The function only sends messages upstream to Azure IoT Hub when the temperature is above a specified threshold. [!INCLUDE [quickstarts-free-trial-note](~/reusable-content/ce-skilling/azure/includes/quickstarts-free-trial-note.md)] ## Prerequisites Before you start this tutorial, follow the tutorial to set up your development environment for Linux container development: [Develop Azure IoT Edge modules using Visual Studio Code](tutorial-develop-for-linux.md). When you finish, you have the following prerequisites in place: * A free or standard-tier [IoT Hub](../iot-hub/iot-hub-create-through-portal.md) in Azure * An AMD64 device running Azure IoT Edge with Linux containers. Use the quickstart to set up a [Linux device](quickstart-linux.md) or [Windows device](quickstart.md). * A container registry, like [Azure Container Registry](/azure/container-registry/) * [Visual Studio Code](https://code.visualstudio.com/) set up with the [Azure IoT Edge](https://marketplace.visualstudio.com/items?itemName=vsciot-vscode.azure-iot-edge) and [Azure IoT Hub](https://marketplace.visualstudio.com/items?itemName=vsciot-vscode.azure-iot-toolkit) extensions. The *Azure IoT Edge tools for Visual Studio Code* extension is in [maintenance mode](https://github.com/microsoft/vscode-azure-iot-edge/issues/639). * Download and install a [Docker compatible container management system](support.md#container-engines) on your development machine. Set it to run Linux containers. To develop an IoT Edge module with Azure Functions, install these additional prerequisites on your development machine: * [C# for Visual Studio Code (powered by OmniSharp) extension](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csharp) * [The .NET Core SDK](https://dotnet.microsoft.com/download) ## Create a function project Azure IoT Edge for Visual Studio Code gives you management capabilities and code templates. In this section, you use Visual Studio Code to create an IoT Edge solution with an Azure Function. ### Create a new project Follow these steps to create a customizable C# Function solution template. 1. Open Visual Studio Code on your development machine. 2. Open the Visual Studio Code command palette by selecting **View** > **Command Palette**. 3. In the command palette, add and run the command **Azure IoT Edge: New IoT Edge solution**. Follow these prompts in the command palette to create your solution: * Select a folder: choose the location on your development machine for Visual Studio Code to create the solution files. * Provide a solution name: add a descriptive name for your solution, like **FunctionSolution**, or accept the default.| * Select a module template: choose **Azure Functions - C#**. * Provide a module name | Name your module **CSharpFunction**. * Provide a Docker image repository for the module. An image repository includes the name of your container registry and the name of your container image. Your container image is pre-populated from the last step. Replace **localhost:5000** with the **Login server** value from your Azure container registry. You can retrieve the **Login server** from the **Overview** page of your container registry in the Azure portal. The final string looks like \<registry name\>.azurecr.io/csharpfunction. :::image type="content" source="./media/tutorial-deploy-function/repository.png" alt-text="Screenshot showing where to add your Docker image repository name in Visual Studio Code."::: ### Add your registry credentials The environment file in your solution stores the credentials for your container registry and shares them with the IoT Edge runtime. The runtime needs these credentials to pull your private images onto your IoT Edge device. The IoT Edge extension in Visual Studio Code tries to pull your container registry credentials from Azure and populate them in the environment file. Check if your credentials are already in the file. If not, add them now: 1. In the Visual Studio Code explorer, open the `.env` file. 1. Update the fields with the **username** and **password** values you copied from your Azure container registry. To find them again, go to your container registry in Azure and look on the **Settings** > **Access keys** page. 3. Save this file. >[!NOTE] >This tutorial uses admin login credentials for Azure Container Registry, which are convenient for development and test scenarios. For production, use a least-privilege authentication option like service principals. For more information, see [Manage access to your container registry](production-checklist.md#manage-access-to-your-container-registry). ### Set target architecture to AMD64 Azure Functions modules on IoT Edge are supported only on Linux AMD64-based containers. The default target architecture for Visual Studio Code is Linux AMD64, but you set it explicitly to Linux AMD64 here. 1. Open the command palette and search for **Azure IoT Edge: Set Default Target Platform for Edge Solution**. 2. In the command palette, select the AMD64 target architecture from the list of options. ### Update the module with custom code Add some code so your **CSharpFunction** module processes messages at the edge before forwarding them to IoT Hub. 1. In the Visual Studio Code explorer, open **modules** > **CSharpFunction** > **CSharpFunction.cs**. 1. Replace the contents of the **CSharpFunction.cs** file with the following code. This code receives telemetry about ambient and machine temperature, and forwards the message to IoT Hub only if the machine temperature is above a defined threshold. ```csharp using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Threading.Tasks; using Microsoft.Azure.Devices.Client; using Microsoft.Azure.WebJobs; using Microsoft.Azure.WebJobs.Extensions.EdgeHub; using Microsoft.Azure.WebJobs.Host; using Microsoft.Extensions.Logging; using Newtonsoft.Json; namespace Functions.Samples { public static class CSharpFunction { [FunctionName("CSharpFunction")] public static async Task FilterMessageAndSendMessage( [EdgeHubTrigger("input1")] Message messageReceived, [EdgeHub(OutputName = "output1")] IAsyncCollector<Message> output, ILogger logger) { const int temperatureThreshold = 20; byte[] messageBytes = messageReceived.GetBytes(); var messageString = System.Text.Encoding.UTF8.GetString(messageBytes); if (!string.IsNullOrEmpty(messageString)) { logger.LogInformation("Info: Received one non-empty message"); // Get the body of the message and deserialize it. var messageBody = JsonConvert.DeserializeObject<MessageBody>(messageString); if (messageBody != null && messageBody.machine.temperature > temperatureThreshold) { // Send the message to the output as the temperature value is greater than the threshold. using (var filteredMessage = new Message(messageBytes)) { // Copy the properties of the original message into the new Message object. foreach (KeyValuePair<string, string> prop in messageReceived.Properties) {filteredMessage.Properties.Add(prop.Key, prop.Value);} // Add a new property to the message to indicate it is an alert. filteredMessage.Properties.Add("MessageType", "Alert"); // Send the message. await output.AddAsync(filteredMessage); logger.LogInformation("Info: Received and transferred a message with temperature above the threshold"); } } } } } //Define the expected schema for the body of incoming messages. class MessageBody { public Machine machine {get; set;} public Ambient ambient {get; set;} public string timeCreated {get; set;} } class Machine { public double temperature {get; set;} public double pressure {get; set;} } class Ambient { public double temperature {get; set;} public int humidity {get; set;} } } ``` 1. Save the file. ## Build and push your IoT Edge solution In the previous section, you created an IoT Edge solution and changed the **CSharpFunction** to filter out messages with reported machine temperatures below the acceptable threshold. Now build the solution as a container image and push it to your container registry. 1. Open the Visual Studio Code integrated terminal. Select **View** > **Terminal**. 1. Sign in to Docker in the terminal. Use the username, password, and login server from your Azure container registry. Get these values from the **Access keys** section of your registry in the Azure portal. ```bash docker login -u <ACR username> -p <ACR password> <ACR login server> ``` You can receive a security warning recommending the use of `--password-stdin`. While that best practice is recommended for production scenarios, it's outside the scope of this tutorial. For more information, see the [docker login](https://docs.docker.com/engine/reference/commandline/login/#provide-a-password-using-stdin) reference. 1. In the Visual Studio Code explorer, right-click the **deployment.template.json** file, then select **Build and Push IoT Edge Solution**. The build and push command starts three operations. First, it creates a new folder in the solution called **config** that has the full deployment manifest, which is built from the deployment template and other solution files. Second, it runs `docker build` to build the container image based on the appropriate Dockerfile for your target architecture. Then, it runs `docker push` to push the image repository to your container registry. This process can take several minutes the first time, but it's faster the next time you run the commands. ## View your container image Visual Studio Code shows a success message when your container image is pushed to your container registry. To confirm the operation, view the image in the registry. 1. In the Azure portal, go to your Azure container registry. 2. Select **Services** > **Repositories**. 3. You see the **csharpfunction** repository in the list. Select this repository to view more details. 4. In the **Tags** section, you see the **0.0.1-amd64** tag. This tag shows the version and platform of the image you built. These values are set in the *module.json* file in the *CSharpFunction* folder. ## Deploy and run the solution Use the Azure portal to deploy your Function module to an IoT Edge device like in the quickstart. You can also deploy and monitor modules from Visual Studio Code. The following sections use the Azure IoT Edge and IoT Hub for Visual Studio Code extensions listed in the prerequisites. Install the extensions now if you haven't already. 1. In the Visual Studio Code explorer, under the **Azure IoT Hub** section, expand **Devices** to see the list of IoT devices. 2. Right-click the name of your IoT Edge device, and then select **Create Deployment for Single Device**. 3. Go to the solution folder that has the **CSharpFunction**. Open the config folder, select the **deployment.amd64.json** file, and then choose **Select Edge Deployment Manifest**. 4. Under your device, expand **Modules** to see a list of deployed and running modules. Select the refresh button. You can see the new **CSharpFunction** running along with the **SimulatedTemperatureSensor** module, **$edgeAgent**, and **$edgeHub**. It can take a few moments for the new modules to show up. The IoT Edge device retrieves its new deployment information from IoT Hub, starts the new containers, and then reports the status back to IoT Hub. :::image type="content" source="./media/tutorial-deploy-function/view-modules.png" alt-text="Screenshot showing how to view deployed modules in Visual Studio Code."::: ## View the generated data See all messages that arrive at your IoT hub from your devices by running **Azure IoT Hub: Start Monitoring Built-in Event Endpoint** in the command palette. To stop monitoring messages, run **Azure IoT Hub: Stop Monitoring Built-in Event Endpoint** in the command palette. To filter the view and see messages from a specific device, right-click the device in the **Azure IoT Hub** > **Devices** section of the Visual Studio Code explorer, and select **Start Monitoring Built-in Event Endpoint**. ## Clean up resources If you plan to continue to the next recommended article, keep the resources and configurations you created and reuse them. You can also keep using the same IoT Edge device as a test device. Otherwise, delete the local configurations and the Azure resources you created in this article to avoid charges. [!INCLUDE [iot-edge-clean-up-cloud-resources](includes/iot-edge-clean-up-cloud-resources.md)] ## Next steps In this tutorial, you created an Azure Function module with code to filter raw data that's generated by your IoT Edge device. Continue on to the next tutorials to learn other ways that Azure IoT Edge can help you turn data into business insights at the edge. > [!div class="nextstepaction"] > [Find averages by using a floating window in Azure Stream Analytics](tutorial-deploy-stream-analytics.md)
Success! Branch created successfully. Create Pull Request on GitHub
Error: