Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions blueprints/full-single-node-cluster/bicep/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,13 @@ Deploys a complete end-to-end environment for Azure IoT Operations on a single-n
| vpnGatewayAzureAdConfig | Azure AD authentication configuration for VPN Gateway. | `[_1.AzureAdConfig](#user-defined-types)` | [variables('_1.azureAdConfigDefaults')] | no |
| shouldCreateAks | Whether to create an Azure Kubernetes Service cluster. | `bool` | `false` | no |
| customLocationsOid | The object id of the Custom Locations Entra ID application for your tenant.<br>Can be retrieved using:<br><br> <pre><code class="language-sh"> az ad sp show --id bc313c14-388c-4e7d-a58e-70017303ee3b --query id -o tsv<br> </code></pre> | `string` | n/a | yes |
| trustIssuerSettings | The trust issuer settings for Customer Managed Azure IoT Operations Settings. | `[_3.TrustIssuerConfig](#user-defined-types)` | {'trustSource': 'SelfSigned'} | no |
| shouldCreateAnonymousBrokerListener | Whether to enable an insecure anonymous AIO MQ Broker Listener. (Should only be used for dev or test environments) | `bool` | `false` | no |
| shouldInitAio | Whether to deploy the Azure IoT Operations initial connected cluster resources, Secret Sync, ACSA, OSM, AIO Platform. | `bool` | `true` | no |
| shouldDeployAio | Whether to deploy an Azure IoT Operations Instance and all of its required components into the connected cluster. | `bool` | `true` | no |
| shouldDeployAioDeploymentScripts | Whether to deploy DeploymentScripts for Azure IoT Operations. | `bool` | `false` | no |
| shouldEnableOtelCollector | Whether or not to enable the Open Telemetry Collector for Azure IoT Operations. | `bool` | `true` | no |
| shouldEnableOpcUaSimulator | Whether or not to enable the OPC UA Simulator and deploy ADR Asset for Azure IoT Operations. | `bool` | `false` | no |
| namespacedDevices | List of namespaced devices to create. | `[_4.NamespacedDevice](#user-defined-types)[]` | [] | no |
| assetEndpointProfiles | List of asset endpoint profiles to create. | `[_4.AssetEndpointProfile](#user-defined-types)[]` | [] | no |
| legacyAssets | List of legacy assets to create. | `[_4.LegacyAsset](#user-defined-types)[]` | [] | no |
Expand Down
21 changes: 9 additions & 12 deletions blueprints/full-single-node-cluster/bicep/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import * as assetTypes from '../../../src/100-edge/111-assets/bicep/types.bicep'
import * as messagingTypes from '../../../src/100-edge/130-messaging/bicep/types.bicep'
import * as aiFoundryTypes from '../../../src/000-cloud/085-ai-foundry/bicep/types.bicep'
import * as vpnGatewayTypes from '../../../src/000-cloud/055-vpn-gateway/bicep/types.bicep'
import * as iotOpsTypes from '../../../src/100-edge/110-iot-ops/bicep/types.bicep'

targetScope = 'subscription'

Expand Down Expand Up @@ -154,9 +155,8 @@ param customLocationsOid string
*/

// Currently disable setting shouldDeployAioDeploymentScripts, remove when DeploymentScripts supports AZ CLI 2.71+ (post May 4)
// @description('The trust issuer settings for Customer Managed Azure IoT Operations Settings.')
// param trustIssuerSettings iotOpsTypes.TrustIssuerConfig = { trustSource: 'SelfSigned' }
var trustIssuerSettings = { trustSource: 'SelfSigned' }
@description('The trust issuer settings for Customer Managed Azure IoT Operations Settings.')
param trustIssuerSettings iotOpsTypes.TrustIssuerConfig = { trustSource: 'SelfSigned' }

@description('Whether to enable an insecure anonymous AIO MQ Broker Listener. (Should only be used for dev or test environments)')
param shouldCreateAnonymousBrokerListener bool = false
Expand All @@ -168,21 +168,18 @@ param shouldInitAio bool = true
param shouldDeployAio bool = true

// Currently disable setting shouldDeployAioDeploymentScripts, remove when DeploymentScripts supports AZ CLI 2.71+ (post May 4)
// @description('Whether to deploy DeploymentScripts for Azure IoT Operations.')
// param shouldDeployAioDeploymentScripts bool = false
var shouldDeployAioDeploymentScripts = false
@description('Whether to deploy DeploymentScripts for Azure IoT Operations.')
param shouldDeployAioDeploymentScripts bool = false

// No additional resource group parameters needed

// Currently disable setting shouldDeployAioDeploymentScripts, remove when DeploymentScripts supports AZ CLI 2.71+ (post May 4)
// @description('Whether or not to enable the Open Telemetry Collector for Azure IoT Operations.')
// param shouldEnableOtelCollector bool = true
var shouldEnableOtelCollector = false
@description('Whether or not to enable the Open Telemetry Collector for Azure IoT Operations.')
param shouldEnableOtelCollector bool = true

// Currently disable setting shouldDeployAioDeploymentScripts, remove when DeploymentScripts supports AZ CLI 2.71+ (post May 4)
// @description('Whether or not to enable the OPC UA Simulator and deploy ADR Asset for Azure IoT Operations.')
// param shouldEnableOpcUaSimulator bool = true
var shouldEnableOpcUaSimulator = false
@description('Whether or not to enable the OPC UA Simulator and deploy ADR Asset for Azure IoT Operations.')
param shouldEnableOpcUaSimulator bool = false

/*
Device Configuration Parameters
Expand Down
4 changes: 3 additions & 1 deletion docs/getting-started/general-user.md
Original file line number Diff line number Diff line change
Expand Up @@ -544,12 +544,14 @@ After successful deployment:
1. **Explore the solution**: Familiarize yourself with deployed components
2. **Configure monitoring**: Set up alerts and dashboards in Grafana
3. **Customize settings**: Modify configuration for your specific needs
4. **Learn more**: Review [Azure IoT Operations documentation][iot-ops-docs] for advanced features
4. **Upgrade Azure IoT Operations**: When new AIO releases ship, follow the [Upgrade Azure IoT Operations](upgrade-aio.md) guide to upgrade and reconcile with Terraform or Bicep
5. **Learn more**: Review [Azure IoT Operations documentation][iot-ops-docs] for advanced features

## Additional Resources

- **[Blueprint Developer Guide](blueprint-developer.md)** - Create custom blueprints
- **[Feature Developer Guide](feature-developer.md)** - Contribute to the platform
- **[Upgrade Azure IoT Operations](upgrade-aio.md)** - Upgrade AIO and reconcile state for Terraform / Bicep
- **[Azure IoT Operations Getting Started][iot-ops-quickstart]** - Official Microsoft guide
- **[Troubleshooting Documentation](../observability/)** - Detailed troubleshooting guides

Expand Down
104 changes: 104 additions & 0 deletions docs/getting-started/upgrade-aio.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
---
title: Upgrade Azure IoT Operations
description: How to upgrade Azure IoT Operations (AIO) and reconcile the upgrade with the edge-ai Terraform or Bicep deployments
author: Edge AI Team
ms.date: 2026-05-05
ms.topic: how-to
estimated_reading_time: 5
keywords:
- azure iot operations
- aio upgrade
- terraform
- bicep
- cert-manager
- secret store
---

## Upgrade Azure IoT Operations

This guide describes how to upgrade an Azure IoT Operations (AIO) instance deployed by edge-ai and how to reconcile the upgrade with your Infrastructure as Code (IaC) of choice.

The `az iot ops upgrade` command updates three cluster components when newer stable versions are available:

- `certManager`
- `secretStore`
- `iotOperations`

The reconciliation steps differ between Terraform (stateful) and Bicep (stateless).

## Prerequisites

- Azure CLI logged in to the target subscription.
- `azure-iot-ops` CLI extension installed (this repo expects version `2.4.0`).
- `<RESOURCE_GROUP_NAME>` — the resource group containing the AIO instance.
- `<INSTANCE_NAME>` — the AIO instance name (for edge-ai blueprints this is typically `iotops-arck-<resource_prefix>-<environment>-<instance>`).

## Run the AIO upgrade

Run the upgrade against your existing AIO instance. Review the proposed changes and confirm:

```bash
az iot ops upgrade \
--resource-group <RESOURCE_GROUP_NAME> \
--name <INSTANCE_NAME>
```

The CLI prints a table comparing current and desired versions for `certManager`, `secretStore`, and `iotOperations`, then performs the update.

After this point, Azure has been mutated — the steps below bring your IaC back in sync.

## Reconcile with Terraform

Terraform is stateful. The state file holds the previous extension versions; after `az iot ops upgrade` it no longer matches Azure. Refresh state, verify, then re-apply your blueprint at the latest edge-ai versions.

1. Refresh state from Azure to absorb the new versions:

```bash
cd blueprints/<your-blueprint>/terraform
source ../../../scripts/az-sub-init.sh
terraform apply -refresh-only -var-file=terraform.tfvars
```

Confirm when prompted. Terraform updates the in-state `version` attribute for the three extensions to match what Azure now reports.

2. Verify there is no drift on the upgraded components:

```bash
terraform plan -var-file=terraform.tfvars | grep -E "cert_manager|secret_store|iot_operations"
```

No output (or `No changes`) means the IaC and Azure agree on the new versions.

3. Re-run edge-ai with the latest AIO version pins and any updated components.

- Pull the latest edge-ai changes (which may bump the version defaults in [variables.init.tf](../../src/100-edge/110-iot-ops/terraform/variables.init.tf), [variables.instance.tf](../../src/100-edge/110-iot-ops/terraform/variables.instance.tf), and [variables.tf](../../src/100-edge/109-arc-extensions/terraform/variables.tf)).
- Apply the blueprint:

```bash
terraform apply -var-file=terraform.tfvars
```

If the upstream pins are now newer than what `az iot ops upgrade` installed, Terraform will move the cluster to the newer pins. If they match, the apply is a no-op for the AIO extensions.

> If you skip step 1, the next `terraform apply` will detect "drift" on the three extensions and roll Azure back to the versions pinned in code. Always run `-refresh-only` first when you upgraded out-of-band.

## Reconcile with Bicep

Bicep is stateless — there is no per-deployment record of previously applied versions to reconcile. After `az iot ops upgrade` no further ARM operations are required to "import" the new state. Subsequent Bicep deployments are idempotent against whatever exists in Azure.

1. Run the AIO upgrade as shown above.

2. Re-run edge-ai with the latest AIO version pins and any updated components.

- Pull the latest edge-ai changes (which may bump the defaults in [109-arc-extensions/bicep/types.bicep](../../src/100-edge/109-arc-extensions/bicep/types.bicep) and [110-iot-ops/bicep/types.bicep](../../src/100-edge/110-iot-ops/bicep/types.bicep)).
- Re-deploy your blueprint with `az deployment group create` (or your existing pipeline) using the same parameters.

If the parameter values are equal to or newer than what `az iot ops upgrade` installed, ARM applies the new versions. Otherwise the deployment is a no-op for the AIO extensions.

> Because Bicep / ARM compares declared properties to live resource state, you do not need a refresh, import, or state-edit step. The next deployment is the reconciliation.

## Troubleshooting

- **Terraform plan still shows version diffs after `-refresh-only`**: confirm that the `azurerm_arc_kubernetes_cluster_extension` resources for `cert_manager`, `secret_store`, and `iot_operations` in state now show the upgraded `version`. If they do, the diff is being driven by code defaults newer than what `az iot ops upgrade` installed — running `terraform apply` will move Azure to those defaults.
- **`az iot ops upgrade` reports no updates**: the cluster is already on the latest stable channel for all three components; nothing to reconcile.
- **Permission errors during refresh**: ensure your principal has read access on the connected cluster, the cluster extensions, and the AIO instance resource group.
Loading
Loading