Productor OSIRIS JSON para Microsoft Azure
El productor Azure de OSIRIS JSON se conecta a Microsoft Azure mediante Azure CLI (az) y genera instantáneas OSIRIS JSON de la topología de sus suscripciones. A partir de v0.4.0, el productor cubre las capas de red, cómputo, almacenamiento, identidad, bases de datos, contenedores, integración, observabilidad y respaldo, incluyendo sus aristas de dependencia entre recursos (Private Endpoint hacia destinos PaaS, App Service hacia App Insights, Log Analytics, RSV, Backup Vault hacia elementos protegidos, AKS hacia subredes y pools de nodos, etc.).
Para empezar a usar OSIRIS JSON para Microsoft Azure, instale el dispatcher principal y el productor OSIRIS JSON para Microsoft Azure:
go install go.osirisjson.org/producers/cmd/osirisjson-producer@latest
go install go.osirisjson.org/producers/cmd/osirisjson-producer-azure@latest
El dispatcher principal le permite ejecutar osirisjson-producer azure .... Sin él, invoque directamente el binario del proveedor como osirisjson-producer-azure ....
Asegúrese de que $GOPATH/bin (o $HOME/go/bin) esté en su PATH. Consulte la página getting started para ver más opciones de instalación.
Requisitos previos
- Instale la Azure CLI
- Autentíquese:
az login - El usuario autenticado debe tener el rol Reader (o un permiso de lectura equivalente) en la o las suscripciones de destino. Para la recopilación completa de datos, incluyendo rutas efectivas, el usuario también necesita el permiso
Microsoft.Network/networkInterfaces/effectiveRouteTable/action(incluido en Network Contributor y superiores). Si este permiso no está presente, el productor omite la recopilación de rutas efectivas con un registro INFO y continúa normalmente.
Puede ejecutar el productor en su máquina local o invocarlo mediante un trabajo programado con una cuenta de servicio en la plataforma de su preferencia.
Uso de la CLI
osirisjson-producer azure [flags]
osirisjson-producer azure template --generate
Modo único
Empiece recopilando una suscripción, que se guardará automáticamente como microsoft-azure-<timestamp>-<name>.json:
osirisjson-producer azure -S a1b2c3d4-e5f6-7890-abcd-ef1234567890
Modo interactivo
Ejecute sin flags para obtener un selector interactivo de suscripciones:
osirisjson-producer azure
El productor detecta todas las suscripciones accesibles y presenta una lista numerada. Seleccione usando números individuales (1,3,5), rangos (30-55), combinaciones (1,3,30-55) o escriba all.
Modo multi-suscripción
Recopile varias suscripciones en un directorio de salida:
# Suscripciones específicas
osirisjson-producer azure -S sub-id-1,sub-id-2,sub-id-3 -o ./output
# Todas las suscripciones accesibles (descubrimiento automático)
osirisjson-producer azure --all -o ./output
# Todas las suscripciones de un tenant específico
osirisjson-producer azure --all --tenant f1e2d3c4-b5a6-9078-fedc-ba9876543210 -o ./output
Modo por lotes (CSV)
Genere una plantilla CSV:
osirisjson-producer azure template --generate
Recopile a partir de un archivo CSV:
osirisjson-producer azure -s subscriptions.csv -o ./output
La plantilla CSV utiliza estas columnas:
| Columna | Obligatoria | Descripción |
|---|---|---|
subscription_id | sí | UUID de la suscripción de Azure |
subscription_name | sí | Etiqueta legible por humanos (utilizada como nombre del archivo de salida) |
tenant_id | UUID del tenant de Azure AD / Entra ID | |
environment | Etapa de despliegue: dv, np, pr (desarrollo, no producción, producción) | |
region | Filtra por región de Azure (vacío = todas las regiones) | |
notes | Notas en texto libre (ignoradas por el productor) |
Jerarquía de salida
Modo único: guarda en microsoft-azure-<timestamp>-<name>.json en el directorio actual.
Modos multi/por lotes/todas las suscripciones: organizados por tenant y marca de tiempo:
output/
<TenantID>/
<timestamp>/
<SubscriptionName>.json
Cada suscripción produce un documento OSIRIS autocontenido. Las referencias entre suscripciones (por ejemplo, peerings de VNet o conexiones ExpressRoute hacia suscripciones remotas) se emiten como recursos stub con provider.subscription establecido en el ID de la suscripción remota, de modo que la arista topológica sobreviva al límite mientras el documento siga siendo válido.
Entornos multi-tenant
Ejecute el productor una vez por tenant. Cada az login autentica contra un tenant. Use az login --tenant <tenant-id> para cambiar. La jerarquía de salida agrupa los documentos por tenant automáticamente.
Referencia de flags
| Flag | Corta | Descripción |
|---|---|---|
--subscription | -S | ID de suscripciones de Azure, separados por comas |
--all | Descubre automáticamente todas las suscripciones accesibles | |
--source | -s | Archivo CSV con las suscripciones de destino |
--output | -o | Directorio de salida (obligatorio para el modo multi/all/CSV) |
--tenant | ID del tenant de Azure AD / Entra ID (opcional) | |
--region | Filtra por una región específica de Azure (opcional) | |
--purpose | Nivel de detalle de la salida: documentation (predeterminado) o audit. Consulte Purpose abajo | |
--safe-failure-mode | Gestión de secretos: fail-closed (predeterminado), log-and-redact, off | |
--version / -v | Muestra la versión y sale | |
--help | Muestra la ayuda y sale |
Propósito
La opción --purpose implementa OSIRIS JSON specification chapter 13.1.3 (data minimization). La recopilación siempre es exhaustiva; la emisión se moldea según el propósito declarado, de manera que la misma ejecución del productor pueda servir tanto para casos de uso de visualización ligera como para casos de uso de auditoría / cumplimiento.
| Valor | Comportamiento |
|---|---|
documentation (predeterminado) | Campos mínimos: identidad, tipo, trazabilidad del proveedor, nombres, etiquetas y relaciones de alto nivel. Se eliminan los objetos properties y extensions por recurso. Adecuado para diagramas, paneles de inventario y documentación de alto nivel. |
audit | Todos los campos legibles, después del enmascaramiento de campos sensibles. Objetos completos properties y extensions para cada recurso, conexión y grupo. Adecuado para revisiones de cumplimiento, auditorías, deriva de configuración o documentación profunda y diseño topológico preciso. |
El valor seleccionado se registra en el documento bajo metadata.scope.purpose, para que los consumidores puedan saber qué nivel de detalle están leyendo.
[!IMPORTANT] Los secretos siempre se redactan sin importar el propósito. La proyección de auditoría agrega detalles (direcciones IP, reglas NSG, subcampos de SKU, detalles de BGP, etc.); nunca agrega material de autenticación. Las contraseñas de administrador de base de datos, las claves de acceso de Cosmos / Redis / Service Bus / Event Hubs, las claves de instrumentación de App Insights y las claves compartidas de Log Analytics nunca se recopilan.
# Predeterminado: documentation (proyección mínima)
osirisjson-producer azure -S a1b2c3d4-e5f6-7890-abcd-ef1234567890
# Audit: fidelidad ARM completa
osirisjson-producer azure -S a1b2c3d4-e5f6-7890-abcd-ef1234567890 --purpose audit
Qué recopila el productor OSIRIS JSON para Microsoft Azure
El productor OSIRIS JSON para Microsoft Azure recopila un inventario completo de los tipos de recursos compatibles mediante Azure CLI en cada ejecución. La siguiente tabla agrupa lo que se consulta.
Redes
| Recurso de Microsoft Azure | Tipo OSIRIS JSON |
|---|---|
| Redes virtuales | network.vpc |
| Subredes | network.subnet |
| Interfaces de red | network.interface |
| Grupos de seguridad de red | network.security.group |
| Grupos de seguridad de aplicaciones | osiris.azure.asg |
| Tablas de rutas | osiris.azure.routetable |
| Direcciones IP públicas | osiris.azure.publicip |
| Balanceadores de carga (L4) | network.loadbalancer |
| Application Gateways (L7) | network.loadbalancer |
| Firewalls de Azure | network.firewall |
| Puertas de enlace NAT | osiris.azure.gateway.nat |
| Puertas de enlace de VNet (VPN / ExpressRoute) | osiris.azure.gateway.vnet |
| Circuitos ExpressRoute | osiris.azure.expressroute |
| Endpoints privados | osiris.azure.privateendpoint |
| Zonas DNS | osiris.azure.dns.zone |
| Zonas DNS privadas | osiris.azure.dns.privatezone |
Cómputo y almacenamiento
| Recurso de Microsoft Azure | Tipo OSIRIS JSON |
|---|---|
| Máquinas virtuales | compute.vm |
| Discos administrados | osiris.azure.disk |
| Snapshots administrados | osiris.azure.snapshot |
| Cuentas de almacenamiento | osiris.azure.storageaccount |
App Service / capa web
| Recurso de Microsoft Azure | Tipo OSIRIS JSON |
|---|---|
| App Service Plan | osiris.azure.appserviceplan |
| Web App | osiris.azure.webapp |
| Function App | osiris.azure.functionapp |
Enrutamiento de App Service: los sitios cuyo kind contiene functionapp se emiten como osiris.azure.functionapp; todos los demás sitios se emiten como osiris.azure.webapp.
Identidad y seguridad
| Recurso de Microsoft Azure | Tipo OSIRIS JSON |
|---|---|
| Key Vault | osiris.azure.keyvault |
| Container Registry | osiris.azure.containerregistry |
| User-Assigned Managed Identity | osiris.azure.managedidentity |
Respaldo y recuperación ante desastres
| Recurso de Microsoft Azure | Tipo OSIRIS JSON |
|---|---|
| Recovery Services Vault | osiris.azure.recoveryvault |
| Backup Vault (Azure Backup) | osiris.azure.backupvault |
Bases de datos
| Recurso de Microsoft Azure | Tipo OSIRIS JSON |
|---|---|
| SQL Server | osiris.azure.sqlserver |
| SQL Database | osiris.azure.sqldatabase |
| PostgreSQL Flexible Server | osiris.azure.postgresqlserver |
| MySQL Flexible Server | osiris.azure.mysqlserver |
| Cuenta de Cosmos DB | osiris.azure.cosmosaccount |
| Caché Redis | osiris.azure.redis |
Contenedores e integración
| Recurso de Microsoft Azure | Tipo OSIRIS JSON |
|---|---|
| Clúster de AKS | osiris.azure.aks.cluster |
| Pool de agentes de AKS | osiris.azure.aks.nodepool |
| Entorno administrado de Container App | osiris.azure.containerapp.environment |
| Container App | osiris.azure.containerapp |
| Grupo de contenedores / ACI | osiris.azure.containergroup |
| Namespace de Service Bus | osiris.azure.servicebus.namespace |
| Namespace de Event Hubs | osiris.azure.eventhubs.namespace |
| API Management Service | osiris.azure.apim |
| Front Door (Standard / Premium) | osiris.azure.frontdoor.profile |
Observabilidad
| Recurso de Microsoft Azure | Tipo OSIRIS JSON |
|---|---|
| Application Insights | osiris.azure.applicationinsights |
| Workspace de Log Analytics | osiris.azure.loganalytics |
Contención
| Recurso de Microsoft Azure | Tipo OSIRIS JSON |
|---|---|
| Grupos de recursos | container.resourcegroup |
Qué no se recopila intencionalmente
OSIRIS JSON define un formato JSON neutral respecto del proveedor para describir recursos de infraestructura, sus propiedades y sus relaciones topológicas; no es un formato de Infrastructure-as-Code ni algo similar. Puede leer más aquí: What is OSIRIS JSON. Lo siguiente queda intencionalmente fuera de alcance:
- Política de monitoreo: alert rules, action groups, metric alerts, scheduled query rules.
- Políticas de respaldo / retención dentro de Recovery Services Vault y Backup Vault (los vaults y las aristas hacia elementos protegidos se emiten; los cuerpos de las políticas no).
- Políticas de la capa de base de datos: SQL auditing, threat-detection, TDE, firewall rules, security-alert-policy.
- Políticas, productos, operaciones y named values de API Management.
- Rutas de Front Door, rule sets, endpoints y asociaciones de políticas WAF (el perfil se emite; el enrutamiento no).
- Secretos de Container App y variables de entorno de ACI.
- Enumeración de diagnostic settings por recurso (agregaría una llamada
azpor recurso). - Azure Front Door clásico (
Microsoft.Network/frontDoors, obsoleto). Microsoft.DBforPostgreSQL/serversheredado (servidor único, en fin de vida en la hoja de ruta de Azure).
Estructura de salida de OSIRIS JSON para 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": [ ... ]
}
}
Tipos de conexión
Las aristas de conexión usan los subtipos estándar de OSIRIS JSON v1.0 según specification chapter 5.2.3, para que los consumidores puedan distinguir las capas de la topología.
| Tipo de conexión OSIRIS JSON | Se usa para |
|---|---|
contains | Contención (subred dentro de la VNet, App Service Plan dentro del sitio, clúster de AKS dentro del pool de nodos, grupo de recursos dentro de la suscripción, SQL Server dentro de SQL Database, disco de origen dentro de Snapshot, VM dentro del disco adjunto) |
network | Conectividad de red genérica (NIC a subred, asociaciones de NSG, enlaces DNS, conexiones de gateway, App Insights a un área de trabajo, Web App a App Insights, AKS / Redis / ACI a subred, APIM a subred) |
network.peering | Peerings de VNet |
network.vpn | Conexiones de gateway VPN |
network.bgp | Conexiones de circuitos ExpressRoute |
dependency | Private Endpoint hacia un destino PaaS (Web App, Function App, Key Vault, Container Registry, Recovery Services Vault, clúster de AKS, Service Bus, Event Hubs, APIM) |
dependency.storage | Private Endpoint hacia Storage Account |
dependency.database | Private Endpoint hacia base de datos (SQL Server, Cosmos DB, Redis) |
Tipos de grupo
| Tipo de grupo OSIRIS JSON | Se usa para |
|---|---|
logical.subscription | Grupo de suscripción de nivel superior |
logical.resourcegroup | Grupos de grupos de recursos (hijos de la suscripción) |
container.region | Un grupo por cada provider.region distinto observado en la suscripción, agrupando todos los recursos de esa región. La región global y los recursos sin región se omiten (no están delimitados geográficamente). El token de frontera es <subscription-id>/<region>, por lo que los grupos nunca colisionan entre suscripciones. |
Tipos de recurso
Los tipos de recurso siguen la OSIRIS JSON v1.0 specification. Los tipos estándar se usan cuando están definidos; los tipos específicos de Azure usan el namespace osiris.azure.*.
Tipos estándar:
container.resourcegroup- Grupos de recursosnetwork.vpc- Redes virtualesnetwork.subnet- Subredesnetwork.interface- Interfaces de rednetwork.security.group- Grupos de seguridad de rednetwork.loadbalancer- Balanceadores de carga (L4 y L7 / Application Gateway)network.firewall- Firewalls de Azurecompute.vm- Máquinas virtuales
Extensiones (osiris.azure)
Los datos específicos de Azure que no se mapean a propiedades portables de OSIRIS JSON se emiten bajo el namespace de extensión osiris.azure. Esto sigue la especificación de OSIRIS JSON: properties contiene datos comunes / portables, extensions contiene datos profundos específicos del proveedor. Las extensiones solo se emiten con --purpose audit.
Las extensiones representativas incluyen:
| Tipo de recurso OSIRIS JSON | Campos de extensión seleccionados |
|---|---|
network.interface | enable_accelerated_networking, effective_routes[] |
network.security.group | security_rules[], default_security_rules[] |
osiris.azure.expressroute | sku, sku_tier, service_provider, peerings[] (tipo de peering BGP, estado, ASN del peer, ID de VLAN, prefijos de dirección) |
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 (área de trabajo de Log Analytics enlazada) |
osiris.azure.loganalytics | customer_id (UUID del área de trabajo usado por KQL; no es un secreto) |
Metadatos del proveedor
Cada recurso incluye provider.type con el tipo de recurso ARM nativo (por ejemplo, Microsoft.Network/virtualNetworks, Microsoft.Compute/virtualMachines). Los stubs entre suscripciones incluyen provider.subscription con el ID de la suscripción remota. Todos los recursos incluyen provider.source establecido en azure-cli.
ID de recursos
Los ID de recursos de Azure siguen el patrón azure::<ARM-resource-id>, utilizando el ID completo del recurso ARM como identificador nativo. Esto garantiza ID globalmente únicos y determinísticos que sobreviven a la correlación entre suscripciones.
Canonicalización de región
provider.region y metadata.scope.regions se canonicalizan a la forma slug de Azure (minúsculas, sin espacios). La CLI az devuelve location de forma inconsistente entre tipos de recurso: la mayoría de los recursos ARM usan westeurope / eastus2, mientras que los App Service Plans y Web Apps muestran la forma de visualización (West Europe). El productor normaliza al slug para que una suscripción de una sola región no aparezca como dos regiones en metadata.scope.regions.
Requisitos de RBAC
| Nivel de permiso | Qué se recopila |
|---|---|
| Reader | Todos los tipos de recurso, propiedades y extensiones (reglas NSG, peerings ER, conexiones de gateway, peerings de VNet, enlaces DNS, aristas de Private Endpoint hacia destinos, App Service hacia App Insights, recursos de AKS, contenedores, bases de datos, mensajería y observabilidad) |
Reader + effectiveRouteTable/action | Todo lo anterior + rutas efectivas de la NIC |
| Network Contributor / Owner | Conjunto de datos completo sin restricciones |
El productor prueba el permiso en la primera NIC y omite de forma segura la recopilación de rutas efectivas si el permiso es denegado. Todos los demás datos se recopilan sin importar eso.
Ejemplos
Suscripción individual
Vamos a explorar una sola suscripción en nuestro tenant y generar desde Microsoft Azure un documento OSIRIS JSON.
osirisjson-producer azure -S a1b2c3d4-e5f6-7890-abcd-ef1234567890 --purpose audit
Documento de salida OSIRIS JSON (recortado, --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 misma ejecución con el valor predeterminado --purpose documentation devuelve el mismo grafo de recursos, pero con los objetos properties y extensions eliminados de cada recurso, conexión y grupo, lo que lo hace adecuado para vistas topológicas de alto nivel y documentación.