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

# Azure setup

## Part 1: Azure Data Ingestion

Set up a Azure app so ConfigView can pull your Azure data into the dashboard.

***

### Step 1: Register an app in Microsoft Entra ID

ConfigView authenticates to Azure as an **app registration** (a service principal) in Microsoft Entra ID. You'll create one app, generate a client secret, and collect three values — the **tenant ID**, **client ID**, and **client secret** — then assign read-only permissions.

<Info>
  You need the **Application Administrator** (or Global Administrator) role in Entra ID to create the app registration, and **Owner** or **User Access Administrator** on the relevant subscriptions / billing account to assign roles.
</Info>

#### 1a. Create the app registration

1. Sign in to the [Azure portal](https://portal.azure.com) and go to **Microsoft Entra ID → App registrations**.
2. Click **➕ New registration**.
3. Name it `ConfigView`, leave **Supported account types** as *Accounts in this organizational directory only*, and leave Redirect URI blank.
4. Click **Register**.
5. On the app's **Overview** page, copy the **Application (client) ID** and the **Directory (tenant) ID**. These become the `MSFT_CLIENT_ID` and `MSFT_TENANT_ID` secrets.

#### 1b. Create a client secret

1. In the app, open **Certificates & secrets → Client secrets → ➕ New client secret**.
2. Add a description and an expiry (e.g. 24 months), then click **Add**.
3. **Immediately copy the secret's `Value`** — it is shown only once and becomes the `MSFT_CLIENT_SECRET_ID` secret.

<Warning>
  Copy the **Value** column, not **Secret ID**. Despite the ConfigView secret being named `MSFT_CLIENT_SECRET_ID`, it must hold the secret's *Value*. If you navigate away before copying it, delete the secret and create a new one.
</Warning>

#### 1c. Grant Microsoft Graph permissions (Entra ID users, groups, devices)

The directory scripts read from Microsoft Graph. In the app, go to **API permissions → ➕ Add a permission → Microsoft Graph → Application permissions** and add:

* `Directory.Read.All` — covers Users, Groups, Group Members, and basic device data.
* `Device.Read.All` — device inventory (Devices, Device Registered Owners/Users).
* *(Optional, more granular instead of `Directory.Read.All`: `User.Read.All`, `Group.Read.All`, `GroupMember.Read.All`.)*

Then click **Grant admin consent for your tenant** and confirm each permission shows a green "Granted" status.

#### 1d. Assign Azure resource & billing roles

The resource, cost, and billing scripts read from Azure Resource Manager and need **role assignments** (not Graph permissions). Assign these to the `ConfigView` app:

| Scope                                                | Role                                              | Covers                                                        |
| ---------------------------------------------------- | ------------------------------------------------- | ------------------------------------------------------------- |
| Each subscription (or a management group above them) | **Reader**                                        | Subscriptions, Resources, Databases, Key Vaults, RBAC, Policy |
| Each subscription                                    | **Cost Management Reader**                        | Cost by Subscription, Amortized Cost, Marketplace Charges     |
| Reservation orders                                   | **Reservations Reader**                           | Reservations                                                  |
| Billing account                                      | **Billing account reader**                        | Invoices                                                      |
| Key Vaults using RBAC                                | **Key Vault Reader** (+ data-plane access policy) | Key Vault secrets/keys/certificates metadata                  |

To assign a subscription role: **Subscriptions → your subscription → Access control (IAM) → ➕ Add → Add role assignment**, choose the role, then assign it to the `ConfigView` app. Billing-account roles live under **Cost Management + Billing → your billing account → Access control (IAM)**; the **Reservations Reader** role is assigned under **Reservations → Role assignments** (or at the reservation-order scope).

***

### Step 2: Add the secrets to ConfigView

1. Go to your ConfigView dashboard: `https://{companyname}.configview.com/admin/secret/`
2. Click **Add Secret** and create each of the following:

| Secret name             | Value                                   |
| ----------------------- | --------------------------------------- |
| `MSFT_CLIENT_ID`        | Application (client) ID from Step 1a    |
| `MSFT_CLIENT_SECRET_ID` | Client secret **Value** from Step 1b    |
| `MSFT_TENANT_ID`        | Directory (tenant) ID from Step 1a      |
| `MSFT_AZURE_SCOPE`      | `https://management.azure.com/.default` |

3. Click **Save**.

<Note>
  `MSFT_AZURE_SCOPE` is the Azure Resource Manager token scope — a **fixed value that is the same for every tenant**, not a subscription ID. ConfigView discovers your subscriptions automatically via the Subscriptions script, so no subscription ID secret is required.
</Note>

<Note>
  **Multiple Azure tenants.** ConfigView supports up to three Azure instances. The first uses the secret names above. For the second and third tenants, create the same secrets suffixed with `_2` and `_3` respectively (e.g. `MSFT_CLIENT_ID_2`, `MSFT_CLIENT_ID_3`) and enable the **Azure (Instance 2)** / **Azure (Instance 3)** apps. Each instance writes to its own tables suffixed with `_2` / `_3`.
</Note>

***

### Step 3: Enable the Azure App in ConfigView

1. Go to: `https://{companyname}.configview.com/admin/cron/`
2. You should see **Azure** in the list of available apps
3. Select the scripts you want to run.
4. Click **Save**

***

### Step 4: Verify

1. Go to: `https://{companyname}.configview.com/admin/status/`
2. Run the **Azure** health check.
3. All checks should pass.

If a check fails, verify that your secrets are saved correctly and the app has the required permissions.

***

### Data Tables

Once the scripts run, the corresponding Azure tables will be created in your database. All tables include a `run_at` column for historical tracking.

**Microsoft Entra ID devices** (mirrors the Entra ID **All devices** blade) are captured by these tables:

* `azure_devices` — every registered/joined device (OS, trust type, compliance, management, last sign-in).
* `azure_device_registered_owners` — the registered owner(s) of each device.
* `azure_device_registered_users` — the registered user(s) of each device.

**Microsoft Entra ID identity** (mirrors the Entra ID **Users** and **Groups** blades) is captured by these tables:

* `azure_users` — directory users (display name, UPN, mail, job title, office, phones).
* `azure_groups` — security and Microsoft 365 groups (type, membership rule, mail, on-prem sync, visibility).
* `azure_group_members` — the members of each group (one row per group/member, with member type for users vs. groups vs. devices vs. service principals).

**Billing & cost reconciliation** (mirrors the **Cost Management + Billing** blade) is captured by these tables:

* `azure_cost_by_subscription` — actual daily cost per service and resource group (purchases booked on the day they are charged).
* `azure_amortized_cost_by_subscription` — the same per-service spend with reservation and savings-plan purchases spread across their benefit term, so monthly totals line up with the invoice.
* `azure_marketplace_charges` — third-party / Azure Marketplace purchases broken out by publisher, offer, and plan (e.g. JFrog, Databricks, Anthropic) that the generic cost "SaaS" bucket lumps together.
* `azure_reservations` — Reserved Instance and savings-plan inventory with term, applied scope, expiry date, and best-effort 30-day utilization (surfaces under-used or soon-to-lapse commitments).
* `azure_invoices` — issued billing-account invoices (invoice number, status, amount due, billing period) — the authoritative anchor for reconciling ingested cost against what Microsoft actually billed.

<Note>
  The billing tables need the extra roles assigned in **Step 1d** (Cost Management Reader, Reservations Reader, Billing account reader) beyond the **Reader** role used for inventory. Each script degrades gracefully — a missing role logs a `403` and skips that dataset rather than failing the run.
</Note>

On additional Azure tenants the same tables are suffixed per instance — `_2` for Azure Instance 2 and `_3` for Azure Instance 3 (e.g. `azure_devices_2`, `azure_users_3`, `azure_groups_3`).
