OPC UA servers are software applications that communicate with assets. OPC UA servers expose OPC UA data points that represent data points. OPC UA data points provide real-time or historical data about the status, performance, quality, or condition of assets.
An asset in Azure IoT Operations is a logical entity that you create to represent a physical asset or device. An Azure IoT Operations asset can have custom properties, data points, streams, and events that describe its behavior and characteristics. An asset is associated with one or more devices. Azure IoT Operations stores asset definitions in the Azure Device Registry.
A device in Azure IoT Operations is a logical entity that defines the connections to physical assets or devices. Without a device, data can't flow from a physical device or asset to the MQTT broker. When you configure a device and asset, a connection is established to the physical asset or device and data point values, events, and streams arrive in Azure IoT Operations instance. A device has one or more inbound endpoints. Azure IoT Operations stores device definitions in the Azure Device Registry.
This article describes how to use the operations experience web UI and the Azure CLI to:
- Define the devices that connect OPC UA servers to your Azure IoT Operations instance.
- Add assets, and define their data points and events to enable data flow from OPC UA servers to the MQTT broker.
These assets, data points, and events map inbound data from OPC UA servers to friendly names that you can use in the MQTT broker and data flows.
The connector can use anonymous or username password user authentication when it connects to an OPC UA server.
Note
This user authentication is separate from the certificate-based application authentication that's used to establish a secure channel between the connector for OPC UA and the OPC UA server. To learn more, see Understand the OPC UA certificates infrastructure.
Prerequisites
To configure devices and assets, you need an instance of Azure IoT Operations.
To sign in to the operations experience web UI, you need a Microsoft Entra ID account with at least contributor permissions for the resource group that contains your Kubernetes - Azure Arc instance. You can't sign in with a Microsoft account (MSA). For more information, see Troubleshoot access to the operations experience web UI.
Your IT administrator must configure the OPC UA connector template for your Azure IoT Operations instance in the Azure portal.
An OPC UA server that you can reach from your Azure IoT Operations cluster. If you don't have an OPC UA server, use the OPC PLC simulator from the Azure IoT Operations samples repository.
To manage the trusted certificates list the connector uses to secure connections to external endpoints, see Manage certificates for external communications.
Create a device
An Azure IoT Operations deployment can include a sample OPC PLC simulator. To create a device that uses the OPC PLC simulator:
Select devices and then Create device:
Tip
Use the filter box to search for devices.
On the Basics page, enter a device name and select New on the Microsoft.OpcUa tile to add an endpoint for the device:
Enter your endpoint information. For example, to use the OPC PLC simulator, enter the following values:
| Field |
Value |
| Name |
opc-ua-connector-0 |
| Connector for OPC UA URL |
opc.tcp://opcplc-000000:50000 |
| User authentication |
Anonymous |
Select Next. On the Additional Info page enter any custom properties for the device.
Select Next to review your device details. Then select Create.
Run the following commands:
az iot ops ns device create \
-n opc-ua-connector-cli \
-g {your resource group name} \
--instance {your instance name}
az iot ops ns device endpoint inbound add opcua \
--device opc-ua-connector-cli \
-g {your resource group name} \
-i {your instance name} \
--name opc-ua-connector-0 \
--endpoint-address "opc.tcp://opcplc-000000:50000"
To learn more, see az iot ops ns device.
Deploy the following Bicep template to create a device with an inbound endpoint for the OPC UA connector. Replace the placeholders <AIO_NAMESPACE_NAME> and <CUSTOM_LOCATION_NAME> with your Azure IoT Operations namespace name and custom location name respectively:
param aioNamespaceName string = '<AIO_NAMESPACE_NAME>'
param customLocationName string = '<CUSTOM_LOCATION_NAME>'
resource namespace 'Microsoft.DeviceRegistry/namespaces@2025-10-01' existing = {
name: aioNamespaceName
}
resource customLocation 'Microsoft.ExtendedLocation/customLocations@2021-08-31-preview' existing = {
name: customLocationName
}
resource device 'Microsoft.DeviceRegistry/namespaces/devices@2025-10-01' = {
name: 'opc-ua-connector-bicep'
parent: namespace
location: resourceGroup().location
extendedLocation: {
type: 'CustomLocation'
name: customLocation.id
}
properties: {
endpoints: {
outbound: {
assigned: {}
}
inbound: {
'opc-ua-connector-0': {
endpointType: 'Microsoft.OpcUa'
address: 'opc.tcp://opcplc-000000:50000'
authentication: {
method: 'Anonymous'
}
}
}
}
}
}
This configuration deploys a new device resource called opc-ua-connector-bicep to the cluster with an inbound endpoint called opc-ua-connector-0.
When the OPC PLC simulator is running, data flows from the simulator, to the connector for OPC UA, and then to the MQTT broker.
The previous example uses the Anonymous authentication mode. This mode doesn't require a username or password.
To use the UsernamePassword authentication mode, complete the following steps:
Follow the steps in Manage secrets for your Azure IoT Operations deployment to add secrets for username and password in Azure Key Vault, and project them into Kubernetes cluster.
Modify the authentication block of your Bicep configuration for the connector to reference the synchronized secrets for username and password, as shown in the example below:
authentication: {
method: 'UsernamePassword'
usernamePasswordCredentials: {
passwordSecretName: '<reference to synced password secret>'
usernameSecretName: '<reference to synced username secret>'
}
}
Other security options
When you create the inbound endpoint, you can also select:
| Option |
Type |
Description |
| Auto accept untrusted server certificate |
Yes/No |
Automatically accept untrusted server certificates |
| Security policy |
Dropdown |
Security policy used to establish secure channel with the OPC UA server |
| Security mode |
Dropdown |
Security mode used to communicate within secure channel with the OPC UA server |
Add an asset, dataset, and data points
To add an asset in the operations experience, follow these steps:
Select the Assets tab. Before you create any assets, you see the following screen:
Tip
Use the filter box to search for assets.
Select Create asset.
On the asset details screen, enter the following asset information:
- Inbound endpoint. Select your device inbound endpoint from the list.
- Asset name
- Description
Configure the set of custom properties that you want to associate with the asset. You can accept the default list of properties or add your own. The following properties are available by default:
- Manufacturer
- Manufacturer URI
- Model
- Product code
- Hardware version
- Software version
- Serial number
- Documentation URI
Select Next to go to the Datasets page.
Add a dataset to an asset
A dataset defines where the connector sends the data it collects from a collection of data points. An OPC UA asset can have multiple datasets. To create a dataset:
Select Create dataset.
Enter the details for the dataset such as its name and destination. For OPC UA assets, the destination is an MQTT topic. For example:
Use the Start instance field to specify the starting node for resolving relative browse paths for data points in the dataset. For more information, see Resolve nodes dynamically using browse paths.
Select Create and next to create the dataset.
Tip
Use the Manage default settings option to configure default dataset settings such as publishing interval, sampling interval, and queue size.
Add individual data points to a dataset
Important
The data point name _ErrorMessage is reserved and shouldn't be used.
Now you can define the data points associated with the dataset. To add OPC UA data points:
Select Add data point.
Enter your data point details:
- Data source. This value is the node ID from the OPC UA server.
- Data point name (Optional). This value is the friendly name that you want to use for the data point. If you don't specify a data point name, the node ID is used as the data point name.
- Sampling interval (milliseconds). You can override the default value for this data point.
- Queue size. You can override the default value for this data point.
The following table shows some example data point values that you can use with the built-in OPC PLC simulator:
| Data source |
Data point name |
| ns=3;s=FastUInt10 |
Temperature |
| ns=3;s=FastUInt100 |
Humidity |
On the data points page, select Next to go to the Add events page.
Use the following commands to add a thermostat asset to your device by using the Azure CLI. The commands add a dataset and two data points to the asset by using the point add command:
# Create the asset
az iot ops ns asset opcua create \
--name thermostat \
--instance {your instance name} \
-g {your resource group name} \
--device opc-ua-connector-cli \
--endpoint opc-ua-connector-0 \
--description 'A simulated thermostat asset'
# Add the dataset
az iot ops ns asset opcua dataset add \
--asset thermostat \
--instance {your instance name} \
-g {your resource group name} \
--name oven \
--data-source "" \
--dest topic="azure-iot-operations/data/thermostat" retain=Never qos=Qos1 ttl=3600
# Add the data points
az iot ops ns asset opcua datapoint add \
--asset thermostat \
--instance {your instance name} \
-g {your resource group name} \
--dataset oven \
--name temperature \
--data-source "ns=3;s=FastUInt10"
az iot ops ns asset opcua datapoint add \
--asset thermostat \
--instance {your instance name} \
-g {your resource group name} \
--dataset oven \
--name humidity \
--data-source "ns=3;s=FastUInt100"
# Show the dataset and datapoints
az iot ops ns asset opcua dataset show \
--asset thermostat \
-n oven \
-g {your resource group name} \
--instance {your instance name}
When you create an asset by using the Azure CLI, you can define:
- Multiple data points by using the
point add command multiple times.
- Multiple events by using the
--event parameter multiple times.
- Optional information for the asset such as:
- Manufacturer
- Manufacturer URI
- Model
- Product code
- Hardware version
- Software version
- Serial number
- Documentation URI
- Default values for sampling interval, publishing interval, and queue size.
- Datapoint specific values for sampling interval, publishing interval, and queue size.
- Event specific values for sampling publishing interval, and queue size.
- The observability mode for each data point and event
Deploy the following Bicep template to create an asset that publishes messages from the device shown previously to an MQTT topic. Replace the placeholders <AIO_NAMESPACE_NAME> and <CUSTOM_LOCATION_NAME> with your Azure IoT Operations namespace name and custom location name respectively:
param aioNamespaceName string = '<AIO_NAMESPACE_NAME>'
param customLocationName string = '<CUSTOM_LOCATION_NAME>'
resource namespace 'Microsoft.DeviceRegistry/namespaces@2025-10-01' existing = {
name: aioNamespaceName
}
resource customLocation 'Microsoft.ExtendedLocation/customLocations@2021-08-31-preview' existing = {
name: customLocationName
}
resource asset 'Microsoft.DeviceRegistry/namespaces/assets@2025-10-01' = {
name: 'thermostat'
parent: namespace
location: resourceGroup().location
extendedLocation: {
type: 'CustomLocation'
name: customLocation.id
}
properties: {
displayName: 'thermostat'
description: 'A simulated thermostat asset'
enabled: true
deviceRef: {
deviceName: 'opc-ua-connector-bicep'
endpointName: 'opc-ua-connector-0'
}
defaultDatasetsConfiguration: '{}'
defaultEventsConfiguration: '{}'
datasets: [
{
name: 'oven'
datasetConfiguration: '{}'
dataPoints: [
{
name: 'temperature'
dataSource: 'ns=3;s=FastUInt10'
dataPointConfiguration: '{}'
}
{
name: 'humidity'
dataSource: 'ns=3;s=FastUInt100'
dataPointConfiguration: '{}'
}
]
destinations: [
{
target: 'Mqtt'
configuration: {
topic: 'azure-iot-operations/data/thermostat'
qos: 'Qos1'
retain: 'Never'
ttl: 3600
}
}
]
}
]
}
}
Add events and event groups
Add an event group to an asset
An event group defines where the connector sends the data it receives from a collection of events. An OPC UA asset can have multiple event groups. To create an event group:
Select Create event group.
Enter a name for the event group and any other required details:
Select Create and next to create the event group and go to the List of events for alerts page.
Add events to an event group
Now you can define the events associated with the event group. To add OPC UA events:
Select Add event.
Enter your event details:
- Data source. This value is the event notifier from the OPC UA server.
- Event name (Optional). This value is the friendly name that you want to use for the event. If you don't specify an event name, the event notifier is used as the event name.
- Topic. The MQTT topic that you want the event to be published to.
- Sampling interval (milliseconds). You can override the default value for this data point.
- Queue size. You can override the default value for this data point.
- Start instance. This value is the starting node for resolving relative browse paths for this event. This field is required if you use relative browse paths in the Data source field. For more information, see Resolve nodes dynamically using browse paths.
- Event filter. An optional configuration that defines the event filter for this event. For more information, see the Event filters section.
Select Manage default settings to configure default event settings for the asset. These settings apply to all the OPC UA events that belong to the asset. You can override these settings for each event that you add. Default event settings include:
- Publishing interval (milliseconds): The rate at which OPC UA server should publish data.
- Queue size: The depth of the queue to hold the sampling data before publishing it.
To add an event group and events to an existing asset, use the az iot ops ns asset opcua event-group and az iot ops ns asset custom event commands:
# Add an event group to the thermostat asset
az iot ops ns asset opcua event-group add \
--data-source "" \
--asset thermostat \
--instance {your instance name} \
-g {your resource group name} \
--name alerts
# Add an event to the event group
az iot ops ns asset custom event add \
--asset thermostat \
--instance {your instance name} \
-g {your resource group name} \
--event-group alerts \
--name serverObjectNotifier \
--data-source "ns=0;i=2253" \
--dest topic="azure-iot-operations/events/test-thermostat-cli" retain=Never qos=Qos1 ttl=3600
# List the event groups for the asset
az iot ops ns asset opcua event-group list \
--asset thermostat \
--instance {your instance name} \
-g {your resource group name}
When you add an event group by using the Azure CLI, you can configure:
- Event group name and data source
- Publishing interval and queue size
- Event destinations (MQTT topic, QoS, retain, TTL)
To add individual events to an event group, use the az iot ops ns asset custom event add command with the --event-group parameter.
To remove an event group, use the az iot ops ns asset opcua event-group remove command.
To add events and event groups to an asset by using Bicep, include the eventGroups array in the asset properties. Each event group can contain an events array with individual events:
eventGroups: [
{
name: 'alerts'
eventGroupConfiguration: '{"publishingInterval":1000,"queueSize":10}'
events: [
{
name: 'serverObjectNotifier'
dataSource: 'ns=0;i=2253'
eventConfiguration: '{}'
destinations: [
{
target: 'Mqtt'
configuration: {
topic: 'azure-iot-operations/events/test-thermostat-bicep'
qos: 'Qos1'
retain: 'Never'
ttl: 3600
}
}
]
}
]
}
]
The eventGroupConfiguration property is a stringified JSON object that can include connector-specific settings such as publishingInterval and queueSize. Individual events use the eventConfiguration property for event-specific settings including per-event destinations.
Event filters
Define event filters to customize the information included in event notifications from the server. By default, the server sends a selection of standard fields in event notifications. The server determines the exact selection for each event type. For example:
{
"EventId":"OkaXYhfr20yUoj1QBbzcIg==",
"EventType":"i=2130",
"SourceNode":"i=2253",
"SourceName":"WestTank",
"Time":"2025-10-10T15:09:13.3946878Z",
"ReceiveTime":"2025-10-10T15:09:13.3946881Z",
"Message":"Raising Events",
"Severity":500
}
Use an event filter to:
- Include extra fields in event notifications.
- Exclude fields from event notifications.
- Modify field names in event notifications.
The following screenshot shows an example event filter:
The following command updates an existing event definition to include an event filter by using the config parameter:
az iot ops ns asset custom event add \
--asset thermostat \
--instance {your instance name} \
-g {your resource group name} \
--event-group alerts \
--name serverObjectNotifier \
--data-source "ns=0;i=2253" \
--dest topic="azure-iot-operations/events/test-thermostat-cli" retain=Never qos=Qos1 ttl=3600 \
--replace true \
--config "{\"eventFilter\":{\"selectClauses\":[{\"browsePath\":\"EventId\",\"typeDefinitionId\":\"ns=0;i=2041\",\"fieldId\":\"myEventId\"},{\"browsePath\":\"EventType\",\"typeDefinitionId\":\"ns=0;i=2041\",\"fieldId\":\"EventType\"},{\"browsePath\":\"SourceName\",\"typeDefinitionId\":\"\",\"fieldId\":\"mySourceName\"},{\"browsePath\":\"Severity\",\"typeDefinitionId\":\"\",\"fieldId\":\"Severity\"}]}}"
To configure event filters by using Bicep, include the filter configuration in the eventConfiguration property of individual events within an event group:
eventGroups: [
{
name: 'alerts'
eventGroupConfiguration: '{"publishingInterval":1000,"queueSize":10}'
events: [
{
name: 'serverObjectNotifier'
dataSource: 'ns=0;i=2253'
eventConfiguration: '{"eventFilter":{"selectClauses":[{"browsePath":"EventId","typeDefinitionId":"ns=0;i=2041","fieldId":"myEventId"},{"browsePath":"EventType","typeDefinitionId":"ns=0;i=2041","fieldId":"EventType"},{"browsePath":"SourceName","typeDefinitionId":"","fieldId":"mySourceName"},{"browsePath":"Severity","typeDefinitionId":"","fieldId":"Severity"}]}}'
destinations: [
{
target: 'Mqtt'
configuration: {
topic: 'azure-iot-operations/events/test-thermostat-bicep'
qos: 'Qos1'
retain: 'Never'
ttl: 3600
}
}
]
}
]
}
]
The selectClauses array defines which fields to include in the event notification and optionally renames them using the alias property.
The complete event filter shown previously defines four output fields:
| Browse path |
Type definition ID |
Field ID |
EventId |
ns=0;i=2041 |
myEventId |
EventType |
ns=0;i=2041 |
blank |
SourceName |
blank |
mySourceName |
Severity |
blank |
blank |
The three properties for a filter row are:
- Browse path. Required value that identifies the source field to include in the forwarded event notification.
- Type definition ID. Optional value that specifies the OPC UA type definition of the source field.
- Field ID. Optional value that specifies the name to use for the field in the forwarded event notification. If you don't specify a field ID, the original field name is used.
The resulting message forwarded by the connector now looks like the following example:
{
"myEventId":"OkaXYhfr20yUoj1QBbzcIg==",
"EventType":"i=2130",
"mySourceName":"WestTank",
"Severity":500
}
Review your changes
Review your asset and OPC UA data point and event details. Make any adjustments you need:
To review your asset configuration, use the following commands:
# View the complete asset details
az iot ops ns asset show \
--name thermostat \
--instance {your instance name} \
-g {your resource group name}
# List datasets and data points
az iot ops ns asset opcua dataset list \
--asset thermostat \
--instance {your instance name} \
-g {your resource group name}
# List event groups
az iot ops ns asset opcua event-group list \
--asset thermostat \
--instance {your instance name} \
-g {your resource group name}
To review your Bicep template before deployment, use the what-if operation:
az deployment group what-if --resource-group {your resource group name} --template-file asset.bicep
This command shows you what changes would be made to your Azure resources without actually deploying them.
Add management groups and actions
A management group is a logical grouping of actions that you can invoke against an OPC UA asset, such as writing a value to a tag or calling a method. Actions must belong to a management group.
To create a management group and define actions for it, see Control OPC UA servers. That article explains the different types of actions (simple writes, complex writes, and method calls) and the MQTT topics you use to invoke them.
Update an asset
Find and select the asset you created previously. Use the Asset details, data points, and Events tabs to make any changes:
On the view data points tab for a dataset, you can add data points, update existing data points, or remove data points.
To update a data point, select an existing data point and update the data point information. Then select Update:
To remove data points, select one or more data points and then select Remove data points:
You can also add, update, and delete events and properties in the same way.
When you're finished making changes, select Save to save your changes.
To list your assets associated with a specific endpoint, use the following command:
az iot ops ns asset query \
--device {your device name} \
--endpoint {your endpoint name} \
-g {your resource group name} \
--instance {your instance name}
Tip
You can refine the query command to search for assets that match specific criteria. For example, you can search for assets by manufacturer.
To view the details of the thermostat asset, use the following command:
az iot ops ns asset show \
--name thermostat \
--instance {your instance name} \
-g {your resource group}
To update an asset, use the az iot ops ns asset opcua update command. For example, to update the asset's description, use a command like the following example:
az iot ops ns asset opcua update \
--name thermostat \
--instance {your instance name} \
-g {your resource group} \
--description "Updated factory PLC"
To list the thermostat asset's data points in a dataset, use the following command:
az iot ops ns asset opcua dataset show \
--asset thermostat \
--name oven \
-g {your resource group} \
--instance {your instance name}
To list the thermostat asset's event groups, use the following command:
az iot ops ns asset opcua event-group list \
--asset thermostat \
-g {your resource group} \
--instance {your instance name}
To add a new data point to the thermostat asset, use a command like the following example:
az iot ops ns asset opcua datapoint add \
--asset thermostat \
--instance {your instance name} \
-g {your resource group name} \
--dataset oven \
--name humidity \
--data-source "ns=3;s=FastUInt100"
To delete a data point, use the az iot ops ns asset opcua dataset point remove command.
You can manage an asset's event groups by using the az iot ops ns asset opcua event-group commands.
To retrieve an asset by using Bicep, use a template like the following example:
param aioNamespaceName string = '<AIO_NAMESPACE_NAME>'
resource namespace 'Microsoft.DeviceRegistry/namespaces@2025-10-01' existing = {
name: aioNamespaceName
}
resource asset 'Microsoft.DeviceRegistry/namespaces/assets@2025-10-01' existing = {
name: 'thermostat'
parent: namespace
}
output asset object = asset
To update an existing asset, for example to modify the description and add a data point, use a template like the following example:
param aioNamespaceName string = '<AIO_NAMESPACE_NAME>'
param customLocationName string = '<CUSTOM_LOCATION_NAME>'
resource namespace 'Microsoft.DeviceRegistry/namespaces@2025-10-01' existing = {
name: aioNamespaceName
}
resource customLocation 'Microsoft.ExtendedLocation/customLocations@2021-08-31-preview' existing = {
name: customLocationName
}
resource asset 'Microsoft.DeviceRegistry/namespaces/assets@2025-10-01' = {
name: 'thermostat'
parent: namespace
location: resourceGroup().location
extendedLocation: {
type: 'CustomLocation'
name: customLocation.id
}
properties: {
displayName: 'thermostat'
description: 'Updated thermostat asset with voltage data point'
enabled: true
deviceRef: {
deviceName: 'opc-ua-connector-bicep'
endpointName: 'opc-ua-connector-0'
}
defaultDatasetsConfiguration: '{}'
defaultEventsConfiguration: '{}'
datasets: [
{
name: 'oven'
datasetConfiguration: '{}'
dataPoints: [
{
name: 'temperature'
dataSource: 'ns=3;s=FastUInt10'
dataPointConfiguration: '{}'
}
{
name: 'humidity'
dataSource: 'ns=3;s=FastUInt100'
dataPointConfiguration: '{}'
}
{
name: 'voltage'
dataSource: 'ns=3;s=FastUInt101'
dataPointConfiguration: '{}'
}
]
destinations: [
{
target: 'Mqtt'
configuration: {
topic: 'azure-iot-operations/data/thermostat'
qos: 'Qos1'
retain: 'Never'
ttl: 3600
}
}
]
}
]
}
}
Delete an asset
To delete an asset, select the asset you want to delete. On the Asset details page, select Delete. Confirm your changes to delete the asset:
To delete an asset, use a command that looks like the following example:
az iot ops ns asset delete \
--name thermostat \
-g {your resource group name} \
--instance {your instance name}
Related content