Esercitazione: Distribuire Operazioni di Azure IoT in una rete a più livelli con connettività privata

Questa esercitazione descrive come distribuire Operazioni di Azure IoT in una topologia di rete fisicamente a più livelli con routing proxy esplicito e connettività privata ai servizi di Azure tramite ExpressRoute. Questa distribuzione usa collegamento privato per raggiungere servizi come Event Grid e non espone endpoint pubblici a nessun livello della rete.

Questo scenario è stato convalidato usando computer fisici in una rete segmentata Purdue/ISA-95 che si estende su livelli da 2 a 4. Il proxy esplicito Firewall di Azure viene distribuito in una rete virtuale Azure, con connettività fornita tramite ExpressRoute.

In questo articolo si apprenderà come:

  • Crea risorse Azure e prepara un ambiente di rete multilivello
  • Preparare i cluster Kubernetes a ogni livello di rete
  • Configurare endpoint privati e DNS per i servizi di Azure
  • Abilitazione dei cluster Arc con il gateway Arc e il routing proxy esplicito
  • Distribuire Operazioni di Azure IoT nei cluster con abilitazione di Arc
  • Assegnare i ruoli RBAC richiesti dai componenti di Operazioni di Azure IoT
  • Convalidare il flusso di telemetria end-to-end dalle origini OPC UA alla Griglia di eventi di Azure
  • Controllare e verificare l'isolamento della rete, la connettività privata e le assegnazioni RBAC (Controllo degli Accessi in Base al Ruolo)

Prerequisiti

  • Sottoscrizione Azure. Se non se ne ha una, creare un account gratuito prima di iniziare.
  • ID del tenant.
  • Autorizzazioni sufficienti per creare endpoint privati, zone DNS privato e assegnazioni di ruolo (in genere Owner o Contributor + Amministratore accesso utente). Questa esercitazione usa ruoli personalizzati definiti nell'Appendice.
  • Un cluster Kubernetes distribuito a ogni livello di rete (livello 2, livello 3 e livello 4), con dispositivi o macchine virtuali assegnati indirizzi IP statici.
  • Segmentazione di rete esistente tra livelli (ad esempio, firewall che consentono solo la comunicazione L2 ↔ L3 ↔ L4) con risoluzione DNS tra livelli tramite CoreDNS.
  • Azure Private Endpoints per Event Grid, Storage (per Schema Registry) e Key Vault, con indirizzi IP privati assegnati e accessibili tramite ExpressRoute o un routing privato equivalente.
  • Proxy esplicito di Firewall di Azure al livello 4 (porte 8080/8443), raggiungibile tramite ExpressRoute da questo livello. Tutto il traffico HTTP/HTTPS in uscita dal livello 4 passa attraverso questo proxy.
  • interfaccia della riga di comando di Azure, kubectl e Docker installati nel computer usato per distribuire le risorse e gestire i cluster Kubernetes.
  • (Facoltativo) Familiarità con il modello Purdue, che definisce i livelli dei sistemi di controllo industriale e viene comunemente usato negli ambienti di produzione.

Annotazioni

Nel flusso di telemetria convalidato viene usato solo HTTPS (porta 8443). Negli ambienti dei clienti, il livello 4 potrebbe invece instradare tramite il proxy aziendale della tua organizzazione.

Riepilogo dell'architettura

Questa distribuzione è allineata al modello Purdue, implementando un'architettura segmentata fisicamente multilivello che si estende sui livelli da 2 a 4.

Ogni livello è separato da firewall di rete che limitano la comunicazione ai livelli adiacenti (ad esempio, L2 ↔ L3 ↔ L4), garantendo una segmentazione stretta. Il traffico in uscita verso Azure viene instradato tramite un proxy esplicito e collegamento privato (facoltativamente tramite Il gateway Arc), assicurando che non vengano usati endpoint esposti a Internet a qualsiasi livello.

Diagramma che mostra linee guida di rete su più livelli per Operazioni di Azure IoT in ambienti di rete industriali segmentati, con una piramide del modello Purdue che si estende su livelli da 2 a 5 a sinistra e un'architettura di Azure Arc a destra che mostra CoreDNS, Envoy e Operazioni di Azure IoT distribuito tra i livelli 3 e 4.

Componenti convalidati

Livello Components Scopo
L2 CoreDNS, Flussi di dati per Operazioni di Azure IoT, Broker MQTT per Operazioni di Azure IoT Inserisce i dati di telemetria dalle origini OPC UA, applica l'arricchimento iniziale e inoltra i dati verso l'alto
L3 CoreDNS, Envoy Proxy, Flussi di dati per Operazioni di Azure IoT, Broker MQTT per Operazioni di Azure IoT Aggrega e trasforma i dati, risolve il DNS per raggiungere L4 e inoltra in modo sicuro i dati di telemetria
L4 Envoy Proxy Inoltra i dati di telemetria arricchiti a Griglia di eventi tramite Proxy esplicito del Firewall di Azure e endpoint privato tramite ExpressRoute

Preparare l'ambiente di rete a più livelli

Ogni livello della rete (livello 2, 3 e 4) usa indirizzi IP statici e regole firewall rigorose per applicare l'isolamento. Ogni livello comunica solo con il livello adiacente ,ad esempio L2 ↔ L3 ↔ L4, implementando le zone del modello Purdue.

Passaggio 1: Creare risorse Azure

Prima di eseguire la distribuzione nella rete perimetrale, creare le risorse di Azure seguenti:

Dopo aver creato queste risorse, disabilitare l'accesso alla rete pubblica su Key Vault, sull'account di archiviazione e sullo spazio dei nomi di Event Grid.

Importante

Il Registro schemi presenta una limitazione nota con la disabilitazione dell'accesso pubblico in fase di creazione. Per informazioni dettagliate, vedere Limitazioni note .

Passaggio 2: Assegnare indirizzi IP statici per ogni livello

Distribuire una macchina (fisica o virtuale) per ogni livello di rete, con i requisiti seguenti:

  • Assegnare indirizzi IP statici all'interno di uno spazio indirizzi condiviso.
  • Tutti i dispositivi eseguono Ubuntu Server 24.04.
  • I dispositivi in L2 e L3 sono abilitati per Arc e ospitano le rispettive istanze Operazioni di Azure IoT.

Configurare indirizzi IP statici usando Netplan. Ad esempio, modificare /etc/netplan/01-netcfg.yaml:

network:
  version: 2
  ethernets:
    eth0:
      addresses:
        - 172.22.232.X/24
      routes:
        - to: default
          via: 172.22.232.1
      nameservers:
        addresses:
          - 168.63.129.16

Applicare la configurazione:

sudo netplan apply

Annotazioni

Gli indirizzi IP illustrati di seguito sono esempi del lab di convalida e non sono accessibili tramite Internet. Sostituire con gli indirizzi IP appropriati per la propria rete. Il server nameserver 168.63.129.16 è raggiungibile solo dall'interno di una rete virtuale Azure. Se il nodo L4 è locale, vedere Distribuzioni locali per un'alternativa usando Azure DNS privato Resolver.

Livello Scopo Nome host di esempio IP di esempio Note
L2 Simulatore OPC UA, Operazioni di Azure IoT (MQTT Broker, Flussi di dati), Arc, CoreDNS p3tiny-01 172.22.232.X Abilitata per Arc, Operazioni di Azure IoT distribuita
L3 Operazioni di Azure IoT (broker MQTT, flussi di dati), CoreDNS, Arc p3tiny-02 172.22.232.Y Abilitata per Arc, Operazioni di Azure IoT distribuita
L4 Envoy Proxy (solo in uscita, accesso esterno) p3tiny-03 172.22.232.Z Non abilitato per Arc, gestisce l'uscita tramite proxy esplicito di Firewall di Azure su ExpressRoute

Passaggio 3: Applicare l'isolamento di rete tra i livelli

Usare firewall o criteri a livello di host (ad esempio UFW) per permettere la comunicazione esclusivamente adiacente.

Percorso di comunicazione Access
L2 ↔ L3 Permetti
L3 ↔ L4 Permetti
L2 ↔ L4 Blocco
L2/L3 → Internet Blocco
L4 → Azure Consentire attraverso Firewall di Azure il proxy esplicito su ExpressRoute

Regole UFW di esempio per l'host L2 (consenti solo L3, nega tutto il resto):

sudo ufw default deny incoming
sudo ufw default deny outgoing
sudo ufw allow from 172.22.232.Y  # Allow L3
sudo ufw allow to 172.22.232.Y    # Allow L3
sudo ufw deny from 172.22.232.Z   # Block L4
sudo ufw deny to 172.22.232.Z     # Block L4
sudo ufw enable

Ripetere per ogni host utilizzando le regole appropriate. Per altre opzioni, vedere la documentazione di UFW .

Passaggio 4: Instradare solo il traffico associato a Azure attraverso L4

Solo il nodo di livello 4 potrebbe avviare il traffico in uscita, inoltrandolo al proxy esplicito Firewall di Azure tramite ExpressRoute, che lo instrada ai servizi di Azure tramite collegamento privato.

  1. Distribuire Envoy Proxy nel computer L4. Per le configurazioni di esempio, vedere Configurare l'infrastruttura.

  2. Inoltrare il traffico HTTPS al proxy esplicito Firewall di Azure:

    • IP: 10.254.0.68
    • Porte: 8080 (HTTP), 8443 (HTTPS)
  3. Verificare che L4 possa raggiungere il proxy:

    curl -v --proxy http://10.254.0.68:8443 https://management.azure.com
    

Annotazioni

Questa convalida usava il traffico HTTP(S) tramite il proxy. Se il proxy supporta MQTT o altri protocolli non HTTP, questi possono essere usati anche in una configurazione simile.

Preparare i cluster Kubernetes

Distribuire un cluster K3s in ogni computer a livello 2, 3 e 4. Per istruzioni, vedere Prepare il cluster Kubernetes abilitato per Azure Arc.

Dopo l'installazione, verificare che ogni cluster sia pronto:

kubectl get nodes

Annotazioni

Il livello 4 esegue solo Il proxy Envoy e non richiede Operazioni di Azure IoT o Arc. Un'installazione K3s leggera è sufficiente.

Configurare collegamento privato di Azure per connettersi in modo sicuro a Griglia di eventi e Archiviazione di Azure usando endpoint privati e la risoluzione dei nomi basata su CoreDNS. Tutto il traffico verso questi servizi rimane su INDIRIZZI IP privati, senza esposizione a Internet.

Passaggio 1: Creare endpoint privati per Griglia di eventi e Archiviazione di Azure

Creare un endpoint privato per l'Event Grid namespace:

az network private-endpoint create \
  --name pe-eventgrid \
  --resource-group <resource-group> \
  --location <region-of-vnet> \
  --subnet "/subscriptions/<subscription-id>/resourceGroups/<rg-vnet>/providers/Microsoft.Network/virtualNetworks/<vnet>/subnets/<subnet>" \
  --private-connection-resource-id \"/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.EventGrid/namespaces/<namespace>\" \
  --group-id topicspace \
  --connection-name pe-conn-eventgrid

Creare un endpoint privato per l'account Archiviazione di Azure:

az network private-endpoint create \
  --name pe-storage-blob \
  --resource-group <resource-group> \
  --location <region-of-vnet> \
  --subnet "/subscriptions/<subscription-id>/resourceGroups/<rg-vnet>/providers/Microsoft.Network/virtualNetworks/<vnet>/subnets/<subnet>" \
  --private-connection-resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.Storage/storageAccounts/<account>" \
  --group-id blob \
  --connection-name pe-conn-storage-blob

Passaggio 2: Creare zone DNS privato

Per ogni servizio, creare la zona di Azure DNS privato appropriata e collegarla alla rete virtuale di livello 4. CoreDNS in L3 (e facoltativamente L2) inoltra le richieste al resolver DNS interno di Azure (168.63.129.16), che risolve i nomi in base al collegamento di zona DNS della zona L4.

Creare le zone DNS:

# Event Grid
az network private-dns zone create \
  --resource-group <resource-group> \
  --name privatelink.ts.eventgrid.azure.net

# Azure Blob Storage
az network private-dns zone create \
  --resource-group <resource-group> \
  --name privatelink.blob.core.windows.net

# Azure Key Vault
az network private-dns zone create \
  --resource-group <resource-group> \
  --name privatelink.vaultcore.azure.net

Collegare ogni zona alla rete virtuale di livello 4:

az network private-dns link vnet create \
  --resource-group <resource-group> \
  --zone-name privatelink.ts.eventgrid.azure.net \
  --name link-eventgrid-l4 \
  --virtual-network "/subscriptions/<subscription-id>/resourceGroups/<rg-vnet>/providers/Microsoft.Network/virtualNetworks/<vnet>" \
  --registration-enabled false

az network private-dns link vnet create \
  --resource-group <resource-group> \
  --zone-name privatelink.blob.core.windows.net \
  --name link-storage-l4 \
  --virtual-network "/subscriptions/<subscription-id>/resourceGroups/<rg-vnet>/providers/Microsoft.Network/virtualNetworks/<vnet>" \
  --registration-enabled false

az network private-dns link vnet create \
  --resource-group <resource-group> \
  --zone-name privatelink.vaultcore.azure.net \
  --name link-keyvault-l4 \
  --virtual-network "/subscriptions/<subscription-id>/resourceGroups/<rg-vnet>/providers/Microsoft.Network/virtualNetworks/<vnet>" \
  --registration-enabled false

Per l'elenco completo dei nomi delle zone DNS private, vedere Valori delle zone DNS private di Azure.

Passaggio 3: Abilitare la risoluzione DNS per gli Endpoint Privati di Azure

Distribuisci CoreDNS su L2 e L3 per inoltrare le query di dominio private di Azure a 168.63.129.16, il resolver DNS interno di Azure per i domini del Private Endpoint. Per istruzioni sulla distribuzione, vedere Configurare l'infrastruttura.

Annotazioni

168.63.129.16 è il DNS del server interno di Azure ed è raggiungibile solo dall'interno di una rete virtuale di Azure. In questo lab, L4 è una macchina virtuale ospitata dalla rete virtuale, quindi le query CoreDNS da L2/L3 vengono inoltrate tramite Envoy a L3 e L4, raggiungendo infine 168.63.129.16 la rete virtuale L4.

Distribuzioni locali

Se il nodo L4 è locale (non all'interno di una rete virtuale Azure), 168.63.129.16 non è raggiungibile. Distribuire invece un Azure DNS privato Resolver con un endpoint in ingresso nella stessa rete virtuale in cui sono collegate le zone DNS privato:

  1. Creare un sistema di risoluzione DNS privato nella rete virtuale:

    az dns-resolver create \
      --name <resolver-name> \
      --resource-group <resource-group> \
      --location <region> \
      --id "/subscriptions/<subscription-id>/resourceGroups/<rg-vnet>/providers/Microsoft.Network/virtualNetworks/<vnet>"
    
  2. Creare un endpoint in ingresso (ottiene un indirizzo IP privato instradabile tramite ExpressRoute):

    az dns-resolver inbound-endpoint create \
      --name <endpoint-name> \
      --dns-resolver-name <resolver-name> \
      --resource-group <resource-group> \
      --location <region> \
      --ip-configurations "[{\"private-ip-allocation-method\":\"Dynamic\",\"id\":\"/subscriptions/<subscription-id>/resourceGroups/<rg-vnet>/providers/Microsoft.Network/virtualNetworks/<vnet>/subnets/<dns-resolver-subnet>\"}]"
    
  3. Si noti l'INDIRIZZO IP privato assegnato all'endpoint in ingresso , ad esempio 10.254.1.4. Utilizzare questo indirizzo IP al posto di 168.63.129.16 nella configurazione di CoreDNS e nel nameserver di Netplan di seguito.

Per ulteriori informazioni, vedere Cos'è DNS di Azure Private Resolver?.

CoreDNS ConfigMap

Creare un oggetto ConfigMap con il Corefile di CoreDNS. Sostituire 168.63.129.16 con l'ip dell'endpoint in ingresso del sistema di risoluzione DNS privato se il nodo L4 è locale:

kubectl apply -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns-custom
  namespace: kube-system
data:
  Corefile: |
    eventgrid.azure.net {
      forward . 168.63.129.16
    }
    blob.core.windows.net {
      forward . 168.63.129.16
    }
    vaultcore.azure.net {
      forward . 168.63.129.16
    }
    . {
      forward . /etc/resolv.conf
    }
EOF

Riavviare CoreDNS per selezionare le modifiche:

kubectl rollout restart deployment coredns -n kube-system

Annotazioni

Questa configurazione garantisce che Griglia di eventi, Archiviazione e Insieme delle credenziali di chiavi risolvano solo in indirizzi IP dell'endpoint privato.

Passaggio 4: Verificare la risoluzione e la connettività DNS

Da L4 confermare la risoluzione DNS:

nslookup <eventgrid-namespace>.privatelink.eventgrid.azure.net
nslookup <account>.privatelink.blob.core.windows.net

Verificare che il traffico passi attraverso Envoy e collegamento privato, non la rete Internet pubblica:

curl -v https://<eventgrid-namespace>.ts.eventgrid.azure.net

Verifica che:

  • I FQDN (nomi di dominio completi) vengono risolti in indirizzi IP privati.
  • Il traffico passa attraverso Envoy e collegamento privato, non gli endpoint pubblici.

Annotazioni

Arc richiede la risoluzione DNS funzionante (tramite CoreDNS) per completare l'onboarding.

Abilitare i cluster per Arc con Arc Gateway (opzionale)

Con la risoluzione DNS e la connettività privata implementata, abilita Arc per i cluster Kubernetes utilizzando il proxy esplicito. Questo passaggio connette ogni cluster a Azure Arc e lo associa alla risorsa Gateway Arc creata in P 1.

Passaggio 1: Impostare le variabili di ambiente proxy

Nella macchina virtuale del gateway Arc, che ospita i servizi di Azure Arc, si devono impostare le variabili proxy di ambiente. La HTTPS_PROXY variabile deve puntare al proxy esplicito del firewall della rete:

export HTTP_PROXY=http://<proxy-server>:<port>
export HTTPS_PROXY=http://<proxy-server>:<port>
export NO_PROXY=localhost,127.0.0.1,.svc,.local,<your-private-DNS-zone>

Passaggio 2: recuperare l'ID oggetto dell'entità di servizio

Il parametro --custom-locations-oid richiede l'ID oggetto (OID) dell'entità servizio di Percorsi personalizzati di Azure Arc.

Per trovarla nel portale di Azure:

  1. Andare a Microsoft Entra ID.
  2. Selezionare Applicazioni aziendali.
  3. Cercare Percorsi personalizzati su Kubernetes con Azure Arc.
  4. Aprire l'applicazione, passare a Proprietà e copiare l'ID oggetto.

Passaggio 3: Connettere il cluster con Arc Gateway

Connettere il cluster dietro il proxy e associarlo al gateway Arc:

az connectedk8s connect \
  --name <cluster-name> \
  --resource-group <resource-group> \
  --location <region> \
  --custom-locations-oid <OID> \
  --enable-oidc-issuer \
  --enable-workload-identity \
  --disable-auto-upgrade \
  --proxy-https $HTTPS_PROXY \
  --proxy-http $HTTP_PROXY \
  --proxy-skip-range $NO_PROXY \
  --gateway-resource-id <gateway-resource-id>

Annotazioni

Omettere --gateway-resource-id se non si usa Arc Gateway (ad esempio, se si usa ExpressRoute solo con endpoint privati).

Passaggio 4: Verificare la connettività arc

  1. Eseguire kubectl logs nel pod del gateway Arc per verificare la connessione ad Azure.
  2. Verificare che la risoluzione del DNS e l'handshake del TLS siano avvenuti correttamente tramite il proxy.

Distribuire Operazioni di Azure IoT

Con i cluster abilitati per Arc in L2 e L3, distribuire Operazioni di Azure IoT su ogni livello. In questo modo viene creata l'identità gestita assegnata dal sistema necessaria per le assegnazioni di controllo degli accessi in base al ruolo nella sezione successiva.

Importante

Usare il --skip-ra flag durante la creazione del Registro schemi. Ciò impedisce all'interfaccia della riga di comando di tentare assegnazioni di ruolo che richiedono diritti di proprietario. Per informazioni dettagliate, vedere Limitazioni note .

Per ogni cluster abilitato per Arc (L2 e L3), passare al contesto del cluster e seguire i passaggi descritti in Deploy Operazioni di Azure IoT:

# For Level 2
kubectl config use-context <L2-cluster>
# Follow deploy instructions, then repeat for Level 3
kubectl config use-context <L3-cluster>

Dopo ogni deployment, verificare che tutti i pod siano attivi:

kubectl get pods -n azure-iot-operations

Annotazioni

Il livello 4 non esegue Operazioni di Azure IoT. Solo il proxy Envoy viene distribuito a questo livello.

Assegna ruoli RBAC

Operazioni di Azure IoT richiede assegnazioni di controllo degli accessi in base al ruolo specifiche per consentire ai componenti di interagire con i servizi Azure come gestione rete virtuale di Azure e Griglia di eventi.

Annotazioni

Queste autorizzazioni sono state assegnate manualmente nel lab dagli amministratori con privilegi elevati. Per la produzione, usare l'automazione di Criteri di Azure.

Assegnazioni di ruolo obbligatorie

Assegnare questi ruoli all'identità gestita assegnata dal sistema Operazioni di Azure IoT in ogni cluster abilitato per Arc (L2 e L3). In questo scenario convalidato, L4 è un pass-through Envoy puro e non ha identità gestite.

Identità Ruolo Ambito Note
Sistema di identità gestita assegnata dal sistema per le operazioni IoT di Azure di livello L2/L3 Collaboratore del BLOB di archiviazione Account di archiviazione contenente i file di schema Per Registro schema
Sistema di gestione Operazioni di Azure IoT L3 con identità gestita assegnata dal sistema Editore di TopicSpaces di EventGrid Namespace di Event Grid L3 pubblica su Event Grid tramite il pass-through Envoy L4
Sistema di gestione Operazioni di Azure IoT L3 con identità gestita assegnata dal sistema Sottoscrittore EventGrid TopicSpaces Namespace di Event Grid L3 si sottoscrive a Event Grid tramite il pass-through di L4 Envoy

Assegnare ogni ruolo usando interfaccia della riga di comando di Azure:

# Storage Blob Contributor (for Schema Registry)
az role assignment create \
  --assignee <identity-client-id> \
  --role "Storage Blob Contributor" \
  --scope <storage-account-resource-id>

# Event Grid Publisher
az role assignment create \
  --assignee <identity-client-id> \
  --role "EventGrid TopicSpaces Publisher" \
  --scope <event-grid-namespace-resource-id>

# Event Grid Subscriber
az role assignment create \
  --assignee <identity-client-id> \
  --role "EventGrid TopicSpaces Subscriber" \
  --scope <event-grid-namespace-resource-id>

Contesto di arricchimento a più livelli

Ogni livello di rete per Operazioni di Azure IoT contribuisce con metadati aziendali alla telemetria in uscita:

Livello Aggiunge campo metadati
L2 product
L3 line-config, factory-code

In questo scenario convalidato, il flusso di dati di L3 aggiunge sia line-config che factory-code prima dell'inoltro tramite Envoy L4. Questo arricchimento a più livelli consente ai sistemi downstream di comprendere il contesto di produzione senza sovraccaricare i dispositivi perimetrali con metadati completi.

Annotazioni

Nelle distribuzioni in cui L4 esegue anche le operazioni di Azure IoT (abilitate per Arc con la propria identità gestita), è possibile invece assegnare i factory-code ruoli di arricchimento e i ruoli RBAC di Griglia di eventi a L4.

Convalidare il flusso di telemetria

Prima di convalidare il flusso end-to-end, verificare che ogni componente sia in esecuzione a livello corretto.

Passaggio 1: Verificare l'idoneità dei componenti

CoreDNS (L2, L3): Verificare che i pod CoreDNS siano in esecuzione e che funzioni la risoluzione DNS:

kubectl get pods -n kube-system -l k8s-app=kube-dns
dig <eventgrid-namespace>.ts.eventgrid.azure.net

Envoy Proxy (L3, L4): Verificare che i pod siano in esecuzione:

kubectl config use-context <level>
kubectl get pods -l app=<envoy-proxy-pod>

Operazioni di Azure IoT MQTT Broker (L2, L3): Verificare che i listener siano attivi:

kubectl get service <k3s-service-name> -n azure-iot-operations

Passaggio 2: Convalidare il percorso di connettività

Il flusso di telemetria end-to-end segue questo percorso:

  1. Telemetry ingestion (L2): i connettori OPC UA a L2 pubblicano i dati di telemetria nei flussi di dati di Operazioni di Azure IoT, che li inoltrano al broker MQTT.
  2. Da L2 a L3: MQTT Broker presso L2 pubblica messaggi in L3 usando MQTT.
  3. Da L3 a L4: MQTT Broker presso L3 pubblica messaggi upstream usando MQTT su WebSocket.
  4. Risoluzione DNS (L3): Flussi di dati e CoreDNS per Operazioni di Azure IoT in L3 risolvono i nomi dei servizi privati per consentire l'accesso a L4.
  5. Inoltro Proxy (da L3 a L4): Envoy Proxy su L3 inoltra il traffico MQTT a Envoy Proxy su L4.
  6. Egress (L4): Envoy Proxy su L4 invia il traffico all'Firewall di Azure Explicit Proxy sulla porta 8443 tramite ExpressRoute.
  7. Private routing: Il proxy instrada le richieste ai servizi Azure tramite endpoint privati.
  8. Integrazione Cloud: Servizi come i topic spaces di Event Grid, Archiviazione di Azure e Azure Key Vault sono accessibili in modo privato tramite collegamento privato di Azure. L'accesso alla rete pubblica è disabilitato per tutti i servizi Azure nella distribuzione.

Spazi degli argomenti di Griglia di eventi

I dati vengono pubblicati in Griglia di eventi tramite MQTT su WebSocket (/mqtt suffisso di percorso). Il flusso di dati Operazioni di Azure IoT di L3 esegue l'autenticazione usando l'identità gestita assegnata dal sistema (che ha i ruoli di EventGrid TopicSpaces Publisher e Subscriber) e invia il traffico tramite il proxy Envoy su L3, che inoltra al proxy Envoy su L4. Il traffico in uscita dal livello 4 viene instradato attraverso il proxy esplicito di Firewall di Azure (porta 8443), che quindi inoltra al private endpoint di Event Grid tramite ExpressRoute. Il livello 4 funge da pass-through puro e non esegue l'autenticazione.

I dati di telemetria vengono convalidati rispetto agli schemi definiti in gestione rete virtuale di Azure, applicati dai flussi di dati Operazioni di Azure IoT in esecuzione in L2 e L3.

Output di esempio

{
  "Temperature": {
    "Value": 98.2,
    "SourceTimestamp": "2025-08-05T13:45:22Z"
  },
  "EnergyUse": {
    "Value": 212,
    "SourceTimestamp": "2025-08-05T13:45:22Z"
  },
  "Weight": {
    "Value": 229,
    "SourceTimestamp": "2025-08-05T13:45:22Z"
  },
  "product": "flakes",
  "line-config": "cereal",
  "factory-code": "1032"
}

Verifica di controllo e post-distribuzione

Importante

In questa sezione vengono fornite le procedure di controllo consigliate. Chiedere al team di rete e alla sicurezza di esaminare questi passaggi prima di usarli nell'ambiente di produzione.

Dopo la distribuzione, verificare che l'isolamento di rete, la connettività privata e le assegnazioni RBAC siano configurate correttamente.

Passaggio 1: Verificare l'isolamento della rete tra i livelli

Verificare che non avvenga alcuna perdita di traffico tra livelli non adiacenti (ad esempio, L2 non deve raggiungere direttamente L4).

  1. Da un host L2, tentare di raggiungere direttamente l'INDIRIZZO IP dell'host L4. La connessione deve scadere o essere rifiutata:

    curl -v --connect-timeout 5 https://<L4-host-ip>:8443
    
  2. Da un host L2 verificare che la connettività a L3 funzioni:

    curl -v --connect-timeout 5 https://<L3-host-ip>:<port>
    
  3. Esaminare i log del firewall per verificare che il traffico tra livelli non sia imprevisto.

Passaggio 2: Confermare i percorsi di traffico tramite endpoint privati

Verificare che tutto il traffico associato a Azure instrada attraverso endpoint privati e non la rete Internet pubblica:

  1. A partire da L4, risolvere i FQDN del servizio Azure e confermare che restituiscono indirizzi IP privati.

    nslookup <eventgrid-namespace>.ts.eventgrid.azure.net
    nslookup <storage-account>.blob.core.windows.net
    nslookup <keyvault-name>.vault.azure.net
    

    Ogni risultato deve restituire un indirizzo IP nell'intervallo di indirizzi privati (ad esempio, 10.254.x.x), non un indirizzo IP pubblico.

  2. Controllare il portale di Azure per ogni endpoint privato per verificare che lo stato della connessione sia Approved.

  3. Nei log di Firewall di Azure verificare che il traffico in uscita da L4 venga instradato solo agli indirizzi IP dell'endpoint privato.

Passaggio 3: convalidare le assegnazioni di controllo degli accessi in base al ruolo

Verificare che siano presenti le assegnazioni di ruolo necessarie:

# Check Storage Blob Contributor
az role assignment list \
  --scope <storage-account-resource-id> \
  --role "Storage Blob Contributor" \
  --output table

# Check Event Grid Publisher
az role assignment list \
  --scope <event-grid-namespace-resource-id> \
  --role "EventGrid TopicSpaces Publisher" \
  --output table

# Check Event Grid Subscriber
az role assignment list \
  --scope <event-grid-namespace-resource-id> \
  --role "EventGrid TopicSpaces Subscriber" \
  --output table

Verificare che l'identità gestita assegnata dal sistema Operazioni di Azure IoT sia elencata come assegnatario per ogni ruolo.

Passaggio 4: Verificare che il DNS venga risolto solo in IP privati

Da ogni livello in cui è stato distribuito CoreDNS, verificare che i nomi dei servizi Azure si risolvano in indirizzi IP privati.

# From L2
dig <eventgrid-namespace>.ts.eventgrid.azure.net
dig <storage-account>.blob.core.windows.net

# From L3
dig <eventgrid-namespace>.ts.eventgrid.azure.net
dig <storage-account>.blob.core.windows.net

Se una query restituisce un indirizzo IP pubblico, controllare le regole di inoltro di CoreDNS e il collegamento della zona DNS privata.

Limitazioni note

Per limitazioni comuni relative alla convalida della piattaforma, al supporto proxy e al Registry Schema, vedere Limitazioni note in Distribuzione di Operazioni di Azure IoT con connettività privata.

Le limitazioni seguenti sono specifiche dell'esercitazione sulla rete a più livelli:

  • Livello 1: Il livello dispositivo L1 non è usato in questo flusso di distribuzione.
  • Livello 4 Arc: Il livello 4 non è abilitato per Arc; a questo livello viene distribuito solo il proxy Envoy.
  • Sovereign clouds: Questo scenario è stato convalidato solo in Azure cloud pubblico. Gli ambienti Sovereign Cloud, ad esempio Azure per enti pubblici, Azure gestiti da 21Vianet, usano endpoint differenti e nomi di zona DNS privato, pertanto non sono stati convalidati.
  • Configurazioni fuori ambito: Scenari che coinvolgono le reti virtuali Azure con firewall esterni, proxy trasparenti o distribuzioni di reti virtuali solo cloud non sono state convalidate e non sono supportate.

Appendice

Informazioni di riferimento sulle risorse chiave Azure

Subscription: <subscription-id>
Tenant: <tenant-id>

Arc Clusters:
- Level2: <L2-cluster-name>
- Level3: <L3-cluster-name>

Storage Containers (schemas):
- L2: <L2-schema-container-name>
- L3: <L3-schema-container-name>

Event Grid Namespace: <eventgrid-namespace-name>
Private Endpoint (Event Grid Topic Spaces): <pe-eventgrid-name> (IP: <private-ip-eventgrid>)

Schema Registries:
- L2: <L2-schema-registry-name>
- L3: <L3-schema-registry-name>

Azure IoT Operations Instances:
- L2: <L2-instance-name>
- L3: <L3-instance-name>

Definizioni di ruolo personalizzate

ACX–Secrets Store Extension Owner: Concede le autorizzazioni per registrare e gestire il driver CSI dell'archivio segreti, configurare le classi del provider di segreti Azure Key Vault e gestire le identità gestite assegnate dall'utente.

{
  "roleName": "ACX-Secrets Store Extension Owner",
  "assignableScopes": ["/subscriptions/<subscription-id>"],
  "permissions": [
    {
      "actions": [
        "Microsoft.SecretSyncController/register/action",
        "Microsoft.SecretSyncController/unregister/action",
        "Microsoft.SecretSyncController/azureKeyVaultSecretProviderClasses/read",
        "Microsoft.SecretSyncController/azureKeyVaultSecretProviderClasses/write",
        "Microsoft.SecretSyncController/azureKeyVaultSecretProviderClasses/delete",
        "Microsoft.Insights/alertRules/*",
        "Microsoft.Resources/deployments/*",
        "Microsoft.ManagedIdentity/userAssignedIdentities/assign/action",
        "Microsoft.ManagedIdentity/userAssignedIdentities/write",
        "Microsoft.ManagedIdentity/userAssignedIdentities/revokeTokens/action"
      ]
    }
  ]
}

AdaptiveCloud_AIO-Collaboratori: Concede le autorizzazioni per gestire le assegnazioni di ruolo e le credenziali di identità federate per le identità gestite assegnate dall'utente all'interno del gruppo di risorse.

{
  "roleName": "AdaptiveCloud_AIO-Contributors",
  "assignableScopes": ["/subscriptions/<subscription-id>/resourceGroups/<resource-group>"],
  "permissions": [
    {
      "actions": [
        "Microsoft.Authorization/roleAssignments/read",
        "Microsoft.Authorization/roleAssignments/write",
        "Microsoft.Authorization/roleAssignments/delete",
        "Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials/read",
        "Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials/write"
      ]
    }
  ]
}

Annotazioni

Negli ambienti che usano Criteri di Azure automazione, queste definizioni manuali dei ruoli potrebbero non essere necessarie per i team OT. I criteri possono preassegnare i ruoli di Collaboratore o di Collaboratore ai dati di BLOB di archiviazione, secondo le esigenze.