# At Management Group

Customers who have configured multiple subscriptions in their account can follow the below guide to integrate all subscriptions with minimal effort.

{% hint style="info" %}
User performing the integration should have **Owner** role on the management groups being integrated.

Make sure the following resource providers are enabled on the subscriptions in the management groups being onboarded:

1. Microsoft.CostManagementExports
2. Microsoft.CostManagement
3. Microsoft.Billing
4. Microsoft.Storage \</aside>
   {% endhint %}

To begin using OneLens, you need to connect your Azure account by creating an App Registration (Service Principal) and assigning the required permissions for FinOps assessment.

The following guide allows to onboard a management group containing one (or multiple) subscriptions to OneLens.

3 types of Azure billing accounts are currently supported:

* *Microsoft Online Services Program / Pay-as-you-go (MOSP),*
* *Microsoft Customer Agreement (MCA) and*
* *Microsoft Enterprise Agreement (EA).*

Only the IAM permissions tied to the App Registration slightly differ according to the type of billing setup you have. To integrate, follow the below steps:<br>

{% stepper %}
{% step %}

### Create a new App Registration (Service Principal)

* From the home page of the Azure portal, search for and open `Microsoft Entra ID`.
* In the left navigation menu, under `Manage`, select `App registrations`.
* Click `+ New Registration`<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FCUyc9beSELULJAn2J9Qn%2Fimage.png?alt=media&#x26;token=4ded82bf-dfb6-4919-a826-4b220df2b5ff" alt=""><figcaption></figcaption></figure>
* In the open Register an application page, under **Name**, enter “*onelens-sa*”.
* All other settings can be left as default (as below).

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FQG1dBYVUo8RkImiflOC8%2Fimage.png?alt=media&#x26;token=b36815b1-708d-4b35-a365-6173f1565b07" alt="" width="563"><figcaption></figcaption></figure>
* Click `Register`\
  &#x20;
* The App Registration details should now be displayed.<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FXg1eoJUTkLV3sesUAdaE%2Fimage.png?alt=media&#x26;token=82e8409f-7e19-4faf-90fa-7043de8fd28b" alt="" width="563"><figcaption></figcaption></figure>

{% hint style="danger" %}
**Copy the Application `Client ID` and `Directory (tenant) ID` values to a safe location. You will need these values later.**
{% endhint %}
{% endstep %}

{% step %}

### Generate a Client Secret

* In the **App registration** page, in the left navigation menu under **Manage**, click `Certificates & secrets`.
* Under the **Client secrets** tab, click `+ New client secret`.<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FsXajdTQjodUvEoIRQQXq%2Fimage.png?alt=media&#x26;token=c68f6a16-72ec-40f4-91bd-5d7fce302eef" alt="" width="563"><figcaption></figcaption></figure>
* The **Add a client secret** window is opened. For description, enter the value “*onelens-secret*”.<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FVGKXahfrf7PVbyiTMY4r%2Fimage.png?alt=media&#x26;token=010c3693-3bdb-4a90-9ae6-a3f4e97af59e" alt="" width="563"><figcaption></figcaption></figure>
* Click `Add`.
* The newly created secret is now displayed.

<figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2Fnd7R2UA8xANExjbFst4T%2Fimage.png?alt=media&#x26;token=9962f906-6a1b-4d1e-9164-ca277066a072" alt="" width="563"><figcaption></figcaption></figure>

{% hint style="info" %}
**Copy the secret’s `Value` and `ID` to a safe location. You will need these values later.**
{% endhint %}

{% endstep %}

{% step %}

### Assign billing permissions to the App Registration

#### For MCA/MOSP/PayGo accounts:

* From the Azure homepage, go to `Cost Management + Billing` and select your `Billing Scope`.

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FLJzFJMlJ2vlisBJLndDp%2Fimage.png?alt=media&#x26;token=c6d5c583-bff3-4386-a2e4-e4e92d6a37bc" alt="" width="563"><figcaption></figcaption></figure>
* From the left navigation menu, select `Access Control (IAM)`
* Click `+ Add`
* Under Role, select `Billing account reader`. In the Users, groups or apps section, search for and add the **App registration** created earlier (“*onelens-sa*”).<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FxiH6vKA9C137DIFaRCRt%2Fimage.png?alt=media&#x26;token=6cbcc5f7-2d12-4187-994f-436827a17548" alt="" width="295"><figcaption></figcaption></figure>
* Click `Add`.

#### For EA accounts:

* From the Azure homepage, search for go to `Management groups`. Select your management group to be integrated.
* From the left navigation menu, select `Access Control (IAM)`.
* Click `+ Add`, and select `Add role assignment`.
* In the opened Add role assignment screen, under `Job function roles`, search for and select `Billing reader`.<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FsLq3BWq1BySU0d3dcdiw%2Fimage.png?alt=media&#x26;token=562e66f4-8bf0-495a-a024-7310f364132e" alt="" width="563"><figcaption></figcaption></figure>
* Click `Next`. Under **Members,** click `+ Select members`, and select the `App registration` created earlier ("*onelens-sa"*)<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2F4OLx2DYAghO5onG7np8w%2Fimage.png?alt=media&#x26;token=b770ab8b-961d-444b-aaea-2fc0b94bd3bb" alt="" width="563"><figcaption></figcaption></figure>
* Click `Review + assign`

{% endstep %}

{% step %}

### Create a storage account and enable exports

* From the Azure homepage, search for and open `Storage accounts`.
* Click `+ Create`. The **Create a storage account** window is opened.
* Under the **Basics** tab, add the following values:
  * **Subscription**: Select a subscription in the management group being onboarded.
  * **Resource group**: Create a new resource group with the name as `onelens-rg`.
  * **Storage account name**: Enter a globally unique, lowercase name like `onelens-<customername>-billing`.
  * **Region**: Choose your desired Azure region e.g. **(Asia Pacific) South India**.
  * **Performance**: **Standard**
  * **Redundancy**: Select **Locally-redundant storage (LRS)**.
  * Click **Next**.<br>

    <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FLqkkeI3jc0Mqjxqe1pRr%2Fimage.png?alt=media&#x26;token=9f7cb8ed-5650-4936-95ff-3d49308dc455" alt="" width="563"><figcaption></figcaption></figure>
* Under the `Advanced` tab, configure the following:
  * Set **Default to Microsoft Entra authorization in the Azure portal** to Enabled

    <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FprjuL63Ox60G2OiYrgrw%2Fimage.png?alt=media&#x26;token=b8033dc7-c6e5-440c-a0bf-2bdfbe9f24d9" alt="" width="563"><figcaption></figcaption></figure>
* All other options can be left in their default state.
* Click `Review + Create`. Wait for the deployment to complete.
* Once created, open the newly created storage account.
* In the left navigation pane, under `Data Storage`, select **Containers**.<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FwtfcNvuklh7VUhRzLOzS%2Fimage.png?alt=media&#x26;token=39d253c9-a1f3-4e6a-89ce-5989669a4412" alt="" width="563"><figcaption></figcaption></figure>
* Click on `+ Add Container`, and add the following values:
  * Under **Name**, enter the value `onelens-cost-usage-reports`**.**
  * Leave the **Anonymous access level** option as default: **Private (no anonymous access)**.<br>

    <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2F8ls7nJMXqkLEmVlZ04OA%2Fimage.png?alt=media&#x26;token=ef0c2d7d-2fbf-47ec-8125-586b2ffd8dbd" alt="" width="326"><figcaption></figcaption></figure>
* Click `Create`.
* Using the Azure Portal search bar, search for an open `Cost Management + Billing`**.**
* Under **Scope**, make sure the right **Billing account** is selected.
* In the left navigation pane, under `Settings`, select `Exports`.
* Click `+ Create`.<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FebCdzbSKKrJLSFTTDyTK%2Fimage.png?alt=media&#x26;token=40b99d5d-cfb2-4b28-aa4c-4c8ece8f7072" alt="" width="563"><figcaption></figcaption></figure>
* In the opened **New export** window, under the **Basics** tab, select **Cost and usage (actual + amortized)**.<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FwjcMRB7Au1LdQncLqz2r%2Fimage.png?alt=media&#x26;token=e0b21367-962b-4e7c-88e5-8939a60b1e1d" alt="" width="563"><figcaption></figcaption></figure>
* Under the **Datasets** tab, in the **Export prefix** field, enter the value: **onelens.**
* In the **Datasets** tab, now two exports should be visible:
  * onelens-actual-cost
  * onelens-amortized-cost<br>

    <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FDo1IVip4WUYqzGXZp1qm%2Fimage.png?alt=media&#x26;token=a0c44472-c0c3-4da6-a17a-d208c46e778e" alt="" width="563"><figcaption></figcaption></figure>
* Click `Next`.
* Under the `Destination` tab, enter the following values:
  * **Storage type:** **Azure blob storage**
  * **Destination and storage**: **Use existing**
  * **Subscription:** Select the **subscription** containing the new storage account.
  * **Storage account:** Select the storage account created earlier (**onelens-\<customername>-billing**).
  * **Container:** Enter the name of the container created earlier (**onelens-cost-usage-reports**).
  * **Directory:** Enter a new directory name like **reports**.
  * **Format:** **Parquet**
  * **Compression type:** **Snappy** (default)
  * **File partitioning:** **enabled** (default)
  * **Overwrite data:** **enabled** (default)<br>

    <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2F0kEGm3iA6wCVsg4eaFvP%2Fimage.png?alt=media&#x26;token=59e39fb8-83cc-4c80-a602-588adc4a4655" alt="" width="563"><figcaption></figcaption></figure>
* Click `Review + Create`. The first set of exports should run within \~24 hours.

{% endstep %}

{% step %}

### Assign Azure RBAC roles to the App Registration

* From the Azure homepage, search for and open `Management groups`.
* Select your **management group** to be integrated.
* From the left navigation menu, select `Access Control (IAM)`.
* Click `+ Add` and select `Add role assignment`.
* In the opened `Add a role assignment` window, under the **Job function roles** tab, search for and select `Reader`. Click `Next`.<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FmKrM8yhGUhAuUFLTyu1g%2Fimage.png?alt=media&#x26;token=c3c2937e-cc7a-4944-bd21-5bdd1404eb06" alt="" width="563"><figcaption></figcaption></figure>
* Under the **Members** tab, click **+ Select members**, and select the App registration created earlier (*”onelens-sa”*).<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FeXZLo0DmOB3sFcPOPBFM%2Fimage.png?alt=media&#x26;token=6be14570-89c6-47d9-8ab7-20efc2b24413" alt="" width="563"><figcaption></figcaption></figure>
* Click `Review + assign`.
* Similarly, add `Cost Management Reader` role.
* Using the Azure search bar on the top, search for and select `Storage Accounts`.
* Navigate to the **storage account** created in step 4.
* In the left navigation pane, select `Access Control (IAM)`.
* Click `+ Add` and select `Add role assignment`.
* In the `Role` tab, search for and select `Storage Blob Data Reader`. Click `Next`.<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FCh1IPODkKPQ3I1drfu5J%2Fimage.png?alt=media&#x26;token=c217594e-56c4-4352-a792-104b57a42596" alt="" width="563"><figcaption></figcaption></figure>
* In the `Members` tab, enter the following:
  * Assign access to: **User, group, or service principal**
  * Members: click `+ Select members`, search for and select the App registration created earlier ("onelens-sa").<br>

    <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FuOZqBAvhi8he1fLDklmg%2Fimage.png?alt=media&#x26;token=0165779c-1bf6-4aa3-8beb-84c9d9390ee7" alt="" width="563"><figcaption></figcaption></figure>
* Click `Review + assign`.

{% endstep %}

{% step %}

### Assign Azure RBAC roles to external user

* Login to the homepage of the Azure Portal, search for and open `Microsoft Entra ID`.
* In the left navigation menu, select `Access Control (IAM).`
* Click `+ Add` > **User** > **Invite external user**.<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2F37OAh5oMyLhzTtzepPYN%2Fimage.png?alt=media&#x26;token=c6ed9f22-8d65-406a-a5e7-8b7a26ba31df" alt="" width="563"><figcaption></figcaption></figure>
* In the opened Invite external user window, enter the following details:
  * **Email**: paste the unique email provided to you by the OneLens team (**onelens.finops+\<customername>@astuto.ai**)
  * **Display Name**: enter the value **OneLens External Reader.**
  * Other options can be left as default.
  * Click `Review + invite`.<br>

    <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FnqQqIXy1SGFtX8lggMor%2Fimage.png?alt=media&#x26;token=7ecc5382-8122-4c68-b894-6d77892eeb25" alt="" width="563"><figcaption></figcaption></figure>
* From the Azure homepage, search for and open `Management groups`.
* Select your **management group** to be integrated.
* From the left navigation menu, select `Access Control (IAM)`.
* Click `+ Add` and select `Add role assignment`.
* In the opened **Add a role assignment** window, under the **Job function roles** tab, search for and select `Reader`. Click `Next`.<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FmBbMjXeDcuzmmiMWPU0m%2Fimage.png?alt=media&#x26;token=85dfa667-ff5b-4a44-9529-bd7946e4353c" alt="" width="563"><figcaption></figcaption></figure>
* Under the **Members** tab, click `+ Select members`, paste the unique email provided to you by the OneLens team (**onelens.finops+\<customername>@astuto.ai**).
* Click `Review + assign`.
* Similarly, add `Cost Management Reader` role.
* Using the Azure search bar on the top, search for and select `Storage Accounts`.
* Navigate to the storage account created in step 4.
* In the left navigation pane, select `Access Control (IAM)`.
* Click `+ Add` and select `Add role assignment`.
* In the **Role** tab, search for and select `Storage Blob Data Reader`**.** Click `Next`.
* In the **Members** tab, enter the following:
  * Assign access to: **User, group, or service principal**
  * Members: click `+ Select members`, paste the unique email provided to you by the OneLens team (**onelens.finops+\<customername>@astuto.ai**).
* Click `Review + assign`.

{% endstep %}

{% step %}

### **Update storage account network default action**

Using the Azure CLI, run the following command to set the storage account’s network default action:

```bash
az storage account update \\
  --name onelens-<customername>-billing \\
  --resource-group onelens-rg \\
  --default-action Allow
```

This command updates the storage account’s network rules so that requests which do not match any explicit network rule are **allowed** (instead of denied). It controls **network access behavior**, not authentication.

{% hint style="info" %}
Public or network-level access being permitted by `--default-action Allow` **does not bypass RBAC**. Entities still require valid credentials, role assignments or SAS to read/write data.
{% endhint %}

{% endstep %}

{% step %}

### Enable cost analysis for AKS (Kubernetes) clusters

{% hint style="info" %}
User enabling cost analysis should have **Owner** or atleast **Contributor** role on the resource groups containing the AKS clusters being onboarded.

Make sure the following resource providers are enabled on the subscriptions in which the AKS clusters being onboarded are present:

1. Microsoft.ContainerService
2. Microsoft.Insights
3. Microsoft.OperationalInsights
   {% endhint %}

#### Enabling Cost Analysis on Multiple Cluster Together

For enabling cost analysis on multiple clusters within a resource group, run the following command using Azure CLI:

{% code overflow="wrap" %}

```powershell
for cluster in $(az aks list -g <resourceGroup> --query "[].name" -o tsv); do
  az aks update --resource-group <resourceGroup> --name $cluster --enable-cost-analysis
done
```

{% endcode %}

where, **\<resourceGroup>** is to be replaced with the name of the resource group in which your AKS cluster is.

#### Enabling Cost Analysis on Single Cluster

For enabling cost analysis on a single cluster, run the following command using Azure CLI:

{% code overflow="wrap" %}

```sh
az aks update --resource-group <resourceGroup> --name <clusterName> --enable-cost-analysis
```

{% endcode %}

where, **\<resourceGroup>** is to be replaced with the name of the resource group in which your AKS cluster is, and **\<clusterName>** is to be replaced with the name of your AKS cluster.

{% hint style="info" %}

AKS cost analysis can only be enabled for clusters on **Standard** or **Premium** pricing tiers. It is not available on the Free tier.

You can check an AKS cluster’s tier with the below command (using Azure CLI):

{% code overflow="wrap" %}

```sh
az aks show --resource-group <resourceGroup> --name <clusterName> --query "sku.tier"
```

{% endcode %}
{% endhint %}
{% endstep %}

{% step %}

### Enable Tag Inheritance

Tags are widely used to group costs to align with different business units, engineering environments, cost departments, and so on. Tags provide the visibility needed for businesses to manage and allocate costs across the different groups. When Tag inheritance is enabled, it applies billing, resource group, and subscription tags to child resource usage records.

Follow the below guide from Microsoft to enable Tag inheritance for MCA/MOSP/EA accounts at billing account or subscription-level

{% embed url="<https://learn.microsoft.com/en-us/azure/cost-management-billing/costs/enable-tag-inheritance>" %}
{% endstep %}
{% endstepper %}

{% hint style="success" %}
**You have now&#x20;**<mark style="color:$success;">**successfully**</mark>**&#x20;integrated your Azure environment with OneLens.**

\
**Please share the following values to the OneLens team to facilitate the connection on our end:**

* *App Registration Tenant (Directory) ID*
* *App Registration Client (Application) ID*
* *App Registration Client Secret Value*
* *App Registration Client Secret ID*
* *Storage Account name*
* *Container name*
* *Subscription ID(s) / Resource Group ID(s) / Management Group ID(s)*
  {% endhint %}
