Producteur OSIRIS JSON pour Microsoft Azure
Le producteur Azure d’OSIRIS JSON se connecte à Microsoft Azure via la Azure CLI (az) et génère des instantanés OSIRIS JSON de la topologie de vos abonnements. À partir de v0.4.0, le producteur couvre les couches réseau, calcul, stockage, identité, bases de données, conteneurs, intégration, observabilité et sauvegarde, y compris leurs arêtes de dépendance inter-ressources (Private Endpoint vers des cibles PaaS, App Service vers App Insights, Log Analytics, RSV, Backup Vault vers des éléments protégés, AKS vers des sous-réseaux et des pools de nœuds, etc.).
Pour commencer à utiliser OSIRIS JSON avec Microsoft Azure, installez le répartiteur principal et le producteur OSIRIS JSON pour Microsoft Azure :
go install go.osirisjson.org/producers/cmd/osirisjson-producer@latest
go install go.osirisjson.org/producers/cmd/osirisjson-producer-azure@latest
Le répartiteur principal vous permet d’exécuter osirisjson-producer azure .... Sans lui, invoquez directement le binaire du fournisseur sous la forme osirisjson-producer-azure ....
Assurez-vous que $GOPATH/bin (ou $HOME/go/bin) figure dans votre PATH. Consultez la page getting started pour plus d’options d’installation.
Prérequis
- Installez la Azure CLI
- Authentifiez-vous :
az login - L’utilisateur authentifié doit disposer du rôle Reader (ou d’une autorisation de lecture équivalente) sur le ou les abonnements cibles. Pour une collecte complète des données, y compris les routes effectives, l’utilisateur doit également disposer de l’autorisation
Microsoft.Network/networkInterfaces/effectiveRouteTable/action(incluse dans Network Contributor et au-delà). Si cette autorisation est absente, le producteur ignore la collecte des routes effectives avec un journal INFO et continue normalement.
Vous pouvez exécuter le producteur sur votre machine locale ou l’invoquer via une tâche planifiée avec un compte de service sur la plateforme de votre choix.
Utilisation de la CLI
osirisjson-producer azure [flags]
osirisjson-producer azure template --generate
Mode unique
Commencez par collecter un abonnement, qui sera automatiquement enregistré sous microsoft-azure-<timestamp>-<name>.json :
osirisjson-producer azure -S a1b2c3d4-e5f6-7890-abcd-ef1234567890
Mode interactif
Exécutez sans flags pour obtenir un sélecteur interactif d’abonnements :
osirisjson-producer azure
Le producteur détecte tous les abonnements accessibles et présente une liste numérotée. Sélectionnez avec des numéros individuels (1,3,5), des plages (30-55), des combinaisons (1,3,30-55) ou saisissez all.
Mode multi-abonnement
Collectez plusieurs abonnements dans un répertoire de sortie :
# Abonnements spécifiques
osirisjson-producer azure -S sub-id-1,sub-id-2,sub-id-3 -o ./output
# Tous les abonnements accessibles (détection automatique)
osirisjson-producer azure --all -o ./output
# Tous les abonnements d'un tenant spécifique
osirisjson-producer azure --all --tenant f1e2d3c4-b5a6-9078-fedc-ba9876543210 -o ./output
Mode batch (CSV)
Générez un modèle CSV :
osirisjson-producer azure template --generate
Collectez à partir d’un fichier CSV :
osirisjson-producer azure -s subscriptions.csv -o ./output
Le modèle CSV utilise les colonnes suivantes :
| Colonne | Requise | Description |
|---|---|---|
subscription_id | oui | UUID de l’abonnement Azure |
subscription_name | oui | Libellé lisible par un humain (utilisé comme nom de fichier de sortie) |
tenant_id | UUID du tenant Azure AD / Entra ID | |
environment | Étape de déploiement : dv, np, pr (développement, préproduction, production) | |
region | Filtre sur une région Azure (vide = toutes les régions) | |
notes | Notes en texte libre (ignorées par le producteur) |
Hiérarchie de sortie
Mode unique : enregistre dans microsoft-azure-<timestamp>-<name>.json dans le répertoire courant.
Modes multi/batch/all : organisés par tenant et horodatage :
output/
<TenantID>/
<timestamp>/
<SubscriptionName>.json
Chaque abonnement produit un document OSIRIS autonome. Les références inter-abonnements (par exemple les VNet peerings ou les connexions ExpressRoute vers des abonnements distants) sont émises comme des ressources factices avec provider.subscription défini sur l’ID de l’abonnement distant, afin que l’arête topologique survive à cette frontière tout en conservant un document valide.
Environnements multi-tenant
Exécutez le producteur une fois par tenant. Chaque az login s’authentifie auprès d’un tenant. Utilisez az login --tenant <tenant-id> pour basculer. La hiérarchie de sortie regroupe automatiquement les documents par tenant.
Référence des flags
| Flag | Court | Description |
|---|---|---|
--subscription | -S | ID du ou des abonnements Azure, séparés par des virgules |
--all | Détecte automatiquement tous les abonnements accessibles | |
--source | -s | Fichier CSV avec les abonnements cibles |
--output | -o | Répertoire de sortie (obligatoire pour les modes multi/all/CSV) |
--tenant | ID du tenant Azure AD / Entra ID (facultatif) | |
--region | Filtre sur une région Azure spécifique (facultatif) | |
--purpose | Niveau de détail de la sortie : documentation (par défaut) ou audit. Voir finalité ci-dessous | |
--safe-failure-mode | Gestion des secrets : fail-closed (par défaut), log-and-redact, off | |
--version / -v | Affiche la version et quitte | |
--help | Affiche l’aide et quitte |
Finalité
Le flag --purpose implémente le chapitre 13.1.3 de la spécification OSIRIS JSON (minimisation des données). La collecte est toujours exhaustive ; l’émission est façonnée par la finalité déclarée, afin qu’une même exécution du producteur puisse répondre aussi bien à des cas d’usage de visualisation légère qu’à des cas d’usage d’audit / conformité.
| Valeur | Comportement |
|---|---|
documentation (par défaut) | Champs minimaux : identité, type, traçabilité du fournisseur, noms, tags et relations de haut niveau. Les objets properties et extensions par ressource sont supprimés. Adapté aux diagrammes, tableaux de bord d’inventaire et documentation de haut niveau. |
audit | Tous les champs lisibles, après masquage des champs sensibles. Objets properties et extensions complets pour chaque ressource, connexion et groupe. Adapté aux revues de conformité, audits, dérive de configuration ou documentation approfondie et conception topologique précise. |
La valeur sélectionnée est enregistrée dans le document sous metadata.scope.purpose, afin que les consommateurs puissent savoir quel niveau de détail ils consultent.
[!IMPORTANT] Les secrets sont toujours masqués, quelle que soit la finalité. La projection d’audit ajoute des détails (adresses IP, règles NSG, sous-champs SKU, détails BGP, etc.) ; elle n’ajoute jamais d’éléments d’authentification. Les mots de passe administrateur de base de données, les clés d’accès Cosmos / Redis / Service Bus / Event Hubs, les clés d’instrumentation App Insights et les clés partagées Log Analytics ne sont jamais collectés.
# Par défaut : documentation (projection minimale)
osirisjson-producer azure -S a1b2c3d4-e5f6-7890-abcd-ef1234567890
# Audit : fidélité ARM complète
osirisjson-producer azure -S a1b2c3d4-e5f6-7890-abcd-ef1234567890 --purpose audit
Ce que collecte le producteur OSIRIS JSON pour Microsoft Azure
Le producteur OSIRIS JSON pour Microsoft Azure collecte un inventaire complet des types de ressources pris en charge via la Azure CLI à chaque exécution. Le tableau suivant regroupe les éléments interrogés.
Réseau
| Ressource Microsoft Azure | Type OSIRIS JSON |
|---|---|
| Virtual Networks | network.vpc |
| Subnets | network.subnet |
| Network Interfaces | network.interface |
| Network Security Groups | network.security.group |
| Application Security Groups | osiris.azure.asg |
| Route Tables | osiris.azure.routetable |
| Public IP Addresses | osiris.azure.publicip |
| Load Balancers (L4) | network.loadbalancer |
| Application Gateways (L7) | network.loadbalancer |
| Azure Firewalls | network.firewall |
| NAT Gateways | osiris.azure.gateway.nat |
| VNet Gateways (VPN / ExpressRoute) | osiris.azure.gateway.vnet |
| ExpressRoute Circuits | osiris.azure.expressroute |
| Private Endpoints | osiris.azure.privateendpoint |
| DNS Zones | osiris.azure.dns.zone |
| Private DNS Zones | osiris.azure.dns.privatezone |
Calcul et stockage
| Ressource Microsoft Azure | Type OSIRIS JSON |
|---|---|
| Virtual Machines | compute.vm |
| Managed Disks | osiris.azure.disk |
| Managed Snapshots | osiris.azure.snapshot |
| Storage Accounts | osiris.azure.storageaccount |
App Service / couche web
| Ressource Microsoft Azure | Type OSIRIS JSON |
|---|---|
| App Service Plan | osiris.azure.appserviceplan |
| Web App | osiris.azure.webapp |
| Function App | osiris.azure.functionapp |
Routage App Service : les sites dont kind contient functionapp sont émis comme osiris.azure.functionapp ; tous les autres sites sont émis comme osiris.azure.webapp.
Identité et sécurité
| Ressource Microsoft Azure | Type OSIRIS JSON |
|---|---|
| Key Vault | osiris.azure.keyvault |
| Container Registry | osiris.azure.containerregistry |
| User-Assigned Managed Identity | osiris.azure.managedidentity |
Sauvegarde et reprise après sinistre
| Ressource Microsoft Azure | Type OSIRIS JSON |
|---|---|
| Recovery Services Vault | osiris.azure.recoveryvault |
| Backup Vault (Azure Backup) | osiris.azure.backupvault |
Bases de données
| Ressource Microsoft Azure | Type OSIRIS JSON |
|---|---|
| SQL Server | osiris.azure.sqlserver |
| SQL Database | osiris.azure.sqldatabase |
| PostgreSQL Flexible Server | osiris.azure.postgresqlserver |
| MySQL Flexible Server | osiris.azure.mysqlserver |
| Cosmos DB account | osiris.azure.cosmosaccount |
| Redis Cache | osiris.azure.redis |
Conteneurs et intégration
| Ressource Microsoft Azure | Type OSIRIS JSON |
|---|---|
| AKS Cluster | osiris.azure.aks.cluster |
| AKS Agent Pool | osiris.azure.aks.nodepool |
| Container App Managed Environment | osiris.azure.containerapp.environment |
| Container App | osiris.azure.containerapp |
| Container Group / ACI | osiris.azure.containergroup |
| Service Bus Namespace | osiris.azure.servicebus.namespace |
| Event Hubs Namespace | osiris.azure.eventhubs.namespace |
| API Management Service | osiris.azure.apim |
| Front Door (Standard / Premium) | osiris.azure.frontdoor.profile |
Observabilité
| Ressource Microsoft Azure | Type OSIRIS JSON |
|---|---|
| Application Insights | osiris.azure.applicationinsights |
| Log Analytics Workspace | osiris.azure.loganalytics |
Regroupement
| Ressource Microsoft Azure | Type OSIRIS JSON |
|---|---|
| Groupes de ressources | container.resourcegroup |
Ce qui n’est volontairement pas collecté
OSIRIS JSON définit un format JSON neutre vis-à-vis des fournisseurs pour décrire les ressources d’infrastructure, leurs propriétés et leurs relations topologiques ; ce n’est pas un format d’Infrastructure-as-Code ni un format similaire. Vous pouvez en lire davantage ici : Qu’est-ce qu’OSIRIS JSON. Les éléments suivants sont volontairement hors périmètre :
- Politique de supervision : alert rules, action groups, metric alerts, scheduled query rules.
- Politiques de sauvegarde / rétention dans Recovery Services Vault et Backup Vault (les vaults et les arêtes vers les éléments protégés sont émis ; les corps de politique ne le sont pas).
- Politique de couche base de données : SQL auditing, threat-detection, TDE, firewall rules, security-alert-policy.
- Politiques, produits, opérations et named values d’API Management.
- Routes Front Door, rule sets, endpoints et associations de politiques WAF (le profil est émis ; le routage ne l’est pas).
- Secrets de Container App et variables d’environnement ACI.
- Énumération des diagnostic settings par ressource (cela ajouterait un appel
azpar ressource). - Azure Front Door classique (
Microsoft.Network/frontDoors, obsolète). Microsoft.DBforPostgreSQL/servershistorique (serveur unique, en fin de vie sur la feuille de route Azure).
Structure de sortie OSIRIS JSON pour Microsoft Azure
{
"$schema": "https://osirisjson.org/schema/v1.0/osiris.schema.json",
"version": "1.0.0",
"metadata": {
"generator": {
"name": "osirisjson-producer-azure",
"version": "0.4.0",
"url": "https://osirisjson.org"
},
"scope": {
"name": "<subscription-id> - <subscription-name>",
"purpose": "documentation",
"providers": ["azure"],
"accounts": ["<tenant-id>"],
"subscriptions": ["<subscription-id>"],
"regions": ["westeurope", "eastus2"]
}
},
"topology": {
"resources": [ ... ],
"connections": [ ... ],
"groups": [ ... ]
}
}
Types de connexion
Les arêtes de connexion utilisent les sous-types standard OSIRIS JSON v1.0 conformément au chapitre 5.2.3 de la spécification, afin que les consommateurs puissent distinguer les couches topologiques.
| Type de connexion OSIRIS JSON | Utilisé pour |
|---|---|
contains | Contenance (sous-réseau au sein du VNet, App Service Plan au sein du site, cluster AKS au sein du pool de nœuds, groupe de ressources au sein de l’abonnement, SQL Server au sein de SQL Database, disque source au sein d’un snapshot, VM au sein du disque attaché) |
network | Connectivité réseau générique (NIC vers un sous-réseau, associations NSG, liens DNS, connexions de passerelle, App Insights vers un espace de travail, Web App vers App Insights, AKS / Redis / ACI vers un sous-réseau, APIM vers un sous-réseau) |
network.peering | Peerings VNet |
network.vpn | Connexions de passerelle VPN |
network.bgp | Connexions de circuit ExpressRoute |
dependency | Private Endpoint vers une cible PaaS (Web App, Function App, Key Vault, Container Registry, Recovery Services Vault, cluster AKS, Service Bus, Event Hubs, APIM) |
dependency.storage | Private Endpoint vers Storage Account |
dependency.database | Private Endpoint vers une base de données (SQL Server, Cosmos DB, Redis) |
Types de groupe
| Type de groupe OSIRIS JSON | Utilisé pour |
|---|---|
logical.subscription | Groupe d’abonnement de niveau supérieur |
logical.resourcegroup | Groupes de groupes de ressources (enfants de l’abonnement) |
container.region | Un groupe par provider.region distinct observé dans l’abonnement, incluant chaque ressource de cette région. La région global et les ressources sans région sont ignorées (elles ne sont pas géographiquement délimitées). Le jeton de délimitation est <subscription-id>/<region>, afin que les groupes n’entrent jamais en collision entre abonnements. |
Types de ressource
Les types de ressource suivent la spécification OSIRIS JSON v1.0. Les types standard sont utilisés lorsqu’ils sont définis ; les types spécifiques à Azure utilisent l’espace de noms osiris.azure.*.
Types standard :
container.resourcegroup- Groupes de ressourcesnetwork.vpc- Réseaux virtuelsnetwork.subnet- Sous-réseauxnetwork.interface- Interfaces réseaunetwork.security.group- Groupes de sécurité réseaunetwork.loadbalancer- Équilibreurs de charge (L4 et L7 / Application Gateway)network.firewall- Azure Firewallscompute.vm- Machines virtuelles
Extensions (osiris.azure)
Les données spécifiques à Azure qui ne correspondent pas à des propriétés OSIRIS JSON portables sont émises dans l’espace de noms d’extension osiris.azure. Cela suit la spécification OSIRIS JSON : properties contient les données communes / portables, extensions contient les données détaillées spécifiques au fournisseur. Les extensions ne sont émises qu’avec --purpose audit.
Les extensions représentatives comprennent :
| Type de ressource OSIRIS JSON | Champs d’extension sélectionnés |
|---|---|
network.interface | enable_accelerated_networking, effective_routes[] |
network.security.group | security_rules[], default_security_rules[] |
osiris.azure.expressroute | sku, sku_tier, service_provider, peerings[] (type de peering BGP, état, ASN du pair, ID VLAN, préfixes d’adresses) |
osiris.azure.webapp / osiris.azure.functionapp | managed_identity, outbound_vnet_routing, private_endpoint_connection_ids[], app_insights_id |
osiris.azure.storageaccount / osiris.azure.keyvault / osiris.azure.containerregistry / osiris.azure.recoveryvault / osiris.azure.sqlserver / osiris.azure.cosmosaccount | private_endpoint_connection_ids[] |
osiris.azure.applicationinsights | workspace_resource_id (espace de travail Log Analytics associé) |
osiris.azure.loganalytics | customer_id (UUID de l’espace de travail utilisé par KQL ; ce n’est pas un secret) |
Métadonnées du fournisseur
Chaque ressource inclut provider.type avec le type de ressource ARM natif (par exemple Microsoft.Network/virtualNetworks, Microsoft.Compute/virtualMachines). Les ressources factices inter-abonnements incluent provider.subscription avec l’ID de l’abonnement distant. Toutes les ressources incluent provider.source défini sur azure-cli.
ID de ressource
Les ID de ressource Azure suivent le modèle azure::<ARM-resource-id>, en utilisant l’ID de ressource ARM complet comme identifiant natif. Cela garantit des ID globalement uniques et déterministes qui résistent à la corrélation inter-abonnements.
Canonicalisation des régions
provider.region et metadata.scope.regions sont canonicalisés vers le format slug d’Azure (minuscules, sans espaces). La CLI az renvoie location de manière incohérente selon les types de ressource : la plupart des ressources ARM utilisent westeurope / eastus2, tandis que les App Service Plans et Web Apps exposent la forme d’affichage (West Europe). Le producteur normalise vers le slug afin qu’un abonnement mono-région n’apparaisse pas comme deux régions dans metadata.scope.regions.
Exigences RBAC
| Niveau d’autorisation | Ce qui est collecté |
|---|---|
| Reader | Tous les types de ressource, propriétés et extensions (règles NSG, peerings ER, connexions gateway, VNet peerings, liens DNS, arêtes Private Endpoint vers des cibles, App Service vers App Insights, ressources AKS, conteneurs, bases de données, messagerie et observabilité) |
Reader + effectiveRouteTable/action | Tout ce qui précède + routes effectives de la NIC |
| Network Contributor / Owner | Jeu de données complet sans restriction |
Le producteur teste l’autorisation sur la première NIC et ignore proprement la collecte des routes effectives si l’autorisation est refusée. Toutes les autres données sont collectées dans tous les cas.
Exemples
Abonnement unique
Nous allons explorer un abonnement unique dans notre tenant et générer depuis Microsoft Azure un document OSIRIS JSON.
osirisjson-producer azure -S a1b2c3d4-e5f6-7890-abcd-ef1234567890 --purpose audit
Document de sortie OSIRIS JSON (tronqué, --purpose audit) :
{
"$schema": "https://osirisjson.org/schema/v1.0/osiris.schema.json",
"version": "1.0.0",
"metadata": {
"generator": {
"name": "osirisjson-producer-azure",
"version": "0.4.0",
"url": "https://osirisjson.org"
},
"scope": {
"name": "a1b2c3d4-e5f6-7890-abcd-ef1234567890 - my-nonprod-subscription",
"purpose": "audit",
"providers": ["azure"],
"accounts": ["f1e2d3c4-b5a6-9078-fedc-ba9876543210"],
"subscriptions": ["a1b2c3d4-e5f6-7890-abcd-ef1234567890"],
"regions": ["westeurope"]
}
},
"topology": {
"resources": [
{
"id": "azure::/subscriptions/a1b2c3d4/resourceGroups/network-rg/providers/Microsoft.Network/virtualNetworks/hub-vnet",
"type": "network.vpc",
"name": "hub-vnet",
"status": "active",
"provider": {
"name": "azure",
"native_id": "/subscriptions/a1b2c3d4/resourceGroups/network-rg/providers/Microsoft.Network/virtualNetworks/hub-vnet",
"type": "Microsoft.Network/virtualNetworks",
"region": "westeurope",
"source": "azure-cli",
"subscription": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"tenant": "f1e2d3c4-b5a6-9078-fedc-ba9876543210"
},
"properties": {
"resource_group": "network-rg",
"address_space": ["10.0.0.0/16"],
"dns_servers": ["10.0.0.4"],
"subnet_count": 4,
"enable_ddos_protection": false,
"peerings": [
{
"name": "hub-to-spoke",
"peering_state": "Connected",
"remote_vnet_id": "/subscriptions/a1b2c3d4/.../spoke-vnet",
"allow_gateway_transit": true,
"allow_forwarded_traffic": true
}
]
}
},
{
"id": "azure::/subscriptions/a1b2c3d4/resourceGroups/data-rg/providers/Microsoft.Storage/storageAccounts/mystg",
"type": "osiris.azure.storageaccount",
"name": "mystg",
"status": "active",
"provider": {
"name": "azure",
"native_id": "/subscriptions/a1b2c3d4/resourceGroups/data-rg/providers/Microsoft.Storage/storageAccounts/mystg",
"type": "Microsoft.Storage/storageAccounts",
"region": "westeurope",
"source": "azure-cli",
"subscription": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"tenant": "f1e2d3c4-b5a6-9078-fedc-ba9876543210"
},
"properties": {
"resource_group": "data-rg",
"sku_tier": "Standard",
"sku_name": "Standard_LRS",
"kind": "StorageV2",
"access_tier": "Hot",
"https_only": true,
"min_tls_version": "TLS1_2",
"public_network_access": "Disabled",
"allow_blob_public_access": false
},
"extensions": {
"osiris.azure": {
"private_endpoint_connection_ids": [
"/subscriptions/a1b2c3d4/.../privateEndpoints/pe-mystg"
]
}
}
}
],
"connections": [
{
"source": "azure::/subscriptions/a1b2c3d4/.../subnets/default",
"target": "azure::/subscriptions/a1b2c3d4/.../virtualNetworks/hub-vnet",
"type": "contains",
"direction": "forward"
},
{
"source": "azure::/subscriptions/a1b2c3d4/.../privateEndpoints/pe-mystg",
"target": "azure::/subscriptions/a1b2c3d4/.../storageAccounts/mystg",
"type": "dependency.storage",
"direction": "forward"
}
],
"groups": [
{
"id": "azure::subscription::a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"type": "logical.subscription",
"name": "my-nonprod-subscription",
"children": [
"azure::resourcegroup::network-rg",
"azure::resourcegroup::data-rg"
]
},
{
"id": "azure::region::a1b2c3d4-e5f6-7890-abcd-ef1234567890/westeurope",
"type": "container.region",
"name": "westeurope",
"members": [
"azure::/subscriptions/a1b2c3d4/.../virtualNetworks/hub-vnet",
"azure::/subscriptions/a1b2c3d4/.../storageAccounts/mystg"
]
}
]
}
}
La même exécution avec la valeur par défaut --purpose documentation renvoie un graphe de ressources identique, mais avec les objets properties et extensions supprimés de chaque ressource, connexion et groupe, ce qui le rend adapté aux vues topologiques de haut niveau et à la documentation.