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.
| Provider | Service | SDK-compat | Driver |
|---|---|---|---|
| AWS | Resource Explorer 2 + Resource Groups Tagging API | ✓ Live | aws.ResourceDiscovery |
| Azure | Resource Graph (armresourcegraph, KQL) | ✓ Live | azure.ResourceDiscovery |
| GCP | Cloud Asset Inventory (cloudasset/v1) | ✓ Live | gcp.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 service | Resource type | AWS · Azure · GCP |
|---|---|---|
compute | Instance | EC2 · VM · Compute Engine |
networking | VPC / Subnet / SecurityGroup | VPC · VNet · Network (+ NSG / Firewall) |
storage | Bucket | S3 · Storage · GCS |
database | Table | DynamoDB · Cosmos DB · Firestore |
serverless | Function | Lambda · Functions · Cloud Functions |
databricks | Workspace | — · Databricks · — |
kubernetes | Cluster / NodeGroup | EKS · AKS · GKE (nodegroups / node pools / agent pools) |
relationaldb | Database | RDS / 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#
| Behavior | What happens |
|---|---|
| Live, not cached | The 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 surfaces | Each provider speaks its own query dialect over the same inventory (dialects below). |
| Azure cost-field projection | Each 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:
- AWS —
service:,tag.<key>:<value>, andregion:across Resource Explorer 2 and the Resource Groups Tagging API. - Azure — a KQL subset over the
Resourcestable:where type ==/in~ (…),where location ==,where tags['k'] ==, and| limit/| take. - GCP — Cloud Asset Inventory filters
service:,assetType:,location:, andlabels.<k>:<v>.
Cost-relevant fields projected on each Azure type:
| Azure type | Projected fields |
|---|---|
microsoft.compute/virtualmachines | priority/Spot, licenseType, OS type, sku.name, zones |
microsoft.compute/disks | IOPS, throughput, sizeGB, tier |
.../virtualmachinescalesets | sku + nested VM profile |
microsoft.network/publicipaddresses | sku, allocation method |
.../virtualnetworks, .../subnets | address space |
microsoft.sql/managedinstances, .../servers, .../servers/databases | sku, vCores, tier, storage, version, zone-redundant |
microsoft.dbformysql / dbforpostgresql/flexibleservers | sku/tier, version, storage, HA mode |
microsoft.containerservice/managedclusters (+ /agentpools) | tier, powerState, k8s version, vmSize, Spot, count, mode |
microsoft.databricks/workspaces | sku, workspaceId, provisioning state |
microsoft.storage/storageaccounts | redundancy, kind, accessTier |
microsoft.documentdb/databaseaccounts | offer type, serverless capability, free tier |
microsoft.web/serverfarms | App 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.
| Provider | Discovery surface |
|---|---|
| AWS | Resource Explorer 2 + Resource Groups Tagging API |
| Azure | Resource Graph (armresourcegraph, KQL) |
| GCP | Cloud Asset Inventory (cloudasset/v1) |
See SDK-Compat for the full per-operation list.