Multiple TensorFlow Graphs from Cognitive Services – Custom Vision Service

For one project, there was a need for multiple models within the same Python application. These models were trained using the Cognitive Services: Custom Vision Service. There are two steps to using an exported model:

  1. Prepare the image
  2. Classify the image

Prepare an image for prediction

from PIL import Image
import numpy as np
import cv2
def convert_to_opencv(image):
# RGB -> BGR conversion is performed as well.
image = image.convert('RGB')
r,g,b = np.array(image).T
opencv_image = np.array([b,g,r]).transpose()
return opencv_image
def crop_center(img,cropx,cropy):
h, w = img.shape[:2]
startx = w//2(cropx//2)
starty = h//2(cropy//2)
return img[starty:starty+cropy, startx:startx+cropx]
def resize_down_to_1600_max_dim(image):
h, w = image.shape[:2]
if (h < 1600 and w < 1600):
return image
new_size = (1600 * w // h, 1600) if (h > w) else (1600, 1600 * h // w)
return cv2.resize(image, new_size, interpolation = cv2.INTER_LINEAR)
def resize_to_256_square(image):
h, w = image.shape[:2]
return cv2.resize(image, (256, 256), interpolation = cv2.INTER_LINEAR)
def update_orientation(image):
exif_orientation_tag = 0x0112
if hasattr(image, '_getexif'):
exif = image._getexif()
if (exif != None and exif_orientation_tag in exif):
orientation = exif.get(exif_orientation_tag, 1)
# orientation is 1 based, shift to zero based and flip/transpose based on 0-based values
orientation -= 1
if orientation >= 4:
image = image.transpose(Image.TRANSPOSE)
if orientation == 2 or orientation == 3 or orientation == 6 or orientation == 7:
image = image.transpose(Image.FLIP_TOP_BOTTOM)
if orientation == 1 or orientation == 2 or orientation == 5 or orientation == 6:
image = image.transpose(Image.FLIP_LEFT_RIGHT)
return image
def prepare_image(image):
# Update orientation based on EXIF tags, if the file has orientation info.
image = update_orientation(image)
# Convert to OpenCV format
image = convert_to_opencv(image)
# If the image has either w or h greater than 1600 we resize it down respecting
# aspect ratio such that the largest dimension is 1600
image = resize_down_to_1600_max_dim(image)
# We next get the largest center square
h, w = image.shape[:2]
min_dim = min(w,h)
max_square_image = crop_center(image, min_dim, min_dim)
# Resize that square down to 256×256
augmented_image = resize_to_256_square(max_square_image)
augmented_image = crop_center(augmented_image, 244, network_input_size)
return augmented_image

Classify the image

To run multiple models in Python was fairly simple. Simply call tf.reset_default_graph() after saving the loaded session into memory.

import tensorflow as tf
import numpy as np
# The category name and probability percentage
class CategoryScore:
def __init__(self, category, probability: float):
self.category = category
self.probability = probability
# The categorizer handles running tensorflow models
class Categorizer:
def __init__(self, model_file_path: str, map: []): = map
self.graph = tf.Graph()
self.graph_def = self.graph.as_graph_def()
with tf.gfile.GFile(model_file_path, 'rb') as f:
tf.import_graph_def(self.graph_def, name='')
output_layer = 'loss:0'
self.input_node = 'Placeholder:0'
self.sess = tf.Session()
self.prob_tensor = self.sess.graph.get_tensor_by_name(output_layer)
def score(self, image):
predictions, =, {self.input_node: [image]})
label_index = 0
scores = []
for p in predictions:
category_score = CategoryScore([label_index],np.float64(np.round(p, 8)))
label_index += 1
return scores

After the CustomVisionCategorizer is create, just call score and it will score with the labels in the map.

Securing SSH in Azure

On a recent project I inherited an Azure IaaS setup that managed Linux VMs by connecting via SSH from public IPs. I figured while we did a vNet migration we might as well secure the SSH pipeline.

Disable SSH Arcfour and CBC Ciphers

Arcfour is compatible with RC4 encryption and has issues with weak keys, which should be avoided. See RFC 4353 for more information here.

The SSH server located on the remote host also allows cipher block chaining (CBC) ciphers to be used to establish a Secure Shell (SSH) connection, leaving encrypted content vulnerable to a plaintext recovery attack. SSH is a cryptographic network protocol that allows encrypted connections between machines to be established. These connections can be used for remote login by an end user, or to encrypt network services. SSH leverages various encryption algorithms to make these connections, including ciphers that employ cipher block chaining.

The plaintext recovery attack can return up to thirty two bits of plaintext with a probability of 2-18 or fourteen bits of plain text with a probability of 2-14. This exposure is caused by the way CBC ciphers verify the message authentication code (MAC) for a block. Each block’s MAC is created by a combination of an unencrypted sequence number and an encrypted section containing the packet length, padding length, payload, and padding. With the length of the message encrypted the receiver of the packet needs to decrypt the first block of the message in order to obtain the length of the message to know how much data to read. As the location of the message length is static among all messages, the first four bytes will always be decrypted by a recipient. An attacker can take advantage of this by submitting an encrypted block, one byte at a time, directly to a waiting recipient. The recipient will automatically decrypt the first four bytes received as it the length is required to process the message’s MAC. Bytes controlled by an attacker can then be submitted until a MAC error is encountered, which will close the connection. Note as this attack will lead to the SSH connection to be closed, iterative attacks of this nature will be difficult to carry out against a target system.

Establishing an SSH connection using CBC mode ciphers can result in the exposure of plaintext messages, which are derived from an encrypted SSH connection. Depending on the data being transmitted, an attacker may be able to recover session identifiers, passwords, and any other data passed between the client and server.

Disable Arcfour ciphers in the SSH configuration. These ciphers are now disabled by default in some OpenSSH installations. All CBC mode ciphers should also be disabled on the target SSH server. In the place of CBC, SSH connections should be created using ciphers that utilize CTR (Counter) mode or GCM (Galois/Counter Mode), which are resistant to the plaintext recovery attack.

Disable SSH Weak MAC Algorithms

The SSH server is configured to allow cipher suites that include weak message authentication code (“MAC”) algorithms. Examples of weak MAC algorithms include MD5 and other known-weak hashes, and/or the use of 96-bit or shorter keys. The SSH protocol uses a MAC to ensure message integrity by hashing the encrypted message, and then sending both the message and the output of the MAC hash function to the recipient. The recipient then generates their hash of the message and related content and compares it to the received hash value. If the values match, there is a reasonable guarantee that the message is received “as is” and has not been tampered with in transit.

If the SSH server is configured to accept weak or otherwise vulnerable MAC algorithms, an attacker may be able to crack them in a reasonable timeframe. This has two potential effects:

  • The attacker may figure out the shared secret between the client and the server thereby allowing them to read sensitive data being exchanged. 
  • The attacker may be able to tamper with the data in-transit by injecting their own packets or modifying existing packet data sent within the SSH stream.

Disable all 96-bit HMAC algorithms, MD5-based HMAC algorithms, and all CBC mode ciphers configured for SSH on the server. The sshd_config file should only contain the following options as far as supported MAC algorithms are concerned:

  • hmac-sha2-512
  • hmac-sha2-256
  • hmac-ripemd160

In addition, all CBC mode ciphers should be replaced with their CTR mode counterparts.


To test, run the following command:

nmap -sS -sV -p 22 –script ssh2-enum-algos [TARGET IP]

Upcoming Pluralsight Course – Designing an Intelligent Edge in Microsoft Azure

Off to start another course for Pluralsight. This time its Designing an Intelligent Edge in Microsoft Azure. If you would like to check out any of my other courses, visit my author’s profile. The new course will cover the following topics:

  • Edge –
    • Scenarios
    • Concerns
    • Architecture
  • Azure AI Pipelines – Overview with edge
  • Edge Pipelines –
    • Azure Stack
    • Azure Databox Edge
    • Azure IoT Edge
  • Cognitive Services – Overview with Edge
  • Azure Databricks – Overview
  • Azure Machine Learning VMs
  • Project Brainwave

Multi-Region Point-to-Site in Microsoft Azure (Windows Fix)

In a previous post, I showcased how to: Create a Single Gateway, Multi-Region, VPN Architecture in Microsoft Azure. If testing with Windows didn’t work, it may be because Windows has to have its route tables updated to know how to tunnel past the gateway into the different regions. MAC and Linux can use IKEv2 without additional route adding.

A. For Windows, by default, it chooses IKEv2, we need to add a route to your spoke VNET

ip tables

Suppose the VNET spoke address space is,  and Client VPN interface IP is

route add

B. We also need to test the CMAK or manually create a SSTP VPN profile to Azure on Windows client.

Creating a Single Gateway, Multi-Region, VPN Architecture in Microsoft Azure

The goal of this post is to showcase how to create a gateway for a multi-region VPN architecture in Microsoft Azure. We can start from a very basic use case, three regions:

  • One containing the VPN gateway all clients will connect through
  • Two other regions containing resources connected to the vNet gateway

There are two terms that will be used throughout this post:

  •  Hub – this refers to the central VPN Gateway that all other VPN Gateways will connect to.
  •  Spoke – this refers to an individual VPN Gateway that connects to the Hub


Since there will be a vNet for each region peered with the hub, address spacing should be taken into consideration before creating each Virtual Network in a region. From previous experience, it was considered best practice to:

Address – {shared}.{region_specific}.{subnet}.{instance}

  •  Shared – A common root address was picked for the first octet. This is the best place to avoid conflicts with networks outside of Azure that will connect to the Hub.
  •  Region Specific – Each region would get its own address for the second octet
  •  Subnet – Each subnet in the region would get an address for the third octet
  •  Instance – Finally each assigned IP address would fill the fourth octet

This does not account for third party integration and Site-to-Site integrations. Those require future planning and, as always in business, there is no way to properly plan for every variation.

Create the vNets

Once the planning phase is complete we will create three Virtual Networks in three separate regions. Which Virtual Network is the Hub and which is the Spokes does not matter yet.

  1. Sign in to the Azure portal and select Create a resource. The New page opens.
  2. In the Search the marketplace field, enter virtual network and select Virtual network from the returned list. The Virtual network page opens.

    Locate Virtual Network resource page

  3. From the Select a deployment model list near the bottom of the page, select Resource Manager, and then select Create. The Create virtual network page opens.

    Create virtual network page

  4. On the Create virtual network page, configure the VNet settings. When you fill in the fields, the red exclamation mark becomes a green check mark when the characters you enter in the field are validated. Some values are autofilled, which you can replace with your own values:
    • Name: Enter the name for your virtual network.
    • Address space: Enter the address space. If you have multiple address spaces to add, enter your first address space here. You can add additional address spaces later, after you create the VNet.
    • Subscription: Verify that the subscription listed is the correct one. You can change subscriptions by using the drop-down.
    • Resource group: Select an existing resource group, or create a new one by entering a name for your new resource group. If you’re creating a new group, name the resource group according to your planned configuration values. For more information about resource groups, see Azure Resource Manager overview.
    • Location: Select the location for your VNet. The location determines where the resources that you deploy to this VNet will live.
    • Subnet: Add the subnet Name and subnet Address range. You can add additional subnets later, after you create the VNet.
  5. Select Create.

Before creating a virtual network gateway for your virtual network, you first need to create the gateway subnet. The gateway subnet contains the IP addresses that are used by the virtual network gateway. If possible, it’s best to create a gateway subnet by using a CIDR block of /28 or /27 to provide enough IP addresses to accommodate future additional configuration requirements.

  1. In the Azure portal, select the Resource Manager virtual network for which you want to create a virtual network gateway.
  2. In the Settings section of your virtual network page, select Subnets to expand the Subnets page.
  3. On the Subnets page, select Gateway subnet to open the Add subnet page.

    Add the gateway subnet

  4. The Name for your subnet is automatically autofilled with the value GatewaySubnet. This value is required for Azure to recognize the subnet as the gateway subnet. Adjust the autofilled Address range values to match your configuration requirements, then select OK to create the subnet.

    Adding the subnet

Create Virtual Network Gateways

Once the Virtual Networks are created, we will create a Virtual Network Gateway for each of the Virtual Networks. Which Virtual Network Gateway is the Hub and which is the Spokes does not matter yet.

  1. Sign in to the Azure portal and select Create a resource. The New page opens.
  2. In the Search the marketplace field, enter virtual network gateway, and select Virtual network gateway from the search list.
  3. On the Virtual network gateway page, select Create to open the Create virtual network gateway page.

    Create virtual network gateway page fields

  4. On the Create virtual network gateway page, fill in the values for your virtual network gateway:
    • Name: Enter a name for the gateway object you’re creating. This name is different than the gateway subnet name.
    • Gateway type: Select VPN for VPN gateways.
    • VPN type: Select the VPN type that is specified for your configuration. Most configurations require a Route-based VPN type.
    • SKU: Select the gateway SKU from the dropdown. The SKUs listed in the dropdown depend on the VPN type you select. For more information about gateway SKUs, see Gateway SKUs.

      Only select Enable active-active mode if you’re creating an active-active gateway configuration. Otherwise, leave this setting unselected.

    • Location: You may need to scroll to see Location. Set Location to the location where your virtual network is located. For example, West US. If you don’t set the location to the region where your virtual network is located, it won’t appear in the drop-down list when you select a virtual network.
    • Virtual network: Choose the virtual network to which you want to add this gateway. Select Virtual network to open the Choose virtual network page and select the VNet. If you don’t see your VNet, make sure the Location field is set to the region in which your virtual network is located.
    • Gateway subnet address range: You’ll only see this setting if you didn’t previously create a gateway subnet for your virtual network. If you previously created a valid gateway subnet, this setting won’t appear.
    • Public IP address: This setting specifies the public IP address object that’s associated with the VPN gateway. The public IP address is dynamically assigned to this object when the VPN gateway is created. The VPN gateway currently supports only Dynamic public IP address allocation. However, dynamic allocation doesn’t mean that the IP address changes after it has been assigned to your VPN gateway. The only time the public IP address changes is when the gateway is deleted and re-created. It doesn’t change across resizing, resetting, or other internal maintenance/upgrades of your VPN gateway.
      • Leave Create new selected.
      • In the text box, enter a name for your public IP address.
    • Configure BGP ASN: Leave this setting unselected, unless your configuration specifically requires it. If you do require this setting, the default ASN is 65515, which you can change.
  5. Verify the settings and select Create to begin creating the VPN gateway. The settings are validated and you’ll see the Deploying Virtual network gateway tile on the dashboard. Creating a gateway can take up to 45 minutes. You may need to refresh your portal page to see the completed status.
  6. After you create the gateway, verify the IP address that’s been assigned to it by viewing the virtual network in the portal. The gateway appears as a connected device. You can select the connected device (your virtual network gateway) to view more information.

Connecting the Gateways

With the Virtual Network Gateways created, it is time to connect the gateways. Starting with the Hub, connect the Hub to a Spoke. Then, connect that Spoke back to the Hub. Do this for each Spoke that is going to connect to the Hub.

  1. In the Azure portal, select All resources, enter virtual network gateway in the search box, and then navigate to the virtual network gateway for your VNet. For example, TestVNet1GW. Select it to open the Virtual network gateway page.

    Connections page

  2. Under Settings, select Connections, and then select Add to open the Add connection page.

    Add connection

  3. On the Add connection page, fill in the values for your connection:
    • Name: Enter a name for your connection. For example, TestVNet1toTestVNet4.
    • Connection type: Select VNet-to-VNet from the drop-down.
    • First virtual network gateway: This field value is automatically filled in because you’re creating this connection from the specified virtual network gateway.
    • Second virtual network gateway: This field is the virtual network gateway of the VNet that you want to create a connection to. Select Choose another virtual network gateway to open the Choose virtual network gateway page.
      • View the virtual network gateways that are listed on this page. Notice that only virtual network gateways that are in your subscription are listed. If you want to connect to a virtual network gateway that isn’t in your subscription, use the PowerShell.
      • Select the virtual network gateway to which you want to connect.
      • Shared key (PSK): In this field, enter a shared key for your connection. You can generate or create this key yourself. In a site-to-site connection, the key you use is the same for your on-premises device and your virtual network gateway connection. The concept is similar here, except that rather than connecting to a VPN device, you’re connecting to another virtual network gateway.
  4. Select OK to save your changes.

Verify your connections

Locate the virtual network gateway in the Azure portal. On the Virtual network gateway page, select Connections to view the Connections page for the virtual network gateway. After the connection is established, you’ll see the Status values change to Succeeded and Connected. Select a connection to open the Essentials page and view more information.


After verifying the connection was successful, the connection can be tested with a Point-to-Site connection or a Site-to-Site connection.

Speaking at DotNetSouth.Tech

I look forward to speaking on AI on the Edge at DotNetSouth.Tech. This year is the conference’s first year so check it out.

AI on the Edge

The next evolution in cloud computing is a smarter application not in the cloud. As the cloud has continued to evolve, the applications that utilize it have had more and more capabilities of the cloud. This presentation will show how to push logic and machine learning from the cloud to an edge application. Afterward, creating edge applications which utilize the intelligence of the cloud should become effortless.


Speaking at Orlando Code Camp

I am happy to announce I will speaking at the Orlando Code Camp again this year. I will be presenting AI on the Edge, a look into Microsoft’s Azure IoT Edge.


AI on the Edge


The next evolution in cloud computing is a smarter application not in the cloud. As the cloud has continued to evolve, the applications that utilize it have had more and more capabilities of the cloud. This presentation will show how to push logic and machine learning from the cloud to an edge application. Afterward, creating edge applications which utilize the intelligence of the cloud should become effortless.

Authoring for Pluralsight – Microsoft Azure Cognitive Services: Text to Speech API

I’m excited to announce that I am authoring another course for Pluralsight. This course targets software developers who are looking to get started with Microsoft Azure Cognitive Services: Text to Speech API to build modern AI solutions and want to get started building an AI solution with a simple REST interface. This course continues from the other Cognitive Services courses created and being created for the Cognitive Services track.


With AI becoming more and more ubiquitous, it is important to quickly and easily integrate with AI services. This course will show how to create modern applications using Microsoft Azure Cognitive Services: Text to Speech API with JavaScript, C#, Java, C++, and Python.


This course assumes viewers are familiar with C# or Java or JavaScript or Python or C++ and understands REST APIs and JSON.


Contoso is an insurance company that has decided to integrate text to speech for multiple consumer facing applications. This course will take a look at utilizing the following features of Cognitive Services – Text to Speech API:

  • Default API interface through multiple SDKs: JavaScript, C#, Java, C++, and Python
  • Creating custom voice fonts
  • Popular scenarios and use case for Text to Speech



Using Open CV C++ with Azure IoT Edge

If you are looking for a guide on creating an Open CV module in Python, check out a guide here. This guide will focus on creating an Azure IoT Edge module in C++. To accomplish this we need to take the following steps:

Create the Azure IoT Edge Module


This article assumes that you use a computer or virtual machine running Windows or Linux as your development machine. And you simulate your IoT Edge device on your development machine.


To create a module, you need Docker to build the module image, and a container registry to hold the module image:

Create a new solution template

Take these steps to create an IoT Edge module based on Azure IoT C SDK using Visual Studio Code and the Azure IoT Edge extension. First you create a solution, and then you generate the first module in that solution. Each solution can contain more than one module.

  1. In Visual Studio Code, select View > Integrated Terminal.
  2. Select View > Command Palette.
  3. In the command palette, enter and run the command Azure IoT Edge: New IoT Edge Solution.Run New IoT Edge Solution
  4. Browse to the folder where you want to create the new solution. Choose Select folder.
  5. Enter a name for your solution.
  6. Select C Module as the template for the first module in the solution.
  7. Enter a name for your module. Choose a name that’s unique within your container registry.
  8. Provide the name of the module’s image repository. VS Code autopopulates the module name with localhost:5000. Replace it with your own registry information. If you use a local Docker registry for testing, then localhost is fine. If you use Azure Container Registry, then use the login server from your registry’s settings. The login server looks like

VS Code takes the information you provided, creates an IoT Edge solution, and then loads it in a new window.

View IoT Edge solution

There are four items within the solution:

  • .vscode folder contains debug configurations.
  • modules folder has subfolders for each module. At this point, you only have one. But you can add more in the command palette with the command Azure IoT Edge: Add IoT Edge Module.
  • An .env file lists your environment variables. If Azure Container Registry is your registry, you’ll have an Azure Container Registry username and password in it.


    The environment file is only created if you provide an image repository for the module. If you accepted the localhost defaults to test and debug locally, then you don’t need to declare environment variables.

  • deployment.template.json file lists your new module along with a sample tempSensor module that simulates data you can use for testing. For more information about how deployment manifests work, see Learn how to use deployment manifests to deploy modules and establish routes.

Develop your module

The default C module code that comes with the solution is located at modules >  > main.c. The module and the deployment.template.json file are set up so that you can build the solution, push it to your container registry, and deploy it to a device to start testing without touching any code. The module is built to simply take input from a source (in this case, the tempSensor module that simulates data) and pipe it to IoT Hub.

When you’re ready to customize the C template with your own code, use the Azure IoT Hub SDKs to build modules that address the key needs for IoT solutions such as security, device management, and reliability.

Build and deploy your module for debugging

In each module folder, there are several Docker files for different container types. Use any of these files that end with the extension .debug to build your module for testing. Currently, C modules support debugging only in Linux amd64 containers.

  1. In VS Code, navigate to the deployment.template.json file. Update your module image URL by adding .debug to the end.Add **.debug** to your image name
  2. Replace the Node.js module createOptions in deployment.template.json with below content and save this file:
    "createOptions": "{\"HostConfig\": {\"Privileged\": true}}"
  3. In the VS Code command palette, enter and run the command Edge: Build IoT Edge solution.
  4. Select the deployment.template.json file for your solution from the command palette.
  5. In Azure IoT Hub Device Explorer, right-click an IoT Edge device ID. Then select Create deployment for IoT Edge device.
  6. Open your solution’s config folder. Then select the deployment.json file. Choose Select Edge Deployment Manifest.

You’ll see the deployment successfully created with a deployment ID in a VS Code-integrated terminal.

Check your container status in the VS Code Docker explorer or by running the docker ps command in the terminal.

Start debugging C module in VS Code

VS Code keeps debugging configuration information in a launch.json file located in a .vscode folder in your workspace. This launch.json file was generated when you created a new IoT Edge solution. It updates each time you add a new module that supports debugging.

  1. Navigate to the VS Code debug view. Select the debug configuration file for your module. The debug option name should be similar to ModuleName Remote Debug (C)Select debug configuration.
  2. Navigate to main.c. Add a breakpoint in this file.
  3. Select Start Debugging or select F5. Select the process to attach to.
  4. In VS Code Debug view, you’ll see the variables in the left panel.

The preceding example shows how to debug C IoT Edge modules on containers. It added exposed ports in your module container createOptions. After you finish debugging your Node.js modules, we recommend you remove these exposed ports for production-ready IoT Edge modules.

Create a working Open CV Build

The working environment is an Ubuntu 18.04 64 bit Desktop OS running Clion using an embedded version of CMake 3.10. Open CV is added via source as a submodule to the project and added as a package in the CMakeLists.txt with the following line:


Once that was added to the CMakeLists.txt, the main.cpp file was changed to the following code:

#include <opencv2/opencv.hpp>
int main( int argc, char** argv )
VideoCapture cap;
return 0;
Mat frame;
cap >> frame;
//Do something with the frame

view raw


hosted with ❤ by GitHub

Deploy the Azure IoT Edge Module

Once you create IoT Edge modules with your business logic, you want to deploy them to your devices to operate at the edge. If you have multiple modules that work together to collect and process data, you can deploy them all at once and declare the routing rules that connect them.

This article shows how to create a JSON deployment manifest, then use that file to push the deployment to an IoT Edge device. For information about creating a deployment that targets multiple devices based on their shared tags, see Deploy and monitor IoT Edge modules at scale


Configure a deployment manifest

A deployment manifest is a JSON document that describes which modules to deploy, how data flows between the modules, and desired properties of the module twins. For more information about how deployment manifests work and how to create them, see Understand how IoT Edge modules can be used, configured, and reused.

To deploy modules using Visual Studio Code, save the deployment manifest locally as a .JSON file. You will use the file path in the next section when you run the command to apply the configuration to your device.

Here’s a basic deployment manifest with one module as an example:

  "modulesContent": {
    "$edgeAgent": {
      "properties.desired": {
        "schemaVersion": "1.0",
        "runtime": {
          "type": "docker",
          "settings": {
            "minDockerVersion": "v1.25",
            "loggingOptions": "",
            "registryCredentials": {}
        "systemModules": {
          "edgeAgent": {
            "type": "docker",
            "settings": {
              "image": "",
              "createOptions": "{}"
          "edgeHub": {
            "type": "docker",
            "status": "running",
            "restartPolicy": "always",
            "settings": {
              "image": "",
              "createOptions": "{}"
        "modules": {
          "tempSensor": {
            "version": "1.0",
            "type": "docker",
            "status": "running",
            "restartPolicy": "always",
            "settings": {
              "image": "",
              "createOptions": "{}"
    "$edgeHub": {
      "properties.desired": {
        "schemaVersion": "1.0",
        "routes": {
            "route": "FROM /* INTO $upstream"
        "storeAndForwardConfiguration": {
          "timeToLiveSecs": 7200
    "tempSensor": {
      "properties.desired": {}

Sign in to access your IoT hub

You can use the Azure IoT extensions for Visual Studio Code to perform operations with your IoT hub. For these operations to work, you need to sign in to your Azure account and select the IoT hub that you are working on.

  1. In Visual Studio Code, open the Explorer view.
  2. At the bottom of the Explorer, expand the Azure IoT Hub Devices section.Expand Azure IoT Hub Devices
  3. Click on the  in the Azure IoT Hub Devices section header. If you don’t see the ellipsis, hover over the header.
  4. Choose Select IoT Hub.
  5. If you are not signed in to your Azure account, follow the prompts to do so.
  6. Select your Azure subscription.
  7. Select your IoT hub.

Deploy to your device

You deploy modules to your device by applying the deployment manifest that you configured with the module information.

  1. In the Visual Studio Code explorer view, expand the Azure IoT Hub Devices section.
  2. Right-click on the device that you want to configure with the deployment manifest.
  3. Select Create Deployment for IoT Edge Device.
  4. Navigate to the deployment manifest JSON file that you want to use, and click Select Edge Deployment Manifest.Select Edge Deployment Manifest

The results of your deployment are printed in the VS Code output. Successful deployments are applied within a few minutes if the target device is running and connected to the internet.

View modules on your device

Once you’ve deployed modules to your device, you can view all of them in the Azure IoT Hub Devices section. Select the arrow next to your IoT Edge device to expand it. All the currently running modules are displayed.

If you recently deployed new modules to a device, hover over the Azure IoT Hub Devices section header and select the refresh icon to update the view.

Right-click the name of a module to view and edit the module twin.