Skip to content
cloudemu
Services

Resource Discovery

A cross-service inventory engine that answers Resource Explorer, Resource Graph, and Cloud Asset Inventory queries over your emulated resources

aws Resource Explorer 2azr Resource Graphgcp Cloud Asset Inventory

Emulates the cross-service inventory APIs — the "list everything I have, filtered by service, type, region, or tag" layer that Resource Explorer, Resource Graph, and Cloud Asset Inventory provide. An engine walks your emulated compute, networking, storage, database, serverless, Databricks, Kubernetes, and relational-database resources and answers those queries over normalized, cross-cloud records.

Reach for it in tests when your code enumerates resources, reconciles inventory, or drives tag-based automation — so you can assert on what's discoverable without a real account. Every provider auto-wires a ResourceDiscovery engine over its core drivers, so anything you create through those services is immediately discoverable, with no separate registration step.

ProviderServiceSDK-compatDriver
AWSResource Explorer 2 + Resource Groups Tagging API✓ Liveaws.ResourceDiscovery
AzureResource Graph (armresourcegraph, KQL)✓ Liveazure.ResourceDiscovery
GCPCloud Asset Inventory (cloudasset/v1)✓ Livegcp.ResourceDiscovery

Query with the real SDK#

Wire the engine into the server alongside your other drivers, then point the real Resource Explorer client at it — this is the path that exercises the actual discovery API and its query-string filters:

import (
    "github.com/aws/aws-sdk-go-v2/service/resourceexplorer2"
    "github.com/stackshy/cloudemu/v2"
    awsserver "github.com/stackshy/cloudemu/v2/server/aws"
)

cloud := cloudemu.NewAWS()
ts := httptest.NewServer(awsserver.New(awsserver.Drivers{
    EC2: cloud.EC2, VPC: cloud.VPC, S3: cloud.S3,
    ResourceDiscovery: cloud.ResourceDiscovery,
    AccountID:         "123456789012",
    Region:            "us-east-1",
}))

client := resourceexplorer2.NewFromConfig(cfg, func(o *resourceexplorer2.Options) {
    o.BaseEndpoint = aws.String(ts.URL)
})

client.Search(ctx, &resourceexplorer2.SearchInput{
    QueryString: aws.String("service:s3 tag.env:prod"),
})

Wire the engine into azureserver.Drivers{ResourceDiscovery: …, SubscriptionID: …} or gcpserver.Drivers{ResourceDiscovery: …, ProjectID: …} for the Azure and GCP equivalents.

Query with the Portable Go API#

When you don't need the SDK round-trip, query the engine directly — ListAll returns everything, List applies structured filters, and GetTagKeys surfaces the tag namespace for tag-driven tests:

import "github.com/stackshy/cloudemu/v2/services/resourcediscovery"

all, _ := aws.ResourceDiscovery.ListAll(ctx)

results, _ := aws.ResourceDiscovery.List(ctx, resourcediscovery.Query{
    Services: []string{"compute"},
    Type:     "Instance",
    Region:   "us-east-1",
    Tags:     map[string]string{"env": "prod"},
})

keys, _ := aws.ResourceDiscovery.GetTagKeys(ctx)

What it inventories#

The engine reads live state from the service drivers and emits normalized, cross-cloud resource records:

Portable serviceResource typeAWS · Azure · GCP
computeInstanceEC2 · VM · Compute Engine
networkingVPC / Subnet / SecurityGroupVPC · VNet · Network (+ NSG / Firewall)
storageBucketS3 · Storage · GCS
databaseTableDynamoDB · Cosmos DB · Firestore
serverlessFunctionLambda · Functions · Cloud Functions
databricksWorkspace— · Databricks · —
kubernetesCluster / NodeGroupEKS · AKS · GKE (nodegroups / node pools / agent pools)
relationaldbDatabaseRDS / Aurora · — · —

Kubernetes clusters and their node groups are surfaced through a KubernetesClusters discovery adapter each provider wires over its cluster mock. Relational databases follow the same pattern via a RelationalDatabases adapter — AWS RDS/Aurora instances, clusters, and snapshots surface through Resource Explorer 2 (filter service:rds); GCP Cloud SQL and Azure SQL discovery are not yet wired.

Behavior & fidelity#

BehaviorWhat happens
Live, not cachedThe engine reads current driver state on every query, so a resource is discoverable the moment you create it and gone the moment you delete it — no reindex step.
Provider-native query surfacesEach provider speaks its own query dialect over the same inventory (dialects below).
Azure cost-field projectionEach Resource Graph row also projects the sku and properties a cost tool prices on, so a value set at create time round-trips over the real armresourcegraph SDK (types below).

Each provider's filter dialect:

  • AWSservice:, tag.<key>:<value>, and region: across Resource Explorer 2 and the Resource Groups Tagging API.
  • Azure — a KQL subset over the Resources table: where type == / in~ (…), where location ==, where tags['k'] ==, and | limit / | take.
  • GCP — Cloud Asset Inventory filters service:, assetType:, location:, and labels.<k>:<v>.

Cost-relevant fields projected on each Azure type:

Azure typeProjected fields
microsoft.compute/virtualmachinespriority/Spot, licenseType, OS type, sku.name, zones
microsoft.compute/disksIOPS, throughput, sizeGB, tier
.../virtualmachinescalesetssku + nested VM profile
microsoft.network/publicipaddressessku, allocation method
.../virtualnetworks, .../subnetsaddress space
microsoft.sql/managedinstances, .../servers, .../servers/databasessku, vCores, tier, storage, version, zone-redundant
microsoft.dbformysql / dbforpostgresql/flexibleserverssku/tier, version, storage, HA mode
microsoft.containerservice/managedclusters (+ /agentpools)tier, powerState, k8s version, vmSize, Spot, count, mode
microsoft.databricks/workspacessku, workspaceId, provisioning state
microsoft.storage/storageaccountsredundancy, kind, accessTier
microsoft.documentdb/databaseaccountsoffer type, serverless capability, free tier
microsoft.web/serverfarmsApp Service plan pricing tier

Values are seeded through the portable driver configs and optional enrichment capabilities — e.g. VolumeConfig.IOPS/Throughput/Tier, InstanceConfig.OSType/Priority/LicenseType/Zones, the AKS Tier/ScaleSetPriority inputs, and BucketAttributes / TableAttributes.

SDK-compat — Live#

Real Resource Explorer 2, Resource Graph, and Cloud Asset Inventory clients drive it end-to-end; the same queries run through the Portable Go API above.

ProviderDiscovery surface
AWSResource Explorer 2 + Resource Groups Tagging API
AzureResource Graph (armresourcegraph, KQL)
GCPCloud Asset Inventory (cloudasset/v1)

See SDK-Compat for the full per-operation list.

On this page

On this page