Azure Collector
Discover and monitor Azure infrastructure
Early Access — The Azure collector is in Early Access. Functionality is complete but may receive updates based on feedback.
The Azure collector discovers and continuously monitors Azure infrastructure across compute, networking, storage, database, and serverless services. It connects to one or more Azure subscriptions via Entra ID Service Principals and periodically scans all regions, publishing configuration items and relationships for processing.
What Gets Discovered
The collector discovers 16 CI types across 6 Azure services:
| CI Type | Azure Service | Description |
|---|---|---|
azure.subscription | Subscription | Azure subscription (scope container) |
azure.resource_group | Resource Manager | Resource group (organizational container) |
azure.vm | Compute | Virtual machine |
azure.image | Compute | Custom VM image |
azure.vmss | Compute | VM Scale Set (definition) |
azure.vnet | Network | Virtual network |
azure.subnet | Network | VNet subnet |
azure.nsg | Network | Network Security Group |
azure.nic | Network | Network interface |
azure.load_balancer | Network | Azure Load Balancer |
azure.storage_account | Storage | Storage account |
azure.managed_disk | Compute | Managed disk |
azure.snapshot | Compute | Disk snapshot |
azure.sql_server | SQL Database | Logical SQL server |
azure.sql_database | SQL Database | Azure SQL Database |
azure.function_app | App Service | Azure Functions app |
Each resource's ARM name property is used as the CI name. Unlike AWS where many resources lack a native name and rely on Name tags, Azure resources always have an explicit name in the ARM response.
Prerequisites
- An Azure subscription
- An Entra ID (Azure AD) Service Principal with a client secret
- The Reader role or a custom role with the permissions listed below
The collector only makes read-only API calls. No write permissions are needed or used.
Create a Service Principal
az ad sp create-for-rbac --name "parascope-collector" --skip-assignmentSave the output. The values map to Parascope configuration fields:
| Output Field | Parascope Field |
|---|---|
appId | Client ID |
password | Client Secret |
tenant | Tenant ID |
RBAC Permissions
The collector needs read access to the resource types it collects. There are two approaches.
Option A: Built-in Reader Role
The simplest setup. The built-in Reader role at subscription scope grants read access to all resource metadata:
az role assignment create \
--assignee <client-id> \
--role "Reader" \
--scope "/subscriptions/<subscription-id>"This is the recommended approach for most deployments. Reader provides more permissions than the collector needs, but it is read-only and well-understood.
Option B: Custom Least-Privilege Role
If your security policy requires granting only the exact permissions needed, create a custom role:
{
"Name": "Parascope Collector",
"Description": "Read-only access to infrastructure metadata for Parascope CMDB",
"Actions": [
"Microsoft.Compute/virtualMachines/read",
"Microsoft.Compute/virtualMachineScaleSets/read",
"Microsoft.Compute/images/read",
"Microsoft.Compute/disks/read",
"Microsoft.Compute/snapshots/read",
"Microsoft.Network/virtualNetworks/read",
"Microsoft.Network/networkSecurityGroups/read",
"Microsoft.Network/networkInterfaces/read",
"Microsoft.Network/loadBalancers/read",
"Microsoft.Storage/storageAccounts/read",
"Microsoft.Sql/servers/read",
"Microsoft.Sql/servers/databases/read",
"Microsoft.Web/sites/read",
"Microsoft.Resources/subscriptions/read",
"Microsoft.Resources/subscriptions/resourceGroups/read"
],
"NotActions": [],
"AssignableScopes": [
"/subscriptions/<subscription-id>"
]
}Save the JSON to a file and create the role:
az role definition create --role-definition @parascope-role.json
az role assignment create \
--assignee <client-id> \
--role "Parascope Collector" \
--scope "/subscriptions/<subscription-id>"The collector handles AuthorizationFailed errors gracefully per resource type. If a permission is missing, that resource type is skipped with a warning while collection continues for other types.
Configuration
Each Azure subscription is configured as a separate Parascope source. Configure credentials and region filters for each source:
| Field | Required | Description |
|---|---|---|
| Tenant ID | Yes | Entra ID (Azure AD) tenant ID |
| Client ID | Yes | Service Principal application (client) ID |
| Client Secret | Yes | Service Principal client secret |
| Subscription ID | Yes | Target Azure subscription ID |
| Region Allowlist | No | Collect only these regions (comma-separated, e.g. westeurope,northeurope). Default: all regions |
| Region Denylist | No | Skip these regions. Ignored if Region Allowlist is set |
Unlike AWS where each region requires separate API calls, Azure Resource Manager APIs are subscription-scoped and return resources from all regions in a single response. Region filtering is applied as a post-fetch filter on the location field. It reduces ingested data but does not reduce API calls.
Multi-Subscription Setup
To monitor multiple Azure subscriptions, add each as a separate source in the collector configuration. Each source uses its own Service Principal credentials and has independent health tracking and circuit breaking. A misconfigured or unreachable subscription does not block collection from other healthy subscriptions.
A single Service Principal can be granted access to multiple subscriptions if they share the same Entra ID tenant. Create one source per subscription, using the same Client ID and Client Secret but different Subscription IDs.
Collected Resources
Subscriptions
The subscription CI serves as the containment root for all resources in that subscription. It captures the subscription ID, display name, and state (Enabled, Disabled, Warned).
Resource Groups
Resource groups provide the organizational layer between subscriptions and resources. Every Azure resource belongs to exactly one resource group. The collector captures the group name, location, provisioning state, and tags.
Virtual Machines
Configuration tracked in change history includes VM size, power state, OS type, OS disk configuration, data disk attachments, network interface references, availability zone, image reference, provisioning state, and tags.
Deallocated VMs are collected as active CIs. Azure distinguishes stopped (OS shutdown, still billed for compute) from deallocated (no compute billing). Both states represent resources that still exist and have configuration worth tracking.
Power state is obtained via the instance view expansion on the list_all() API call. For subscriptions with 500+ VMs, this expansion adds significant response latency.
Images
Only custom (user-created) images in the subscription are collected. Marketplace images, shared image gallery images, and community images are separate Azure APIs and are excluded. Configuration includes OS type, OS state (Generalized or Specialized), and source VM reference.
VM Scale Sets
VMSS resources are collected as definitions only. The collector captures the SKU (VM size), instance capacity, and upgrade policy mode (Manual, Rolling, Automatic). Individual VMSS instance VMs are not enumerated in this version, as they require a separate API call per scale set.
Virtual Networks
VNet configuration includes the address space (CIDR blocks), provisioning state, and tags. VNets contain their subnets via contains relationships.
Subnets
Each subnet captures its address prefix, parent VNet reference, and associated NSG reference. Subnets are linked to their parent VNet and serve as the target for NIC runs_on relationships.
Network Security Groups
Full inbound and outbound rule details are captured, including rule name, priority, protocol, direction, source and destination address prefixes, source and destination port ranges, and access action (Allow or Deny). Because security group rules define blast radius and compliance posture, changes to rules are tracked in change history.
Network Interfaces
NICs are first-class CIs in Azure, unlike AWS where network interfaces are implicit on EC2 instances. Each NIC captures its IP configurations, associated NSG, associated VM, MAC address, and tags. NICs carry the relationships between VMs and subnets (via has_attached and runs_on) and between VMs and NSGs (via uses).
Load Balancers
Configuration includes SKU (Basic, Standard, Gateway), frontend IP configurations, backend address pools, health probes, and load balancing rules.
Storage Accounts
Each storage account captures the SKU, kind (StorageV2, BlobStorage, etc.), access tier (Hot, Cool, Premium), provisioning state, primary service endpoints, and encryption configuration.
Managed Disks
Disk configuration includes SKU (Standard_LRS, Premium_LRS, etc.), size in GB, OS type (if OS disk), disk state (Attached, Unattached, Reserved), and provisioning state.
Snapshots
Each snapshot captures its source managed disk reference, disk size in GB, and provisioning state. Snapshots link back to their source disk via snapshot_of relationships.
SQL Servers
The logical SQL server CI captures the server name, FQDN, SQL version, state, and administrator login. SQL servers are containers for SQL databases, linked via contains relationships.
SQL Databases
Database configuration includes the SKU name (e.g. S0, P1, GP_S_Gen5_1), maximum size in bytes, collation, status, and parent server reference. The master system database is excluded.
Function Apps
Configuration includes the app kind, state (Running, Stopped), default hostname, runtime stack (python, node, dotnet, java), and OS type (Linux, Windows). Function apps are filtered by the kind field containing "functionapp" to exclude regular web apps.
Relationships
The collector maps the following relationships between Azure resources:
| Source | Relationship | Target | Derivation |
|---|---|---|---|
azure.subscription | contains | azure.resource_group | RG's subscription |
azure.resource_group | contains | azure.vm | Parsed from ARM resource ID |
azure.resource_group | contains | azure.vnet | Parsed from ARM resource ID |
azure.resource_group | contains | azure.nsg | Parsed from ARM resource ID |
azure.resource_group | contains | azure.storage_account | Parsed from ARM resource ID |
azure.resource_group | contains | azure.load_balancer | Parsed from ARM resource ID |
azure.resource_group | contains | azure.sql_server | Parsed from ARM resource ID |
azure.resource_group | contains | azure.function_app | Parsed from ARM resource ID |
azure.vnet | contains | azure.subnet | Parsed from subnet resource ID |
azure.vm | has_attached | azure.managed_disk | VM's data disk references |
azure.vm | has_attached | azure.nic | VM's network interface references |
azure.vm | created_from | azure.image | VM's image reference (custom images only) |
azure.vmss | uses | azure.nsg | VMSS network profile NSG reference |
azure.nic | runs_on | azure.subnet | NIC's IP configuration subnet |
azure.nic | uses | azure.nsg | NIC-level NSG reference |
azure.snapshot | snapshot_of | azure.managed_disk | Snapshot's source disk ID |
azure.sql_server | contains | azure.sql_database | Database's parent server |
azure.load_balancer | runs_on | azure.subnet | Frontend IP configuration subnet |
azure.function_app | runs_on | azure.resource_group | Function's resource group |
This gives you a navigable resource topology: subscription > resource group > resources, plus VNet topology (VNet > subnet > NIC > VM), NSG coverage, disk attachment chains, and SQL server hierarchy.
Why VMs connect to subnets through NICs: In Azure, network interfaces are independent resources with their own subnet bindings and NSG associations. The path from a VM to its subnet is vm > has_attached > nic > runs_on > subnet. There is no direct VM-to-subnet shortcut because the NIC carries the actual network configuration.
Cross-source correlation also links Azure resources to other Parascope sources:
azure.vmtokubernetes.node-- matched by private IP or hostname, linking Azure VMs to AKS backing nodesazure.sql_databasetopostgresql.server-- matched by SQL server FQDN endpoint, when the PostgreSQL collector monitors the same database
Troubleshooting
AuthenticationFailed
The Service Principal credentials are invalid. Verify that the Client ID, Client Secret, and Tenant ID are correct. Client secrets expire; check the expiration date in Entra ID under App registrations.
AuthorizationFailed
The Service Principal is missing permissions for the resource type in the error message. Verify the role assignment scope matches the target subscription. If using the custom role, check that the required action is included.
TooManyRequests (429)
Azure is throttling API requests. The collector retries automatically with exponential backoff via the Azure SDK's built-in retry policy. You do not need to take action. If collection is frequently slow due to throttling, consider increasing the collection interval.
SubscriptionNotFound
The Subscription ID in the source configuration is incorrect, or the Service Principal does not have access to that subscription. Verify the subscription ID and check that the role assignment exists.
No resources collected for a region
Region allowlist and denylist filter resources by the location field after fetching. Verify the region names match Azure's location identifiers (e.g., westeurope, eastus, northeurope) not display names (e.g., "West Europe").
Azure Portal Links
Parascope constructs deep links to the Azure Portal for every collected resource using the ARM resource ID:
https://portal.azure.com/#@/resource{resourceId}Click "Open in Azure Portal" on any Azure CI detail page to navigate directly to that resource in the portal.
Related Documentation
- Managing Collectors -- Collector health and configuration
- Collector Reference: Infrastructure -- Kubernetes, Proxmox, OpenStack, and Netbox
- Correlation Engine -- Cross-source relationship discovery
- CI Types -- Complete CI type reference