Provider Connectors

Billing data

Get your negotiated Azure prices into LevelFour with billing reader on an Enterprise Agreement or Microsoft Customer Agreement, or read cost from a daily export on pay-as-you-go.

LevelFour prices every figure on what Azure charged you, actual and amortized, and never on list or retail prices. Where it reads that cost depends on how you buy Azure.

How you buy AzureWhere LevelFour reads costWhat you do
Enterprise Agreement (EA)Your enrollment, once LevelFour holds Enrollment readerGrant the billing role, below
Microsoft Customer Agreement (MCA)Your billing account, once LevelFour holds Billing account readerGrant the billing role, below
Pay-as-you-goA daily export in your own storageNothing beyond the connect command
Cloud Solution Provider (CSP)Each subscription, as your partner allowsAsk your partner, below

To check yours, run az billing account list --query "[].agreementType" -o tsv in Cloud Shell.

Negotiated prices on EA and MCA

Until LevelFour holds a billing role, it reads cost per subscription. That cost misses what Azure records only at the billing account.

Without a billing role, your Azure costs leave out reservation and savings plan purchases and Marketplace charges, and on an EA a subscription shows no cost at all unless your enrollment lets account owners view charges. Grant the billing role to see the whole invoice.

The connect command grants the billing role on its own when the person running it holds billing rights. Most engineers do not, so finance usually adds it afterwards.

The finance follow-up

Hand this to someone who manages your billing account: an Enterprise Administrator on an EA, or a Billing account owner or contributor on an MCA.

Get the command for a billing admin

In LevelFour, open Connect Providers > Azure and, on the Azure account, click Get the command for a billing admin. The command belongs to the same connection, so nothing you connected before changes.

Run it in Cloud Shell

The billing admin pastes the command into Azure Cloud Shell and picks the same subscriptions as the first run. The script finds the existing LevelFour app, adds a fresh secret, and grants the billing role on every billing account the admin manages.

On an MCA, run it in the directory that holds the billing account. Azure gives billing roles only to identities from that directory.

Check the output

The script ends with Connected. If Enrollment reader or Billing account reader shows under Not granted on the LevelFour page, the admin lacks the right to assign it. Have the account owner run it, or grant the role by hand.

Granting the role by hand

Find the LevelFour service principal's object ID first:

az ad sp list --display-name LevelFour --query "[0].id" -o tsv

In the Azure portal, open Cost Management + Billing, select your billing account, open Access control (IAM), and add LevelFour as Billing account reader.

The Azure portal cannot give an EA billing role to a service principal. Assign Enrollment reader through the billing API instead, as an Enterprise Administrator:

ENROLLMENT="YOUR_ENROLLMENT_NUMBER"
PRINCIPAL_ID="THE_OBJECT_ID_ABOVE"
TENANT_ID="$(az account show --query tenantId -o tsv)"
az rest --method put \
  --url "https://management.azure.com/providers/Microsoft.Billing/billingAccounts/$ENROLLMENT/billingRoleAssignments/$(cat /proc/sys/kernel/random/uuid)?api-version=2019-10-01-preview" \
  --body "{\"properties\": {\"principalId\": \"$PRINCIPAL_ID\", \"principalTenantId\": \"$TENANT_ID\", \"roleDefinitionId\": \"/providers/Microsoft.Billing/billingAccounts/$ENROLLMENT/billingRoleDefinitions/24f8edb6-1668-4659-b5e2-40bb5f3a7d7e\"}}"

The role ID 24f8edb6-1668-4659-b5e2-40bb5f3a7d7e is Azure's built-in Enrollment reader.

LevelFour picks up the role on its next check, and the following sync reads cost from the billing account.

Pay-as-you-go: the daily cost export

Azure offers no line-by-line cost report for a pay-as-you-go subscription, so the connect command sets up an export in your own subscription and LevelFour reads it from there. It creates:

WhatName
A resource group, in the region you chooselevelfour-cost-export
A storage account, standard and locally redundant, with public access offlf followed by 20 letters and digits
A private containerlevelfour-cost
Two daily exports per subscription, actual and amortized costlevelfour-actualcost and levelfour-amortizedcost, writing under exports/<subscription ID>
Storage Blob Data Reader for LevelFour, on that container only

The command asks which region should store the export, and suggests the one that holds most of your resource groups. Set LEVELFOUR_EXPORT_REGION before you paste the command to answer up front. The storage holds a few CSV files a day and costs cents a month.

The exports cover the subscriptions you chose to connect. For a management group, that means each subscription under it when the command runs, so run the command again from the LevelFour page after you add a pay-as-you-go subscription to the group.

Each export writes from the current month on. The command also asks Azure to run each export once for each of the 13 months before this one. Azure queues those runs, and LevelFour reads each month as its files land. It asks only once LevelFour has accepted the connection. If Cloud Shell listed past months Azure refused, run the command again from the LevelFour page, or export those months from the Azure portal under Cost Management > Exports.

Azure leaves Marketplace and commitment purchases out of pay-as-you-go cost data, so they do not appear in LevelFour either.

To set the export up by hand instead, create the same storage and exports in Cost Management > Exports, give LevelFour Storage Blob Data Reader on the container, then run the connect command once so LevelFour learns where the export writes.

Cloud Solution Provider

If you buy Azure through a CSP partner, Azure shows cost at retail rates, without the partner's discounts or credits, and only after your partner turns on cost visibility for your directory. Reservation usage shows at zero. Treat these figures as retail, and ask your partner for the invoice they bill you.

Confirming it worked

After the next sync, your Azure cost includes reservation, savings plan and Marketplace purchases, and the month's total matches your invoice. On a pay-as-you-go account, the first export lands within a day, and cost for the current month appears after the sync that follows.

Removing access

Billing role. On an MCA, remove LevelFour under Cost Management + Billing > Access control (IAM). On an EA, list the enrollment's role assignments with az rest --method get --url "https://management.azure.com/providers/Microsoft.Billing/billingAccounts/$ENROLLMENT/billingRoleAssignments?api-version=2019-10-01-preview", then send az rest --method delete to the one whose principalId is the LevelFour object ID.

Pay-as-you-go export. Delete both exports on each subscription the command exported, then the resource group that holds the storage. That group lives only in the subscription you ran the command in:

for SUBSCRIPTION in YOUR_SUBSCRIPTION_ID ANOTHER_SUBSCRIPTION_ID; do
  for EXPORT in levelfour-actualcost levelfour-amortizedcost; do
    az rest --method delete \
      --url "https://management.azure.com/subscriptions/$SUBSCRIPTION/providers/Microsoft.CostManagement/exports/$EXPORT?api-version=2023-07-01-preview"
  done
done
az group delete --name levelfour-cost-export --subscription "SUBSCRIPTION_YOU_RAN_THE_COMMAND_IN"

Troubleshooting

Not granted: Billing account reader or Not granted: Enrollment reader. The person who ran the command cannot assign billing roles. Have a billing account owner or Enterprise Administrator run it, or grant the role by hand.

Costs on an EA are zero or missing. Your enrollment hides charges from account owners and LevelFour holds no billing role. Grant Enrollment reader.

Pay-as-you-go costs never arrive. Check the run history of levelfour-actualcost in Cost Management > Exports. A failed run usually means the Microsoft.CostManagementExports resource provider is not registered on the subscription. Register it with az provider register --namespace Microsoft.CostManagementExports and run the export again.

A Not granted: Cost export storage line. You lack rights to create a resource group or storage account in the subscription Cloud Shell is set to. Switch to one you own with az account set --subscription <id>, then run the command again from the LevelFour page.

Next

  • Commitments reads your reservations and savings plans through the same billing role
  • Connect Azure covers the connect command and every role it grants

On this page

Ask the FinOps Agent about your cloud spend