About This Page
This page is part of the Azure documentation. It contains code examples and configuration instructions for working with Azure services.
Bias Analysis
Bias Types:
⚠️
windows_first
⚠️
missing_linux_example
⚠️
windows_tools
⚠️
powershell_heavy
Summary:
The documentation page demonstrates a strong Windows bias. It assumes the development machine is Windows, provides only Windows-specific installation commands (e.g., vcpkg bootstrap with .bat, use of Visual Studio, Windows file paths), and references Windows tools and patterns (e.g., Developer Command Prompt, Visual Studio Solution Explorer) without offering equivalent Linux instructions or examples. Linux is mentioned primarily as a target for deployment, not as a development environment. There are no Linux shell commands for setup, no Visual Studio for Linux guidance, and no parity in tool installation or usage instructions.
Recommendations:
- Provide explicit instructions for setting up the development environment on Linux, including installation of Visual Studio Code or other supported IDEs, and relevant extensions.
- Include Linux shell command examples for all setup steps (e.g., vcpkg installation, Docker installation, Azure CLI installation).
- Offer Linux file path examples alongside Windows paths, especially for template and project locations.
- Clarify which features and workflows are available or not available on Linux, and offer alternatives where possible.
- Add screenshots and walkthroughs for Linux-based development, including debugging and deployment.
- Where Windows-only tools are referenced (e.g., Visual Studio 2022), suggest cross-platform alternatives or note the limitations for Linux users.
- Rephrase the prerequisites to not assume Windows as the default, or provide parallel Linux sections.
- Ensure all CLI commands are shown in both Windows (cmd/PowerShell) and Linux (bash) syntax.
Create pull request
Flagged Code Snippets
1. From the **Tools** menu in Visual Studio, select **Azure IoT Edge Tools** > **Setup IoT Edge Simulator**.
1. Paste the connection string and select **OK**.
> [!NOTE]
> You need to follow these steps only once on your development computer as the results are automatically applied to all subsequent Azure IoT Edge solutions. This procedure can be followed again if you need to change to a different connection string.
### Build and debug a single module
Typically, you want to test and debug each module before running it within an entire solution with multiple modules. The IoT Edge simulator tool allows you to run a single module in isolation a send messages over port 53000.
1. In **Solution Explorer**, select and highlight the module project folder (for example, *IotEdgeModule1*). Set the custom module as the startup project. Select **Project** > **Set as StartUp Project** from the menu.
1. Press **F5** or select the run toolbar button to start the IoT Edge simulator for a single module. It may take 10 to 20 seconds the initially.
:::image type="content" source="./media/how-to-visual-studio-develop-module/run-module.png" alt-text="Screenshot of how to run a module.":::
1. You should see a .NET Core console app window appear if the module has been initialized successfully.
1. Set a breakpoint to inspect the module.
* If developing in C#, set a breakpoint in the `PipeMessage()` function in **ModuleBackgroundService.cs**.
* If using C, set a breakpoint in the `InputQueue1Callback()` function in **main.c**.
1. Test the module by sending a message. When you're debugging a single module, the simulator listens on the default port 53000 for messages. To send a message to your module, run the following curl command from a command shell like **Git Bash** or **WSL Bash**.
1. Press **Ctrl + F5** or select the stop button to stop debugging.
### Build and debug multiple modules
After you're done developing a single module, you might want to run and debug an entire solution with multiple modules. The IoT Edge simulator tool allows you to run all modules defined in the deployment manifest including a simulated edgeHub for message routing. In this example, you run two custom modules and the simulated temperature sensor module. Messages from the simulated temperature sensor module are routed to each custom module.
1. In **Solution Explorer**, add a second module to the solution by right-clicking the main project folder. On the menu, select **Add** > **New IoT Edge Module**.
:::image type="content" source="./media/how-to-visual-studio-develop-module/add-new-module.png" alt-text="Screenshot of how to add a 'New IoT Edge Module' from the menu." lightbox="./media/how-to-visual-studio-develop-module/add-new-module.png":::
1. In the `Add module` window give your new module a name and replace the `localhost:5000` portion of the repository URL with your Azure Container Registry login server, like you did before.
1. Open the file `deployment.debug.template.json` to see that the new module has been added in the **modules** section. A new route was also added to the **routes** section in `EdgeHub` to send messages from the new module to IoT Hub. To send data from the simulated temperature sensor to the new module, add another route with the following line of `JSON`. Replace `<NewModuleName>` (in two places) with your own module name.
>[!NOTE]
>This article uses admin login credentials for Azure Container Registry, which are convenient for development and test scenarios. When you're ready for production scenarios, we recommend 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).
1. If you use a local registry, [run a local registry](https://docs.docker.com/registry/deploying/#run-a-local-registry).
1. Finally, in the **Solution Explorer**, right-click the main project folder and select **Build and Push IoT Edge Modules** to build and push the Docker image for each module. This might take a minute. When you see `Finished Build and Push IoT Edge Modules.` in your Output console of Visual Studio, you're done.
## Deploy the solution
Now that you've built and pushed your module images to your Azure Container Registry, deploy the solution to your IoT Edge device. You already have a deployment manifest template in this tutorial. Generate a deployment manifest from it, then use an Azure CLI command to deploy your modules to your IoT Edge device in Azure.
1. Right-click on your main project in Visual Studio Solution Explorer and choose **Generate Deployment for IoT Edge**.
:::image type="content" source="./media/how-to-visual-studio-develop-module/generate-deployment.png" alt-text="Screenshot of location of the 'generate deployment' menu item.":::
1. Go to your local Visual Studio main project folder and look in the `config` folder. The file path might look like this: `C:\Users\<YOUR-USER-NAME>\source\repos\<YOUR-IOT-EDGE-PROJECT-NAME>\config`. Here you find the generated deployment manifest such as `deployment.amd64.debug.json`.
1. Open your `deployment.amd64.debug.json` file and confirm the `edgeHub` schema version is set to 1.2.
> [!TIP]
> The deployment template for Visual Studio 2022 requires the 1.2 schema version. If you need it to be 1.1 or 1.0, wait until after the deployment is generated (don't change it in `deployment.debug.template.json`). Generating a deployment creates a 1.2 schema by default. However, you can manually change `deployment.amd64.debug.json`, the generated manifest, if needed before deploying it to Azure.
> [!IMPORTANT]
> Once your IoT Edge device is deployed, it currently won't display correctly in the Azure portal with schema version 1.2 (version 1.1 is okay).However, this won't affect your device, as it's still connected in IoT Hub and can be communicated with at any time using the Azure CLI.
>
>:::image type="content" source="./media/how-to-publish-subscribe/unsupported-1.2-schema.png" alt-text="Screenshot of Azure portal error on the IoT Edge device page.":::
1. Now let's deploy our manifest with an Azure CLI command. Open the Visual Studio **Developer Command Prompt** and change to the **config** directory.
git clone https://github.com/Microsoft/vcpkg
cd vcpkg
bootstrap-vcpkg.bat
vcpkg.exe install azure-iot-sdk-c:x64-windows
vcpkg.exe --triplet x64-windows integrate install
:::image type="content" source="./media/how-to-visual-studio-develop-csharp-module/debug-single-module.png" alt-text="Screenshot of the output console, Visual Studio project, and Bash window." lightbox="./media/how-to-visual-studio-develop-csharp-module/debug-single-module.png":::
The breakpoint should be triggered. You can watch variables in the Visual Studio **Locals** window, found when the debugger is running. Go to **Debug** > **Windows** > **Locals**.
In your Bash or shell, you should see a `{"message":"accepted"}` confirmation.
In your .NET console you should see:
1. Right-click the main project (for example, *AzureIotEdgeApp1*) and select **Set as StartUp Project**. By setting the main project as the startup project, all modules in the solution run. This includes both modules you added to the solution, the simulated temperature sensor module, and the simulated Edge hub.
1. Press **F5** or select the run toolbar button to run the solution. It may take 10 to 20 seconds initially. Be sure you don't have other Docker containers running that might bind the port you need for this project.
1. You should see two .NET Core console app windows appear one for each module.
1. Set a breakpoint to inspect the modules.
* If developing in C#, set a breakpoint in the `PipeMessage()` function in **ModuleBackgroundService.cs**.
* If using C, set a breakpoint in the `InputQueue1Callback()` function in **main.c**.
1. Create breakpoints in each module and then press **F5** to run and debug multiple modules simultaneously. You should see multiple .NET Core console app windows, with each window representing a different module.
:::image type="content" source="./media/how-to-visual-studio-develop-csharp-module/debug-multiple-modules.png" alt-text="Screenshot of Visual Studio with two output consoles.":::
1. Press **Ctrl + F5** or select the stop button to stop debugging.
## Build and push images to registry
After you develop and debug your module, build and push the module image to your Azure Container Registry. Then deploy the module to your IoT Edge device.
1. Set the main IoT Edge project as the start-up project, not one of the individual modules.
1. Select either **Debug** or **Release** as the configuration to build for your module images.
> [!NOTE]
> When you choose **Debug**, Visual Studio uses `Dockerfile.(amd64|windows-amd64).debug` to build Docker images. This includes the .NET Core command-line debugger VSDBG in your container image. For production-ready IoT Edge modules, use the **Release** configuration, which uses `Dockerfile.(amd64|windows-amd64)` without VSDBG.
1. If you use a private registry like Azure Container Registry (ACR), use the following Docker command to sign in. Get the username and password from the **Access keys** page of your registry in the Azure portal.
1. Add the Azure Container Registry login information to the runtime settings in the `deployment.debug.template.json` file. You can add your registry credentials to your `.env` file (most secure) or add them directly to your `deployment.debug.template.json` file.
**Add credentials to your `.env` file:**
In **Solution Explorer**, select the **Show All Files** toolbar button. The `.env` file appears. Add your Azure Container Registry username and password to your `.env` file. Find these credentials on the **Access Keys** page of your Azure Container Registry in the Azure portal.
:::image type="content" source="./media/how-to-visual-studio-develop-module/show-env-file.png" alt-text="Screenshot of button that shows all files in the Solution Explorer.":::