Configure Azure IoT Operations Dataflow Profiles

The azure-native:iotoperations:DataflowProfile resource, part of the Pulumi Azure Native provider, defines a dataflow profile that manages data routing instances within an Azure IoT Operations deployment. This guide focuses on two capabilities: instance count configuration for scaling and diagnostics setup for logs and metrics.

Dataflow profiles belong to an IoT Operations instance and run in an Azure Arc custom location. The examples are intentionally small. Combine them with your own IoT Operations instance, custom location, and dataflow definitions.

Create a minimal dataflow profile with single instance

Most deployments start with a single profile instance to handle data movement between sources and destinations.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const dataflowProfile = new azure_native.iotoperations.DataflowProfile("dataflowProfile", {
    dataflowProfileName: "aio-dataflowprofile",
    extendedLocation: {
        name: "qmbrfwcpwwhggszhrdjv",
        type: azure_native.iotoperations.ExtendedLocationType.CustomLocation,
    },
    instanceName: "resource-name123",
    properties: {
        instanceCount: 1,
    },
    resourceGroupName: "rgiotoperations",
});
import pulumi
import pulumi_azure_native as azure_native

dataflow_profile = azure_native.iotoperations.DataflowProfile("dataflowProfile",
    dataflow_profile_name="aio-dataflowprofile",
    extended_location={
        "name": "qmbrfwcpwwhggszhrdjv",
        "type": azure_native.iotoperations.ExtendedLocationType.CUSTOM_LOCATION,
    },
    instance_name="resource-name123",
    properties={
        "instance_count": 1,
    },
    resource_group_name="rgiotoperations")
package main

import (
	iotoperations "github.com/pulumi/pulumi-azure-native-sdk/iotoperations/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := iotoperations.NewDataflowProfile(ctx, "dataflowProfile", &iotoperations.DataflowProfileArgs{
			DataflowProfileName: pulumi.String("aio-dataflowprofile"),
			ExtendedLocation: &iotoperations.ExtendedLocationArgs{
				Name: pulumi.String("qmbrfwcpwwhggszhrdjv"),
				Type: pulumi.String(iotoperations.ExtendedLocationTypeCustomLocation),
			},
			InstanceName: pulumi.String("resource-name123"),
			Properties: &iotoperations.DataflowProfilePropertiesArgs{
				InstanceCount: pulumi.Int(1),
			},
			ResourceGroupName: pulumi.String("rgiotoperations"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var dataflowProfile = new AzureNative.IoTOperations.DataflowProfile("dataflowProfile", new()
    {
        DataflowProfileName = "aio-dataflowprofile",
        ExtendedLocation = new AzureNative.IoTOperations.Inputs.ExtendedLocationArgs
        {
            Name = "qmbrfwcpwwhggszhrdjv",
            Type = AzureNative.IoTOperations.ExtendedLocationType.CustomLocation,
        },
        InstanceName = "resource-name123",
        Properties = new AzureNative.IoTOperations.Inputs.DataflowProfilePropertiesArgs
        {
            InstanceCount = 1,
        },
        ResourceGroupName = "rgiotoperations",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.iotoperations.DataflowProfile;
import com.pulumi.azurenative.iotoperations.DataflowProfileArgs;
import com.pulumi.azurenative.iotoperations.inputs.ExtendedLocationArgs;
import com.pulumi.azurenative.iotoperations.inputs.DataflowProfilePropertiesArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var dataflowProfile = new DataflowProfile("dataflowProfile", DataflowProfileArgs.builder()
            .dataflowProfileName("aio-dataflowprofile")
            .extendedLocation(ExtendedLocationArgs.builder()
                .name("qmbrfwcpwwhggszhrdjv")
                .type("CustomLocation")
                .build())
            .instanceName("resource-name123")
            .properties(DataflowProfilePropertiesArgs.builder()
                .instanceCount(1)
                .build())
            .resourceGroupName("rgiotoperations")
            .build());

    }
}
resources:
  dataflowProfile:
    type: azure-native:iotoperations:DataflowProfile
    properties:
      dataflowProfileName: aio-dataflowprofile
      extendedLocation:
        name: qmbrfwcpwwhggszhrdjv
        type: CustomLocation
      instanceName: resource-name123
      properties:
        instanceCount: 1
      resourceGroupName: rgiotoperations

The instanceCount property controls how many profile instances run concurrently. The extendedLocation binds the profile to an Azure Arc custom location where the IoT Operations instance runs. The instanceName references the parent IoT Operations instance that owns this profile.

Scale to multiple profile instances for throughput

As data volumes grow, teams increase the instance count to handle higher message throughput.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const dataflowProfile = new azure_native.iotoperations.DataflowProfile("dataflowProfile", {
    dataflowProfileName: "aio-dataflowprofile",
    extendedLocation: {
        name: "qmbrfwcpwwhggszhrdjv",
        type: azure_native.iotoperations.ExtendedLocationType.CustomLocation,
    },
    instanceName: "resource-name123",
    properties: {
        instanceCount: 3,
    },
    resourceGroupName: "rgiotoperations",
});
import pulumi
import pulumi_azure_native as azure_native

dataflow_profile = azure_native.iotoperations.DataflowProfile("dataflowProfile",
    dataflow_profile_name="aio-dataflowprofile",
    extended_location={
        "name": "qmbrfwcpwwhggszhrdjv",
        "type": azure_native.iotoperations.ExtendedLocationType.CUSTOM_LOCATION,
    },
    instance_name="resource-name123",
    properties={
        "instance_count": 3,
    },
    resource_group_name="rgiotoperations")
package main

import (
	iotoperations "github.com/pulumi/pulumi-azure-native-sdk/iotoperations/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := iotoperations.NewDataflowProfile(ctx, "dataflowProfile", &iotoperations.DataflowProfileArgs{
			DataflowProfileName: pulumi.String("aio-dataflowprofile"),
			ExtendedLocation: &iotoperations.ExtendedLocationArgs{
				Name: pulumi.String("qmbrfwcpwwhggszhrdjv"),
				Type: pulumi.String(iotoperations.ExtendedLocationTypeCustomLocation),
			},
			InstanceName: pulumi.String("resource-name123"),
			Properties: &iotoperations.DataflowProfilePropertiesArgs{
				InstanceCount: pulumi.Int(3),
			},
			ResourceGroupName: pulumi.String("rgiotoperations"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var dataflowProfile = new AzureNative.IoTOperations.DataflowProfile("dataflowProfile", new()
    {
        DataflowProfileName = "aio-dataflowprofile",
        ExtendedLocation = new AzureNative.IoTOperations.Inputs.ExtendedLocationArgs
        {
            Name = "qmbrfwcpwwhggszhrdjv",
            Type = AzureNative.IoTOperations.ExtendedLocationType.CustomLocation,
        },
        InstanceName = "resource-name123",
        Properties = new AzureNative.IoTOperations.Inputs.DataflowProfilePropertiesArgs
        {
            InstanceCount = 3,
        },
        ResourceGroupName = "rgiotoperations",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.iotoperations.DataflowProfile;
import com.pulumi.azurenative.iotoperations.DataflowProfileArgs;
import com.pulumi.azurenative.iotoperations.inputs.ExtendedLocationArgs;
import com.pulumi.azurenative.iotoperations.inputs.DataflowProfilePropertiesArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var dataflowProfile = new DataflowProfile("dataflowProfile", DataflowProfileArgs.builder()
            .dataflowProfileName("aio-dataflowprofile")
            .extendedLocation(ExtendedLocationArgs.builder()
                .name("qmbrfwcpwwhggszhrdjv")
                .type("CustomLocation")
                .build())
            .instanceName("resource-name123")
            .properties(DataflowProfilePropertiesArgs.builder()
                .instanceCount(3)
                .build())
            .resourceGroupName("rgiotoperations")
            .build());

    }
}
resources:
  dataflowProfile:
    type: azure-native:iotoperations:DataflowProfile
    properties:
      dataflowProfileName: aio-dataflowprofile
      extendedLocation:
        name: qmbrfwcpwwhggszhrdjv
        type: CustomLocation
      instanceName: resource-name123
      properties:
        instanceCount: 3
      resourceGroupName: rgiotoperations

Setting instanceCount to 3 runs three profile instances in parallel, distributing data processing load across them. Each instance operates independently, increasing overall throughput capacity.

Enable diagnostics with logs and metrics

Production deployments require observability to monitor dataflow health and troubleshoot issues.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const dataflowProfile = new azure_native.iotoperations.DataflowProfile("dataflowProfile", {
    dataflowProfileName: "resource-name123",
    extendedLocation: {
        name: "qmbrfwcpwwhggszhrdjv",
        type: azure_native.iotoperations.ExtendedLocationType.CustomLocation,
    },
    instanceName: "resource-name123",
    properties: {
        diagnostics: {
            logs: {
                level: "rnmwokumdmebpmfxxxzvvjfdywotav",
            },
            metrics: {
                prometheusPort: 7581,
            },
        },
        instanceCount: 14,
    },
    resourceGroupName: "rgiotoperations",
});
import pulumi
import pulumi_azure_native as azure_native

dataflow_profile = azure_native.iotoperations.DataflowProfile("dataflowProfile",
    dataflow_profile_name="resource-name123",
    extended_location={
        "name": "qmbrfwcpwwhggszhrdjv",
        "type": azure_native.iotoperations.ExtendedLocationType.CUSTOM_LOCATION,
    },
    instance_name="resource-name123",
    properties={
        "diagnostics": {
            "logs": {
                "level": "rnmwokumdmebpmfxxxzvvjfdywotav",
            },
            "metrics": {
                "prometheus_port": 7581,
            },
        },
        "instance_count": 14,
    },
    resource_group_name="rgiotoperations")
package main

import (
	iotoperations "github.com/pulumi/pulumi-azure-native-sdk/iotoperations/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := iotoperations.NewDataflowProfile(ctx, "dataflowProfile", &iotoperations.DataflowProfileArgs{
			DataflowProfileName: pulumi.String("resource-name123"),
			ExtendedLocation: &iotoperations.ExtendedLocationArgs{
				Name: pulumi.String("qmbrfwcpwwhggszhrdjv"),
				Type: pulumi.String(iotoperations.ExtendedLocationTypeCustomLocation),
			},
			InstanceName: pulumi.String("resource-name123"),
			Properties: &iotoperations.DataflowProfilePropertiesArgs{
				Diagnostics: &iotoperations.ProfileDiagnosticsArgs{
					Logs: &iotoperations.DiagnosticsLogsArgs{
						Level: pulumi.String("rnmwokumdmebpmfxxxzvvjfdywotav"),
					},
					Metrics: &iotoperations.MetricsArgs{
						PrometheusPort: pulumi.Int(7581),
					},
				},
				InstanceCount: pulumi.Int(14),
			},
			ResourceGroupName: pulumi.String("rgiotoperations"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var dataflowProfile = new AzureNative.IoTOperations.DataflowProfile("dataflowProfile", new()
    {
        DataflowProfileName = "resource-name123",
        ExtendedLocation = new AzureNative.IoTOperations.Inputs.ExtendedLocationArgs
        {
            Name = "qmbrfwcpwwhggszhrdjv",
            Type = AzureNative.IoTOperations.ExtendedLocationType.CustomLocation,
        },
        InstanceName = "resource-name123",
        Properties = new AzureNative.IoTOperations.Inputs.DataflowProfilePropertiesArgs
        {
            Diagnostics = new AzureNative.IoTOperations.Inputs.ProfileDiagnosticsArgs
            {
                Logs = new AzureNative.IoTOperations.Inputs.DiagnosticsLogsArgs
                {
                    Level = "rnmwokumdmebpmfxxxzvvjfdywotav",
                },
                Metrics = new AzureNative.IoTOperations.Inputs.MetricsArgs
                {
                    PrometheusPort = 7581,
                },
            },
            InstanceCount = 14,
        },
        ResourceGroupName = "rgiotoperations",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.iotoperations.DataflowProfile;
import com.pulumi.azurenative.iotoperations.DataflowProfileArgs;
import com.pulumi.azurenative.iotoperations.inputs.ExtendedLocationArgs;
import com.pulumi.azurenative.iotoperations.inputs.DataflowProfilePropertiesArgs;
import com.pulumi.azurenative.iotoperations.inputs.ProfileDiagnosticsArgs;
import com.pulumi.azurenative.iotoperations.inputs.DiagnosticsLogsArgs;
import com.pulumi.azurenative.iotoperations.inputs.MetricsArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var dataflowProfile = new DataflowProfile("dataflowProfile", DataflowProfileArgs.builder()
            .dataflowProfileName("resource-name123")
            .extendedLocation(ExtendedLocationArgs.builder()
                .name("qmbrfwcpwwhggszhrdjv")
                .type("CustomLocation")
                .build())
            .instanceName("resource-name123")
            .properties(DataflowProfilePropertiesArgs.builder()
                .diagnostics(ProfileDiagnosticsArgs.builder()
                    .logs(DiagnosticsLogsArgs.builder()
                        .level("rnmwokumdmebpmfxxxzvvjfdywotav")
                        .build())
                    .metrics(MetricsArgs.builder()
                        .prometheusPort(7581)
                        .build())
                    .build())
                .instanceCount(14)
                .build())
            .resourceGroupName("rgiotoperations")
            .build());

    }
}
resources:
  dataflowProfile:
    type: azure-native:iotoperations:DataflowProfile
    properties:
      dataflowProfileName: resource-name123
      extendedLocation:
        name: qmbrfwcpwwhggszhrdjv
        type: CustomLocation
      instanceName: resource-name123
      properties:
        diagnostics:
          logs:
            level: rnmwokumdmebpmfxxxzvvjfdywotav
          metrics:
            prometheusPort: 7581
        instanceCount: 14
      resourceGroupName: rgiotoperations

The diagnostics block configures observability. The logs section sets the logging level for structured log output. The metrics section exposes Prometheus-compatible metrics on the specified port, allowing monitoring systems to scrape profile health data.

Beyond these examples

These snippets focus on specific dataflow profile features: instance count scaling and diagnostics and observability. They’re intentionally minimal rather than full data routing solutions.

The examples reference pre-existing infrastructure such as Azure IoT Operations instances, Azure Arc custom locations, and resource groups. They focus on configuring the profile rather than provisioning the surrounding IoT Operations environment.

To keep things focused, common dataflow patterns are omitted, including:

  • Dataflow definitions (separate Dataflow resources)
  • Endpoint configurations (separate DataflowEndpoint resources)
  • Authentication and authorization settings
  • Network policies and connectivity rules

These omissions are intentional: the goal is to illustrate how each profile feature is wired, not provide drop-in IoT Operations modules. See the DataflowProfile resource reference for all available configuration options.

Let's configure Azure IoT Operations Dataflow Profiles

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Configuration & Setup
What's the minimal configuration needed to create a DataflowProfile?
You need four required properties: extendedLocation (with type CustomLocation), instanceName, resourceGroupName, and properties.instanceCount.
What is extendedLocation and why is it required?
extendedLocation specifies the edge location of the resource and must be type CustomLocation. It’s a required property for all DataflowProfile resources.
What does instanceCount control?
instanceCount controls the number of dataflow profile instances. Examples show values of 1 (minimal), 3 (multi-instance), and 14 (full configuration).
Immutability & Updates
What properties can't be changed after creating a DataflowProfile?
Four properties are immutable: extendedLocation, dataflowProfileName, instanceName, and resourceGroupName. Changes to these require recreating the resource.
Advanced Features
How do I configure diagnostics for my DataflowProfile?
Add the optional diagnostics property with logs.level for logging and metrics.prometheusPort for Prometheus metrics collection.
API Versions & Import
How do I use a different Azure API version for this resource?
Generate a local SDK package using pulumi package add azure-native iotoperations [ApiVersion]. Available versions include 2024-08-15-preview through 2025-10-01.
How do I import an existing DataflowProfile?
Use pulumi import azure-native:iotoperations:DataflowProfile <name> /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.IoTOperations/instances/{instanceName}/dataflowProfiles/{dataflowProfileName}.

Using a different cloud?

Explore integration guides for other cloud providers: