# Automated using Terraform

{% hint style="warning" %}
The user executing the script must hold specific roles based on the target integration scope:\
\
**Management Group:** `Owner` or `User Access Administrator` at the Management Group level

**Subscription:** `Owner` at the Subscription level

**Resource Group:** `Owner` at the Resource Group level
{% endhint %}

OneLens is designed to adapt to your specific Azure organizational hierarchy. Whether your governance model relies on complex Management Groups, standalone Subscriptions with individual billing, or isolated Resource Groups, OneLens supports integration at the scope that best fits your needs.

To accelerate this process, we provide a **unified Terraform solution** that automates the complete onboarding workflow for all three scopes. This automation handles the end-to-end setup, including:

* **Infrastructure Setup:** Creates the App Registration (Service Principal), Storage Accounts, and Blob Containers.
* **Data Configuration:** Configures Cost Exports in Parquet format with Snappy compression and enables file partitioning.
* **Access Management:** Assigns required IAM roles and manages external user invitations.

{% hint style="warning" %}
The following prerequisites must be met before deploying the Terraform onboarding script:

* **Azure CLI:** Must be installed and authenticated (`az login`).
* **Terraform version:** Version 1.0 or greater is required
* **Optional:** `jq` is recommended for better JSON output formatting.\
  \
  **Note:** If you are using **Azure Cloud Shell (recommended)**, the above prerequisites will already be satisfied.
  {% endhint %}

{% stepper %}
{% step %}

### Uploading the Script

* Login to the Azure Portal.
* From the Azure homepage, click the **Cloud Shell icon** on the top navigation bar to launch `Azure Cloud Shell`.

<figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FvMYQdUH6kYmxBcPKoOTb%2FScreenshot%202025-12-25%20at%201.45.45%E2%80%AFPM.png?alt=media&#x26;token=731d92e1-326c-4a50-a252-b5d02f53488a" alt=""><figcaption></figcaption></figure>

* The Azure Cloud Shell window would now be open. Authenticate your user if prompted.
* Use the following command to set the working subscription in the Cloud Shell session. The cost export used by OneLens will be created in this subscription (applicable for all scopes).

```
az account set --subscription <subscription_ID>
```

<figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FfUgA4M4erajq7s0iGLF4%2FScreenshot%202025-12-25%20at%201.58.08%E2%80%AFPM.png?alt=media&#x26;token=d31ef4a5-1b4c-48be-80c7-ddd30fdba651" alt=""><figcaption></figcaption></figure>

* Create a new folder using the following command:

```
mkdir onelens_onboarding_azure
```

* Navigate into the newly created folder using the following command:

```
cd ./onelens_onboarding_azure/
```

<figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FRD0vV6IPh1bzdv7arjE5%2FScreenshot%202025-12-25%20at%202.10.00%E2%80%AFPM.png?alt=media&#x26;token=e45851cf-aca0-4e69-9023-f2c7db7fcc7c" alt=""><figcaption></figcaption></figure>

* Use the **Manage files** **> Upload** option to upload the Terraform script folder to Azure Cloud Shell.

{% hint style="info" %}
The script would have been provided to you in a **ZIP** format by the OneLens team. Please unzip the file into a folder and proceed to upload the files.
{% endhint %}

<figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FRp4E3w0vQVDNgRw7m86q%2FScreenshot%202025-12-25%20at%202.10.55%E2%80%AFPM.png?alt=media&#x26;token=90cde387-ae94-4a1f-a262-43a8858edb73" alt=""><figcaption></figcaption></figure>

* Select all **9** files from the unzipped folder to upload.
* The Azure Cloud Shell window should display a successfully uploaded message.

<figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FWoWi4ZjT7u2eLif1j4tU%2FScreenshot%202025-12-25%20at%202.13.08%E2%80%AFPM.png?alt=media&#x26;token=ae6eb999-7ca4-4100-b4fb-3eebe3572236" alt=""><figcaption></figcaption></figure>

* Move all the files into the newly created folder using the following commands (for easier maintenance).

```
cd ..
mv backend.tf data.tf deploy.sh locals.tf main.tf outputs.tf provider.tf README.md variables.tf ./onelens_onboarding_azure/
cd onelens_onboarding_azure
```

<figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FW37oZT0cdI756vOY2fED%2FScreenshot%202025-12-25%20at%202.27.18%E2%80%AFPM.png?alt=media&#x26;token=23754df8-059d-4bf2-8f03-d84639033289" alt=""><figcaption></figcaption></figure>

{% endstep %}

{% step %}

### Setting variables for Terraform

* Use the following commands to make the deploy.sh script executable and execute it:

```
chmod +x ./deploy.sh
./deploy,sh
```

This will initiate the deployment script and run pre-flight permission checks.

<figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FKm4w2K5ld6O9S2GtLlP2%2FScreenshot%202025-12-25%20at%202.30.14%E2%80%AFPM.png?alt=media&#x26;token=cad4b856-2fa9-4ba7-a658-579403931281" alt=""><figcaption></figcaption></figure>

* Choose the scope of deployment by entering:
  * **1** for *Management Group*
  * **2** for *Subscription(s)*
  * **3** for *Resource Group(s)*

<figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FPyG9rEaoElGfJzsh29Y8%2FScreenshot%202025-12-25%20at%202.34.29%E2%80%AFPM.png?alt=media&#x26;token=07c14192-8bfb-4b94-a83c-af0b9ad2eefc" alt=""><figcaption></figcaption></figure>

In this guide, we are onboarding a single Subscription as an example.<br>

* The script will prompt you for your company name (use lowercase characters and hyphens only).

<figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FrOtNyaq54bXCxVCIA2jX%2FScreenshot%202025-12-25%20at%202.37.00%E2%80%AFPM.png?alt=media&#x26;token=cbfbe244-5c80-4da6-89d0-7cb8e3fefbaf" alt=""><figcaption></figcaption></figure>

* Next, enter the Subscription ID(s) separated by commas, or type "ALL" to onboard all available subscriptions.

{% hint style="info" %}
Depending on your scope of onboarding, the script will prompt you for the Management Group (tenant) ID(s) or the Resource Group ID(s).
{% endhint %}

* Using the entered value, the script determines your **Billing Account type** (MOSP, MCA, EA) and the **Billing Account ID** and prints the same for your verification. Type **yes** to use the value.

<figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2F4a0bZAIidBC3xcjFVI3h%2FScreenshot%202025-12-25%20at%202.51.46%E2%80%AFPM.png?alt=media&#x26;token=63c1a7ab-6811-4ad2-9289-a9b1de377bd1" alt=""><figcaption></figcaption></figure>

* Next, the script will prompt you to enter the **External User email ID** (unless explicitly provided by the OneLens team, you can hit **Enter** to use the default value).
* Next, the script will prompt you to specify an **Azure region** where the new storage account (for storing the Cost export) is to be created. To use the default value (Central India), hit **Enter**.&#x20;

{% hint style="warning" %}
You can specify any region by using the **programmatic name** from the below list.\
\
[Azure regions list](https://learn.microsoft.com/en-us/azure/reliability/regions-list#azure-regions-list-1)
{% endhint %}

<figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FHrrpgZuHLTiwcdVV3pvH%2FScreenshot%202025-12-25%20at%203.01.40%E2%80%AFPM.png?alt=media&#x26;token=eeac247e-4d3c-4a5c-951e-8902c343f2aa" alt=""><figcaption></figcaption></figure>

* Next, the script will prompt you to enable **AKS Cost Analysis** for detailed usage and cost metrics for Azure Kubernetes clusters. If you do not use AKS in the selected scope, you can enter **no.**\
  \
  If yes, the script will check for available clusters in your scope and enable AKS cost analysis.

{% hint style="info" %}
For more details on how and why we enable AKS cost analysis, please refer to the below documentation from Microsoft:\
\
[AKS Cost Analysis](https://learn.microsoft.com/en-us/azure/aks/cost-analysis)
{% endhint %}

<figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2F727IsGPRcRdFFKVxJzjK%2FScreenshot%202025-12-25%20at%203.08.13%E2%80%AFPM.png?alt=media&#x26;token=0d65ff24-eeef-43ea-b74f-5a05f9747db1" alt=""><figcaption></figcaption></figure>

* Next, the script will prompt you to **enable Tag Inheritance**. It is **recommended to enable** it for better tagged visibility on OneLens.

{% hint style="info" %}
For more details on how and why we enable Tag Inheritance, please refer to the below documentation from Microsoft:\
\
[Enable Tag Inheritance](https://learn.microsoft.com/en-us/azure/cost-management-billing/costs/enable-tag-inheritance)
{% endhint %}

<figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FFwAIC7EA52G4MUfxuQhr%2FScreenshot%202025-12-25%20at%203.19.05%E2%80%AFPM.png?alt=media&#x26;token=5a3d0155-333c-4670-8fee-2e88c3d783a0" alt=""><figcaption></figcaption></figure>

* Next, the script will prompt you to enter the client ID of the **App Registration** to enable integration with OneLens. It is recommended to create a new App Registration by pressing **Enter**.
* Subsequently, the script prompts you to enter the name of the **Storage Account** to use for cost exports. It is recommended to create a new Storage Account by pressing **Enter**.

<figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FhhDTtZFWxMNKdHJjrC9T%2FScreenshot%202025-12-25%20at%203.24.48%E2%80%AFPM.png?alt=media&#x26;token=f58ba499-c940-4af1-98fd-90d7558bc650" alt=""><figcaption></figcaption></figure>

* To keep the OneLens resources organized in your environment, the script creates a Resource Group called **onelens-rg**. \
  \
  If a resource group with that name is already present, press **1** to use it, or press **2** to create a new Resource Group with a custom name. By default, the script will create a new Resource Group.

<figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2Fz2LbIKVTWWE7dcVb4uxl%2FScreenshot%202025-12-25%20at%203.28.35%E2%80%AFPM.png?alt=media&#x26;token=991e92cb-ea34-46f9-99c5-9a95b87bca3f" alt=""><figcaption></figcaption></figure>

* The script will then prompt you for a **Container name** to be created in the Storage Account.\
  \
  By default, the script will use the value **onelens-cost-usage-reports** on pressing **Enter**.

<figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FlEt4FRJiEdQsPPKLAq3c%2FScreenshot%202025-12-25%20at%203.32.40%E2%80%AFPM.png?alt=media&#x26;token=2af862aa-d39a-4f23-a568-faa7b413b9ac" alt=""><figcaption></figcaption></figure>

{% endstep %}

{% step %}

### Executing the script

* After validating all inputs, the script runs the `terraform init` and `terraform plan` commands, then prints a **summary** of the resources to be created for your reference.\
  \
  Upon entering **yes**, the script proceeds to run the `terraform apply` command.

<figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FolnIxgzQsuRMuz7dyOXo%2FScreenshot%202025-12-25%20at%203.37.42%E2%80%AFPM.png?alt=media&#x26;token=d758d9d1-92cb-4a0c-8b05-c1b2c953ea97" alt=""><figcaption></figcaption></figure>

* On successful execution, the script saves the outputs into a Terraform statefile and outputs a summary.

{% 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 %}

{% endstep %}

{% step %}

### Optional: Backup the state file to Azure Storage (recommended)

* As a final step, the script prompts you to backup the Terraform state file to the storage account used. \
  \
  It is recommended to enter **yes**, to streamline the process for deleting the OneLens resources in case of a future offboarding activity.
  {% endstep %}
  {% endstepper %}
