> For the complete documentation index, see [llms.txt](https://docs.north.cloud/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.north.cloud/docs/getting-started/quickstart/azure-onboarding.md).

# Azure Onboarding

Learn how to integrate your Azure account with North.Cloud

This process creates a read-only identity in your tenant, a storage account to hold your cost exports, and three daily Cost Management exports. North stores no secrets and no credentials.

## Before You Start

{% hint style="info" %}
Prerequisites:

* [ ] If you do not have an account, create a free account first at [app.north.cloud](https://app.north.cloud).
* [ ] Confirm you hold the Azure roles listed below. Ask your Azure administrator if you are not sure.
* [ ] Collect your Subscription and your Billing Account ID.
* [ ] Ask your North representative for the WIF Subject and the WIF Audience.
  {% endhint %}

### Roles You Need

The person who runs the onboarding must hold the following roles.

| Role                                                                                 | Scope                 | Why it is needed                                                                                                                |
| ------------------------------------------------------------------------------------ | --------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| Application Administrator, Application Developer, or Cloud Application Administrator | Entra ID, tenant-wide | Creates the App Registration. Configures the federated identity credential.                                                     |
| Billing Account Owner or Billing Account Contributor                                 | Billing account       | Creates the Cost Management exports. Assigns Cost Management Reader at the billing scope.                                       |
| Contributor or Owner                                                                 | Target subscription   | Creates the resource group, the storage account, and the blob container.                                                        |
| Owner or User Access Administrator                                                   | Tenant root           | Assigns the three tenant-level roles: Reservations Reader, Savings Plan Reader, and Reader on the tenant-root management group. |

Contributor and Billing Account Owner cannot write role assignments at the tenant root. Some tenants also need a Global Administrator to [elevate access](https://learn.microsoft.com/azure/role-based-access-control/elevate-access-global-admin) before the tenant-root management group can be assigned.

`Microsoft.Authorization/roleAssignments/write` is in Owner. It is not in Contributor. You must hold it at the scope where each role is assigned. Subscription Owner covers the Storage Blob Data Reader grant only. Cost Management Reader needs the billing-account role. The three tenant-root roles need the tenant-scoped role.

[Azure permissions](/docs/getting-started/permissions-required/azure-permissions.md) lists every action the onboarding performs, and every permission North receives.

### How to Verify Your Roles

#### 1. Entra ID: App Registration Permissions

Go to **entra.microsoft.com > Users > your user > Assigned Roles**. Confirm you hold Application Administrator, Application Developer, or Cloud Application Administrator. The role lets you create App Registrations, Service Principals, and Federated Identity Credentials.

<figure><img src="https://1793025303-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeLw7hj1pxE38VmG1sYVW%2Fuploads%2F1gnKT2H9HfL1grZ2NJ2f%2Fentra-assigned-roles.png?alt=media&#x26;token=58b4522d-fccc-4cfc-a6ad-9c948af999c6" alt=""><figcaption></figcaption></figure>

To check the exact permissions, click the role name. Under **Description**, confirm the role includes:

* `microsoft.directory/applications/create`
* `microsoft.directory/applications/credentials/update`
* `microsoft.directory/servicePrincipals/create`

#### 2. Billing Account: Cost Management Permissions

Go to **portal.azure.com > Cost Management + Billing > Access Control (IAM)**. Confirm you hold Billing Account Owner or Billing Account Contributor. Your Billing Account ID is under **Properties** on the same page.

<figure><img src="https://1793025303-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeLw7hj1pxE38VmG1sYVW%2Fuploads%2FVjVydf5qYzMOsDOUvax3%2Fbilling-account-access.png?alt=media&#x26;token=fa0b07b1-0c44-45a6-aa44-81c3aba0c9f5" alt=""><figcaption></figcaption></figure>

The role lets you create Cost Management exports and assign Cost Management Reader to the App Registration. To confirm, click your role assignment and check that it includes:

* `Microsoft.CostManagement/exports/write` (create exports)
* `Microsoft.Authorization/roleAssignments/write` (assign roles at billing scope)

#### 3. Subscription: Resource Creation Permissions

Go to **portal.azure.com > Subscriptions > your subscription > Access control (IAM) > View my access**. Confirm you hold Owner or Contributor.

<figure><img src="https://1793025303-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeLw7hj1pxE38VmG1sYVW%2Fuploads%2FAmfUaE7t5EiuDnrADSPF%2Fsubscription-access.png?alt=media&#x26;token=608f0e78-0768-438b-ba59-c14cba26115d" alt=""><figcaption></figcaption></figure>

To check the exact permissions:

1. Go to **Subscriptions > your subscription > Access control (IAM) > Roles**.
2. Search for your role, for example Contributor.
3. Click the role name, then click **Permissions**.
4. Confirm the list includes:
   1. `Microsoft.Resources/subscriptions/providers/register/action` (register resource providers)
   2. `Microsoft.Resources/subscriptions/resourceGroups/write` (create resource groups)
   3. `Microsoft.Storage/storageAccounts/write` (create storage accounts)
   4. `Microsoft.Storage/storageAccounts/blobServices/containers/write` (create containers)
   5. `Microsoft.Authorization/roleAssignments/write` (assign RBAC roles - included in Owner but **not** in Contributor; Owner is required for this action)

{% hint style="info" %}
**Note on scope:** `Microsoft.Authorization/roleAssignments/write` is in Owner but not Contributor - and it must be held *at the scope where each role is assigned*. Subscription Owner only covers the Storage Blob Data Reader grant; Cost Management Reader (billing account) and the three tenant-root roles (both commitment roles plus Reader on the tenant-root management group) need the billing- and tenant-scoped roles in the Prerequisites table above. If any Step 5 grant fails, the script reports it and exits non-zero - have an admin with the right scope assign the missing role(s) via Access control (IAM), then re-run.
{% endhint %}

#### Cost Management: Export Creation Access

Go to **portal.azure.com > Cost Management + Billing > Cost Management > Exports**. If the Exports page opens and the **+ Add** button is available, you can create exports.

If the Exports page shows an access error, you do not hold Billing Account Owner or Billing Account Contributor at the billing account scope.

### Supported Agreement Types

| Agreement Type                     | FOCUS Export | Actual and Amortized Export | Billing Account Scope |
| ---------------------------------- | ------------ | --------------------------- | --------------------- |
| Enterprise Agreement (EA)          | Yes          | Yes                         | Enrollment            |
| Microsoft Customer Agreement (MCA) | Yes          | Yes                         | Billing account       |
| Microsoft Partner Agreement (MPA)  | Yes          | Yes                         | Billing account       |

#### Enterprise Agreement Customers

If your organization uses an Enterprise Agreement, note the following differences:

* Your Billing Account ID is your Enrollment Number, a numeric ID. Find it in the Azure Portal under Cost Management + Billing > Properties, or in the EA Portal.
* If your EA restricts cost visibility, the person who runs the onboarding may also need EA Admin or Department Admin access to enable cost exports at the billing account scope.
* EA enrollment admins must enable "AO view charges" and "DA view charges" in the EA Portal. If those settings are off, the exports can return empty data.
* The exports are created at the billing account, or enrollment, scope. That scope includes every subscription and department under the EA. You do not onboard each subscription separately.

### Information You Need

You look up the first two values in the Azure Portal. Your North Customer Success Engineer supplies the rest.

| Input               | Source | Where to find it, or how it is used                                                                                                                      |
| ------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Subscription        | You    | Azure Portal > Subscriptions. Use the name or the ID of the subscription where you want the storage account created.                                     |
| Billing Account ID  | You    | Azure Portal > Cost Management + Billing > Properties. This is the billing account North reads cost data from.                                           |
| WIF Subject         | North  | Identifies North's authentication identity.                                                                                                              |
| WIF Audience        | North  | Identifies North's authentication pool.                                                                                                                  |
| App Name (optional) | North  | Display name for the App Registration created in your tenant. The default is `north`. Your North representative tells you if a different name is needed. |

Your North representative usually sends you a ready-to-paste command with the North-supplied values already filled in. You then add your subscription and your billing account ID.

## Connect Your Account

Choose one of the two methods below. The result is the same.

{% tabs %}
{% tab title="Onboarding script" %}
Run the script in Azure Cloud Shell, or in any terminal with the Azure CLI installed and authenticated with `az login`. Azure Cloud Shell is the simpler option, because the Azure CLI is already installed and already authenticated there.

Each of the seven steps below is idempotent. If you run the script again, it detects the resources that already exist and skips them.

{% stepper %}
{% step %}

### Get the script

Your North representative provides the script file. Make it executable:

```bash
chmod +x north_azure_onboarding_v3.sh
```

{% endstep %}

{% step %}

### Run the script

```bash
./north_azure_onboarding_v3.sh \
  "<SUBSCRIPTION>" \
  "<BILLING_ACCOUNT_ID>" \
  "<WIF_SUBJECT>" \
  "<WIF_AUDIENCE>" \
  [<APP_NAME>]
```

The last argument is optional. Omit it to use the default name, `north`.

Example:

{% code overflow="wrap" %}

```bash
./north_azure_onboarding_v3.sh "My Subscription" "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy_yyyy-mm-dd" "us-east-1:aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" "us-east-1:bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
```

{% endcode %}

{% hint style="warning" %}
The WIF Subject and WIF Audience values above are placeholders. Use the exact values your North representative supplied.
{% endhint %}
{% endstep %}

{% step %}

### Send the output values to North

When the script finishes, it prints your connection details. Copy them and send them to your North contact.

```
  App Name:           <app-registration-name>
  Tenant ID:          <your-tenant-id>
  Client ID:          <app-registration-client-id>
  Billing Account ID: <your-billing-account-id>
  Subscription ID:    <your-subscription-id>
  Storage Account:    <storage-account-name>
  Container:          north-exports
```

{% endstep %}
{% endstepper %}

### What the Script Does

**Step 1. Register the Cost Management Exports provider.** Registers `Microsoft.CostManagementExports` on your subscription. Azure requires this before any cost export can be created. Registration is free and adds no ongoing cost.

**Step 2. Create an App Registration.** Creates an Entra ID App Registration, named `north` by default. This is the identity North authenticates as when it reads your export files. A matching Service Principal is created in your tenant.

If an App Registration with that name already exists, the script reuses it. If two or more apps share that name, the script stops and asks you to resolve the duplicate first. This prevents an unrelated app from being rebound by mistake.

The script creates no client secrets and no certificates. It grants no admin consent and no API permissions. It gives North no ability to modify any Azure resource.

**Step 3. Configure secretless authentication.** Creates a Federated Identity Credential on the App Registration. North's AWS infrastructure obtains a signed JWT from Amazon Cognito. Entra ID validates that JWT against Cognito's public OIDC endpoint, then issues a short-lived access token. The trust is defined by three exact-match fields: issuer, subject, and audience. The issuer is fixed at `https://cognito-identity.amazonaws.com`. Your North representative supplies the subject and the audience.

**Step 4. Create a storage account and container.**

| Resource        | Name                          | Purpose                                   |
| --------------- | ----------------------------- | ----------------------------------------- |
| Resource Group  | `north-billing-rg`            | Contains the storage account.             |
| Storage Account | `northexports<sub-id-prefix>` | Holds the cost export Parquet files.      |
| Blob Container  | `north-exports`               | The container inside the storage account. |

The storage account name is derived from your subscription ID, so that it is globally unique. Storage cost is small. The export files are a few megabytes per month.

If you later enable a firewall on this storage account, you must also enable "Allow trusted Azure services access". Cost Management cannot write the exports otherwise. Updating that configuration needs the Owner role on the storage account. Contributor is not enough.

**Step 5. Assign RBAC roles.** Grants the App Registration the five read-only roles listed on [Azure permissions](/docs/getting-started/permissions-required/azure-permissions.md). North cannot create, modify, or delete anything in your environment.

If a role assignment fails, the script reports it and exits with a non-zero status. Ask an administrator with the right scope to assign the missing role through Access control (IAM), then run the script again.

**Step 6. Confirm provider registration.** Waits for the Cost Management Exports provider from step 1 to finish activating. This usually takes less than 30 seconds.

**Step 7. Create the Cost Management exports.** Creates three daily exports that write Snappy-compressed Parquet files to your container.

| Export                   | Type                    | Storage path | Description                                                                                                         |
| ------------------------ | ----------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------- |
| `north-focus-export`     | FOCUS Cost, version 1.0 | `focus/`     | The primary export. Carries actual and amortized cost in one file, following the FinOps FOCUS standard.             |
| `north-actual-export`    | Actual Cost             | `actual/`    | Invoice-basis cost data. Kept as a backup and validation source.                                                    |
| `north-amortized-export` | Amortized Cost          | `amortized/` | Amortized cost data, which spreads upfront commitment fees across the term. Kept as a backup and validation source. |

Each export runs daily at midnight UTC. Each one covers month-to-date data and overwrites the previous day's file, so the current month is always current.
{% endtab %}

{% tab title="Azure Portal" %}
Use these steps to set up the integration by hand instead of running the script. The result is the same.

{% stepper %}
{% step %}

### Register the Cost Management Exports provider

1. Go to **Azure Portal > Subscriptions > your subscription > Settings > Resource providers**.
2. Search for `Microsoft.CostManagementExports`.
3. If the status is "NotRegistered", click **Register**.
4. Wait for the status to change to "Registered".
   {% endstep %}

{% step %}

### Create an App Registration

1. Go to **entra.microsoft.com > App registrations > New registration**.
2. Set the name to `north`, or to the name your North representative provided.
3. For supported account types, select **Accounts in this organizational directory only**, which is single tenant.
4. Leave the Redirect URI blank.
5. Click **Register**.
6. Record the **Application (client) ID**. You send it to North at the end.
   {% endstep %}

{% step %}

### Configure Workload Identity Federation

1. In the App Registration you created, go to **Certificates & secrets > Federated credentials > Add credential**.
2. Select **Other issuer**.
3. Enter the following values exactly.

| Field              | Value                                                                                                                           |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------- |
| Issuer             | `https://cognito-identity.amazonaws.com`                                                                                        |
| Subject identifier | Supplied by North                                                                                                               |
| Audience           | Supplied by North                                                                                                               |
| Name               | `<app-name>-aws-federation`, for example `north-aws-federation`. This matches the App Registration name from the previous step. |
| Description        | `North AWS Lambda WIF trust`                                                                                                    |

4. Click **Add**.

{% hint style="warning" %}
The Subject and Audience values are specific to your North environment. Use the exact values your North representative supplied. Do not use placeholder values.
{% endhint %}
{% endstep %}

{% step %}

### Create a storage account and container

1. Go to **Azure Portal > Storage accounts > Create**.
2. Enter the following settings.

| Setting              | Value                                                                                       |
| -------------------- | ------------------------------------------------------------------------------------------- |
| Resource group       | Create new: `north-billing-rg`                                                              |
| Storage account name | `northexports<unique-suffix>`. It must be globally unique, lowercase, and carry no hyphens. |
| Region               | East US, or your preferred region                                                           |
| Primary service      | Azure Blob Storage                                                                          |
| Performance          | Standard                                                                                    |
| Redundancy           | LRS, locally-redundant storage                                                              |

3. Click **Review + create**, then **Create**.
4. Open the new storage account, then go to **Containers > + Container**.
5. Set the name to `north-exports`.
6. Leave the access level at Private, which is the default.
7. Click **Review + Create**.
   {% endstep %}

{% step %}

### Assign the RBAC roles

Create five role assignments for the App Registration. For each role, do the following.

1. Go to the scope named in the table below.
2. Go to **Access control (IAM) > Add > Add role assignment**.
3. Search for the role name.
4. On the Members tab, select **User, group, or service principal**.
5. Click **Select members**, search for the App Registration you created earlier, for example `north`, and select it.
6. Click **Review + assign**.

| Role                     | Where to assign it                                                          |
| ------------------------ | --------------------------------------------------------------------------- |
| Storage Blob Data Reader | Storage account > Containers > `north-exports` > Access control (IAM)       |
| Cost Management Reader   | Cost Management + Billing > your billing account > Access control (IAM)     |
| Reservations Reader      | Azure Portal > Reservations > Access control (IAM)                          |
| Savings Plan Reader      | Azure Portal > Savings plans > Access control (IAM)                         |
| Reader                   | Azure Portal > Management groups > Tenant Root Group > Access control (IAM) |

[Azure permissions](/docs/getting-started/permissions-required/azure-permissions.md) explains what each role grants.
{% endstep %}

{% step %}

### Create the Cost Management exports

1. Go to **Azure Portal > Cost Management > Exports > Add**. Exports can sit under Reporting + Analytics.
2. Create the three exports below.

**Export 1, FOCUS Cost. This is the primary export.**

| Setting           | Value                               |
| ----------------- | ----------------------------------- |
| Name              | `north-focus-export`                |
| Type of data      | Cost and usage details (FOCUS)      |
| Dataset version   | 1.0                                 |
| Frequency         | Daily export of month-to-date costs |
| Start date        | Today                               |
| File format       | Parquet                             |
| Compression       | Snappy                              |
| Overwrite data    | On                                  |
| File partitioning | On                                  |
| Storage account   | `northexports<your-suffix>`         |
| Container         | `north-exports`                     |
| Directory         | `focus`                             |

**Export 2, Actual Cost. This is a backup source.**

| Setting           | Value                               |
| ----------------- | ----------------------------------- |
| Name              | `north-actual-export`               |
| Type of data      | Cost and usage details (actual)     |
| Frequency         | Daily export of month-to-date costs |
| Start date        | Today                               |
| File format       | Parquet                             |
| Compression       | Snappy                              |
| Overwrite data    | On                                  |
| File partitioning | On                                  |
| Storage account   | `northexports<your-suffix>`         |
| Container         | `north-exports`                     |
| Directory         | `actual`                            |

**Export 3, Amortized Cost. This is a backup source.**

| Setting           | Value                               |
| ----------------- | ----------------------------------- |
| Name              | `north-amortized-export`            |
| Type of data      | Cost and usage details (amortized)  |
| Frequency         | Daily export of month-to-date costs |
| Start date        | Today                               |
| File format       | Parquet                             |
| Compression       | Snappy                              |
| Overwrite data    | On                                  |
| File partitioning | On                                  |
| Storage account   | `northexports<your-suffix>`         |
| Container         | `north-exports`                     |
| Directory         | `amortized`                         |
| {% endstep %}     |                                     |

{% step %}

### Send the connection details to North

Send the following values to your North representative.

| Value              | Where to find it                                                  |
| ------------------ | ----------------------------------------------------------------- |
| Tenant ID          | Entra ID > Overview > Tenant ID                                   |
| Client ID          | Entra ID > App registrations > your app > Application (client) ID |
| Billing Account ID | Cost Management + Billing > Properties                            |
| Subscription ID    | Subscriptions > your subscription > Overview                      |
| Storage Account    | The storage account name you created                              |
| Container          | `north-exports`                                                   |
| {% endstep %}      |                                                                   |
| {% endstepper %}   |                                                                   |
| {% endtab %}       |                                                                   |
| {% endtabs %}      |                                                                   |

## What Gets Created in Your Azure Environment

| Resource                           | Purpose                                                                |
| ---------------------------------- | ---------------------------------------------------------------------- |
| App Registration (Entra ID)        | The identity North authenticates as.                                   |
| Federated Identity Credential      | Lets North authenticate from its infrastructure with no stored secret. |
| Storage Account and Blob Container | Holds the cost export files that Azure writes.                         |
| RBAC Role Assignments              | Give North read-only access to your billing data and your storage.     |
| Cost Management Exports            | Write your cost data to that container every day, in Parquet format.   |

## After You Connect

Export data can take up to 24 hours to appear after onboarding completes. North analyzes your usage once that data arrives, and then shows your spend, your commitments, and your savings opportunities.

## Troubleshooting

### "ERROR: Could not find subscription"

Check that the subscription name or ID is correct. Run `az account list --output table` to list the subscriptions available to you.

### Export creation fails

You need the Billing Account Owner or Billing Account Contributor role on the billing account. Cost Management exports need billing-scope permissions.

### "Storage account name is taken globally"

Azure storage account names must be globally unique. If the generated name is already taken, contact North support.

### New subscription, features not available

A new subscription can take up to 48 hours before Cost Management features are fully available. If export creation fails on a recently created subscription, wait and try again.

### The script stops at "Confirming provider registration"

The Cost Management Exports provider sometimes takes several minutes to register. Wait up to five minutes. If it still does not finish, check the registration status in the Azure Portal under Subscriptions > Resource providers.

## Removing the Integration

North provides a cleanup script. Contact your North Customer Success Engineer for it.

To remove the resources by hand:

1. Delete the Cost Management exports, under Azure Portal > Cost Management > Exports.
2. Delete the storage account, `northexports<prefix>` in `north-billing-rg`.
3. Delete the resource group `north-billing-rg`, if you no longer need it.
4. Delete the App Registration from Entra ID > App registrations. It is named `north` by default.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.north.cloud/docs/getting-started/quickstart/azure-onboarding.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
