Skip to content

[BUG] resourceGroups/{rg}/resources omits Compute, ContainerService, ContainerRegistry, Cache and every DB provider #269

Description

@MichaelDanCurtis

Service

ARM (Microsoft.Resources) — the resource-group resource index.

Azure API Action

Resources - List By Resource Group
GET /subscriptions/{sub}/resourceGroups/{rg}/resources?api-version=2021-04-01

Expected behavior

Real Azure returns every resource in the group, whatever provider owns it.

Actual behavior

The listing returns only the providers ArmHandler knows about: its own inline Storage / Key Vault / Web state, plus Network, API Management, Managed Identity, plus whatever implements the CDI ResourceIndexContributor interface — and AciHandler is currently the only implementation.

So a resource group holding a VM comes back without the VM, even though the same VM answers a direct GET with 200 and appears in the type-scoped list under /providers/Microsoft.Compute/virtualMachines.

Providers with a management plane in floci-az that never reach the index:

Provider Handler
Microsoft.Compute/virtualMachines VmHandler
Microsoft.ContainerService/managedClusters AksHandler
Microsoft.ContainerRegistry/registries AcrHandler
Microsoft.Cache/Redis RedisHandler
Microsoft.DBforPostgreSQL/flexibleServers PostgresHandler
Microsoft.DBforMySQL/flexibleServers MySqlHandler
Microsoft.DBforMariaDB/servers MariaDbHandler
Microsoft.Sql/servers SqlHandler

Reproduction

docker run -d --rm --name floci-az-repro -p 4577:4577 \
  floci/floci-az@sha256:6566c73b8f4b6e3ef90322c8c84a47258bb1ca13c82ea1d40027f7af11247e30

B=http://localhost:4577
SUB=00000000-0000-0000-0000-000000000001
RG=repro-rg

curl -s -X PUT "$B/subscriptions/$SUB/resourceGroups/$RG?api-version=2021-04-01" \
  -H 'Content-Type: application/json' -d '{"location":"eastus"}'

curl -s -X PUT "$B/subscriptions/$SUB/resourceGroups/$RG/providers/Microsoft.Compute/virtualMachines/repro-vm?api-version=2024-11-01" \
  -H 'Content-Type: application/json' -d '{
    "location":"eastus",
    "properties":{
      "hardwareProfile":{"vmSize":"Standard_D2s_v3"},
      "storageProfile":{"imageReference":{"publisher":"Canonical","offer":"0001-com-ubuntu-server-jammy","sku":"22_04-lts","version":"latest"},
                        "osDisk":{"createOption":"FromImage","name":"repro-osdisk"}},
      "osProfile":{"adminUsername":"azureuser","computerName":"reprovm"}}}'

curl -s -X PUT "$B/subscriptions/$SUB/resourceGroups/$RG/providers/Microsoft.Storage/storageAccounts/reprosa?api-version=2023-01-01" \
  -H 'Content-Type: application/json' -d '{"location":"eastus","sku":{"name":"Standard_LRS"},"kind":"StorageV2"}'

# The VM exists and is listed at the type-scoped level:
curl -s -o /dev/null -w 'direct GET  -> HTTP %{http_code}\n' \
  "$B/subscriptions/$SUB/resourceGroups/$RG/providers/Microsoft.Compute/virtualMachines/repro-vm?api-version=2024-11-01"
curl -s "$B/subscriptions/$SUB/resourceGroups/$RG/providers/Microsoft.Compute/virtualMachines?api-version=2024-11-01" \
  | python3 -c 'import sys,json; print("type list  ->", [r["name"] for r in json.load(sys.stdin)["value"]])'

# ...but the resource-group aggregation does not contain it:
curl -s "$B/subscriptions/$SUB/resourceGroups/$RG/resources?api-version=2021-04-01" \
  | python3 -c 'import sys,json; print("rg index   ->", [(r["name"], r["type"]) for r in json.load(sys.stdin)["value"]])'

Output on the pinned release above:

direct GET  -> HTTP 200
type list  -> ['repro-vm']
rg index   -> [('reprosa', 'Microsoft.Storage/storageAccounts')]

The storage account is there. The VM is not.

Impact

  • ResourceIndexContributor's own javadoc records why this listing matters: "The azurerm provider calls that listing before deleting a resource group to verify it is empty; a service that skips registration lets terraform destroy remove a group whose resources still exist." That is exactly the state VMs, AKS clusters, registries, Redis caches and every DB server are in today.
  • Anything that enumerates a group generically rather than per-type — az resource list -g, the Resource Management SDKs, drift/verification tooling that diffs deployed state against expected — sees an incomplete group and reports real resources as missing.

Root cause

ArmHandler.handleResourceGroupBranch builds the index from a hand-maintained set of subsystems plus Instance<ResourceIndexContributor>. The interface exists precisely so a service can opt in with one method, but only ACI ever did — every service added since (and every service that predates the interface) is silently absent.

Related, not covered here

GET /subscriptions/{sub}/resources (subscription-level) returns only Key Vaults and API Management services, so on an estate with neither it returns an empty list even when the subscription holds resources. Same family of gap, different endpoint; happy to file separately.

Environment

  • floci-az version / image tag: floci/floci-az@sha256:6566c73b8f4b6e3ef90322c8c84a47258bb1ca13c82ea1d40027f7af11247e30
  • Also reproduced against main at a9e4799 with a @QuarkusTest + RestAssured case
  • How you're running floci-az: Docker, and ./mvnw test

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    armAzure Resource Manager (ARM)bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions