> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tensorcost.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Connect Azure infrastructure cost

> Connect an Azure subscription with no client secret on either side — needs a directory admin and a subscription owner, about 10 minutes combined.

# Connect Azure infrastructure cost

This connects an Azure subscription for infrastructure spend. It's built to store **no long-lived customer secret at all** — not a client secret, not an API key. TensorCost authenticates using its own multi-tenant Entra (Azure AD) application; what your subscription grants is a role assignment to that application's identity in your tenant, not a credential you hand over.

<Warning>
  **This flow needs two different people**, and there's no way around it today: a **directory admin** to register TensorCost's application in your tenant, and a **subscription owner** to deploy the setup template. They can be the same person in a small organization, but in most companies they aren't — line up both before you start, rather than discovering the gap partway through.
</Warning>

## What TensorCost reads

A daily **FOCUS** (FinOps Open Cost and Usage Specification — an industry-standard billing format) export of your subscription's Cost Management data, written to a storage account the setup template creates. TensorCost reads that export; it has no other way to see your Azure spend.

## Prerequisites

* **A directory admin** — someone with the Application Administrator or Cloud Application Administrator role in your Entra tenant, and access to the Azure CLI (`az`).
* **A subscription owner** — someone who can deploy a Bicep template (Azure's equivalent of a CloudFormation template) into the subscription (Owner role, or User Access Administrator + Cost Management Contributor).
* TensorCost's Application (client) ID, shown in the connect form itself (step 1 below) — you don't need to look this up anywhere else.

## Steps

<Steps>
  <Step title="Open the connect form">
    **Build → Connect**, Cloud tab → **Microsoft Azure** → **Connect →**. The form shows TensorCost's Application ID and walks the same three steps below.
  </Step>

  <Step title="Directory admin: register TensorCost's application">
    Have your directory admin run, in a terminal with the Azure CLI signed in to your tenant:

    ```bash theme={null}
    az ad sp create --id <TensorCost-App-Id>
    ```

    This creates a service principal for TensorCost's application **in your tenant only**. It grants no access by itself — it's the equivalent of installing an app, not authorizing it to do anything yet.

    Then resolve that service principal's object ID — you'll need it for the next step:

    ```bash theme={null}
    az ad sp show --id <TensorCost-App-Id> --query id -o tsv
    ```
  </Step>

  <Step title="Subscription owner: deploy the setup template">
    Whoever owns the subscription deploys a small Azure template (Bicep — Azure's equivalent of a CloudFormation template) using the object ID from the previous step as `principalObjectId`. Use the **Deploy in Azure Portal** link the connect form shows (it points at the correct template for your environment — don't hardcode a template URL of your own), or the equivalent Azure CLI deployment if you prefer.

    The template creates:

    * A storage account and blob container.
    * A daily FOCUS-format Cost Management export, writing into that container.
    * Two read-only role assignments to TensorCost's service principal: **Cost Management Reader** on the subscription, and **Storage Blob Data Reader** on the export container.

    Note the storage account name and container name from the deployment outputs — you'll paste them in the next step.
  </Step>

  <Step title="Paste the values back and verify">
    Back in the connect form, fill in:

    | Field                              | Where it comes from                                                    |
    | ---------------------------------- | ---------------------------------------------------------------------- |
    | Azure Tenant ID                    | Your Entra directory (tenant) ID                                       |
    | Subscription ID                    | The subscription you deployed into                                     |
    | Cost export storage account        | The template's `storageAccountName` output                             |
    | Cost export container              | The template's `containerName` output                                  |
    | Cost export path prefix (optional) | Only if you changed the export's folder path from the template default |

    Click **Verify**, then **Connect**.
  </Step>
</Steps>

## Why there's no client secret

TensorCost authenticates with its own application's credentials against your tenant, using the role assignments your subscription owner just granted — there's nothing on your side to store, rotate, or leak. The service principal created in step 2 is just an identity for RBAC to point at; the actual authentication secret belongs to TensorCost, lives in TensorCost's own tenant, and is rotated on TensorCost's schedule, invisibly to you.

## What Verify actually checks

Verify performs a real connectivity check, in two parts, and fails closed if either one doesn't hold:

1. **Subscription access** — mints a token and confirms it can read the subscription (proves the Cost Management Reader assignment landed).
2. **Export container access** — confirms it can list the blob container named in your form (proves the Storage Blob Data Reader assignment landed, and that the storage account/container actually exist).

An **empty** container is a pass, not a failure — a brand-new export can take up to 24 hours to write its first file, and that's expected. A **missing** container, or one the service principal can't read, is a hard fail.

## Common failures

| What you see                                                            | Cause                                                                                                                              | Fix                                                                                           |
| ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| Azure AD couldn't find a tenant matching this ID                        | Typo in the Tenant ID                                                                                                              | Re-check the Directory (tenant) ID in the Entra admin center                                  |
| The service principal doesn't have permission to read this subscription | The Cost Management Reader assignment didn't complete, or wasn't applied to this subscription                                      | Confirm the template deployed successfully into the right subscription                        |
| TensorCost couldn't find a subscription with this ID                    | Typo in the Subscription ID                                                                                                        | Re-check against the Azure Portal subscription overview                                       |
| The Cost Management export storage container does not exist             | The template hasn't been deployed yet, or the storage account/container name doesn't match what you typed                          | Confirm the template deployment succeeded and copy the exact output names                     |
| The service principal can't read the export's storage container         | Storage Blob Data Reader is missing — Cost Management Reader alone doesn't cover blob storage, they're different permission planes | Redeploy the template, or check the role assignment on the storage account/container directly |
| No storage account named "…" exists                                     | Storage account name typo                                                                                                          | Re-copy the exact `storageAccountName` output from the template deployment                    |

## What this does not fix

The two-person requirement is a real limitation today, not a copy problem we've smoothed over — TensorCost cannot yet do both the app registration and the template deployment as a single step for you. If you're not the directory admin or the subscription owner yourself, expect to coordinate with whoever is before you can complete this connection.
