While working with Terraform on HashiCorp Cloud Platform (HCP) and attempting to leverage the AzAPI provider, I ran into a subtle but important issue related to authentication.

Normally, when working locally or in traditional CI/CD environments, I’ve grown accustomed to the AzAPI provider relying on the AzureRM provider’s authentication context. But in HCP Stacks, that behavior doesn’t carry over seamlessly.

The Typical Setup

When using the AzAPI provider in combination with AzureRM, it’s common to let AzAPI inherit the authentication context from AzureRM. In this conventional setup, the provider declarations are usually as minimal as:

provider "azurerm" {
  features {}
}

provider "azapi" {}

This works smoothly because AzAPI, by default, can piggyback on AzureRM’s credentials — especially when using mechanisms like Azure CLI or environment variables. However, this implicit credential sharing doesn’t apply in all contexts.

The HCP Terraform Stacks Case

When trying to apply a similar pattern within an HCP Terraform Stack, I set up my providers like this:

provider "azurerm" "this" {
  config {
    features {}

    use_cli = false

    use_oidc        = true
    oidc_token      = var.identity_token
    client_id       = var.client_id
    subscription_id = var.subscription_id
    tenant_id       = var.tenant_id
  }
}
provider "azapi" "this" {}

At first glance, this configuration looks reasonable — especially if you’re accustomed to AzAPI leveraging AzureRM’s context. However, it results in the following error when attempting to access an existing resource:

Error: Failed to retrieve resource
on src/terraform/shared/ai.tf line 10, in resource "azapi_resource" "ai_foundry":
resource "azapi_resource" "ai_foundry" {
checking for presence of existing Resource: (ResourceId "/subscriptions/f716a567-edba-413c-baf4-52b493c5b8f9/resourceGroups/rg-ro-engine-processor-dev-shared/providers/Microsoft.CognitiveServices/accounts/aif-fggjb8yw" / Api Version "2025-06-01"): ChainedTokenCredential: failed to acquire a token.
Attempted credentials:
 AzureCLICredential: Azure CLI not found on path

This clearly indicates that the AzAPI provider is falling back to trying Azure CLI for authentication — even though AzureRM is successfully using OIDC. That’s the root of the problem.

The Missing Piece: Explicit AzAPI Configuration

Unlike in local development or traditional pipeline engines like Azure DevOps or GitHub Actions — like I am used to — HCP Terraform requires each provider to be configured explicitly. The AzAPI provider does not automatically inherit the OIDC token or client details from AzureRM. To fix the issue, AzAPI needs to be configured with the same OIDC settings:

provider "azapi" "this" {
  config {
    use_oidc        = true
    oidc_token      = var.identity_token
    client_id       = var.client_id
    subscription_id = var.subscription_id
    tenant_id       = var.tenant_id
  }
}

This resolved the error immediately, allowing AzAPI to authenticate using the same identity as AzureRM under HCP’s OIDC-based workflow.

Lessons Learned

This was a subtle issue — one that’s easy to overlook if you’re used to the convenience of local environments where AzAPI authentication is often implicit. The key takeaway is that in HCP Terraform Stacks, every provider that communicates with Azure must be explicitly configured with OIDC parameters. There’s no automatic inheritance between providers, even if they’re targeting the same subscription.

Understanding this behavior is essential when transitioning Terraform workloads to HCP. It’s a small configuration detail, but without it, AzAPI simply can’t acquire the token it needs, leading to frustrating and cryptic errors.

Conclusion

When using AzAPI in HCP Stacks, remember to treat it as a first-class citizen in terms of authentication. It can’t rely on AzureRM’s credentials and must be configured explicitly with the same OIDC values. This aligns with Terraform’s provider model and ensures consistent behavior across environments — local, CI/CD, or HCP.

Once configured properly, AzAPI works just as expected, and the experience is as seamless as it is in other contexts.

Alt