Skip to main content

Cloud Discovery

When DriftWise scans a cloud account, it uses each provider's native inventory API to enumerate every resource in one pass. You no longer choose which resource types to scan — DriftWise discovers the whole account, then classifies results into broad categories.

How It Works

Every scan goes through up to two phases:

PhaseWhat it doesWhen it runs
DiscoverySingle API call (paginated internally) that lists every resource visible to the account credentials.Always
EnrichmentFetches full per-resource properties. Required only when the discovery API returns identity without properties.AWS only

For GCP and Azure the discovery API returns full resource properties, so enrichment is skipped and resources are stored with enrichment_status = n/a.

Provider APIs

ProviderDiscovery APIEnrichment API
AWSResource Explorer 2 Search("*")CloudControl GetResource
GCPCloud Asset Inventory SearchAllResources— (properties returned from discovery)
AzureResource Graph Resources query— (properties returned from discovery)

All three APIs are account-wide and span every region and service the credential can see. Pagination is handled inside DriftWise — the scan worker makes as many calls as necessary and you receive the full result set.

AWS: Enabling Resource Explorer

Resource Explorer 2 must be enabled in the AWS account before DriftWise can discover resources. It's free to enable but requires a one-time setup.

  1. Open the Resource Explorer console in the region you want to use as the aggregator index.
  2. Click Turn on Resource ExplorerQuick setup (recommended).
  3. Wait for indexing to complete. Initial results typically appear within minutes; full indexing of a large account can take several hours.
  4. Confirm the aggregator shows all of your regions in the Indexes tab.

The region hosting the aggregator index must match the region field on the DriftWise credential — only the aggregator region can serve cross-region searches. If the credential points at a different region, the scan fails with a region-mismatch error that names the aggregator region. If Resource Explorer has not been enabled at all, the scan fails with Resource Explorer 2 is not enabled or has no default view.

Required IAM Permissions

DriftWise's AWS scanner needs:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"resource-explorer-2:Search",
"resource-explorer-2:ListIndexes",
"cloudformation:GetResource",
"sts:GetCallerIdentity"
],
"Resource": "*"
}
]
}

resource-explorer-2:ListIndexes is used on the error path to diagnose whether the aggregator lives in a different region than the credential — without it, a region mismatch degrades to a generic "not enabled" error.

cloudformation:GetResource, not cloudcontrol:GetResource

The Cloud Control API shares IAM namespace with CloudFormation — its service prefix is cloudformation. There is no cloudcontrol: IAM namespace. This policy also does not cover the per-service read permissions (s3:GetBucket*, ec2:DescribeInstances, etc.) that CloudControl re-checks when dispatching to each resource type's handler; attach ReadOnlyAccess or extend the statement above with the per-service Describe*/Get*/List* actions for every resource type you expect to enrich.

The managed ReadOnlyAccess policy is the easiest alternative — it covers all of the above plus the underlying per-service read actions. See AWS Cloud Account for the full credential setup.

GCP: Required Roles

Grant the DriftWise service account the Cloud Asset Viewer role at the project (or folder / organization) level:

gcloud projects add-iam-policy-binding $GCP_PROJECT \
--member="serviceAccount:<SA_EMAIL>" \
--role="roles/cloudasset.viewer"

roles/cloudasset.viewer covers the cloudasset.assets.searchAllResources permission used by discovery. See GCP Cloud Account for the full credential setup.

Azure: Required Roles

The service principal's Reader role at the subscription scope covers Resource Graph reads — no additional permissions are needed. A resource-group-scoped Reader will only return resources inside that group. See Azure Cloud Account for the full credential setup.

Resource Categories

Resources are normalized to one of eight broad categories, regardless of provider. Examples in the table below are grouped as AWS / GCP / Azure.

CategoryExamples
computeEC2, ECS, EKS / Compute Engine, GKE / Virtual Machines, AKS, Managed Disks
storageS3, EFS / Cloud Storage, Persistent Disk / Storage Accounts
databaseRDS, DynamoDB, ElastiCache, Redshift / Cloud SQL, Spanner, Bigtable, Memorystore / SQL Database, Cosmos DB, Azure Cache
networkVPC, Subnet, Security Group, ELB, Route 53, CloudFront / VPC Network, Firewall, Load Balancer / VNet, NSG, Load Balancer
iamIAM Role, IAM Policy, KMS Key, Secrets Manager, ACM / Service Account / RBAC, Managed Identity
serverlessLambda, Step Functions / Cloud Functions, Cloud Run / App Service, Azure Functions
messagingSQS, SNS, EventBridge, Kinesis / Pub/Sub / Service Bus, Event Hubs
otherAnything that does not match above — still stored and compared

Resource types outside the explicit mappings above (for example Azure Key Vault, Azure Event Grid, or Google Cloud KMS) currently fall under other. They are still tracked and drift-compared using their exact provider type — the category only affects filtering and risk classification.

Categories are used for filtering, risk classification, and plan noise matching. The underlying provider-specific type (for example AWS::EC2::Instance) is preserved alongside the category for exact-match drift detection.

Kubernetes Resources

Resources reported by the Kubernetes operator retain their fine-grained k8s/<kind> normalized type (for example k8s/deployment, k8s/service). They are not collapsed into the broad categories above — fine-grained typing is required for drift matching against K8s manifests.

Region Filtering

To scan only specific regions, pass filter_regions in the POST /orgs/:id/scans body (see the scans tag of the API reference for the full shape). Empty or omitted = scan every region the credential can see.

Behaviour by provider:

  • AWS — Resource Explorer returns every region visible to the aggregator index; DriftWise filters the result list to the requested regions before storage.
  • GCP — Cloud Asset Inventory returns every location; resources in a region or any zone within that region match the filter.
  • Azure — Resource Graph returns every location; results are filtered to the requested regions.

Pass an empty array or omit the field to scan every region the credential can see.

Enrichment Status

Every stored resource carries an enrichment_status:

StatusMeaning
noneDiscovered, not yet enriched. Transient — AWS only.
enrichedProperties populated from enrichment (AWS) or from discovery (GCP / Azure).
n/aProvider does not need enrichment. Default for GCP and Azure.
failedEnrichment was attempted but failed. The enrichment_failure_reason column explains why.

failed rows keep whatever identity data the discoverer returned — drift detection still works, but property-based checks may return incomplete results.

Failure Reasons

ReasonScopeMeaning
unsupported_identifierPer-resourceCloudControl does not support the resource's identifier shape. Permanent until AWS adds support.
get_resource_failedPer-resourceCloudControl returned an error (throttling, permission drift, resource deleted mid-scan). Usually transient.
scrub_failedPer-resourceThe property blob could not be safely redacted. Fail-closed: properties are dropped rather than risk leaking secrets.
credential_decrypt_failedBatch-wideThe credential blob could not be decrypted. Operator action needed.
credential_parse_failedBatch-wideCredential decrypted OK but failed provider-specific parsing.
enricher_call_failedBatch-wideThe enricher returned a fatal error for the whole batch.
marshal_failedBatch-wideEnrichment returned valid data but marshaling for storage failed.

Redaction (Scrubbing)

Cloud provider responses can contain embedded secrets — passwords in environment variables, API keys in tag values, bearer tokens in launch templates. Before property blobs are stored, DriftWise runs them through a pattern-based scrubber that redacts sensitive key names (password, api_key, secret, ...) and sensitive value shapes (AWS access key IDs, JWTs, bearer tokens). If the scrubber cannot parse the payload — usually because the JSON shape is unexpected — the resource is marked enrichment_status = failed with reason scrub_failed and the properties are dropped entirely. This is fail-closed on purpose: a resource with empty properties is a minor usability issue, a leaked secret is not.

Troubleshooting

AWS: Resource Explorer 2 is not enabled or has no default view

Resource Explorer has not been turned on in any region of the account, or the account has an index but no default view has been published. See AWS: Enabling Resource Explorer above — Quick setup creates both the aggregator index and a default view.

AWS: Resource Explorer is enabled in region X but the credential region is Y

The aggregator index lives in a different region than the one you configured on the DriftWise credential. Resource Explorer only serves cross-region searches from the aggregator region. Two options:

  • Re-create the DriftWise credential with region set to the aggregator region (recommended).
  • Publish a default view in the credential's region — this restricts results to that single region.

AWS: Many resources show enrichment_status = failed with reason unsupported_identifier

CloudControl does not support the ARN shape for that resource type. The resource is still tracked (identity and metadata) but its properties column will be empty. Permanent until AWS adds CloudControl support.

AWS: Resources show failed with reason get_resource_failed

Usually CloudControl throttling or a permission gap. The scan worker retries failed resources on the next scan. If it persists, confirm the credential has cloudformation:GetResource (the IAM prefix for Cloud Control API — there is no cloudcontrol: namespace) and the per-service read permission that CloudControl dispatches into (e.g. s3:GetBucket* for S3 buckets, ec2:DescribeInstances for EC2 instances). ReadOnlyAccess covers both.

GCP: Some resources missing from scan results

Cloud Asset Inventory has a propagation delay of up to several minutes after a resource is created. Re-run the scan, or let the next scheduled scan pick them up.

Azure: Scan returns 0 resources

The service principal's Reader role must be granted at the subscription (or management group) level — a resource-group-scoped Reader will only return resources inside that group.