# Automated using Terraform

{% hint style="info" %}
The user performing the integration must have the following roles assigned:

1. **Organisation Administrator** on your organisation
2. **Billing Account Administrator** on your organisation/billing account
3. **Service Usage Administrator** on your organisation<br>

**Why this is needed?**

Organisation Administrator role is used to create a new billing project and assign the organisation level roles.

Billing Account Administrator role is used to assign Billing account viewer role for the Service Account and the external user.

Service Usage Administrator role is used to check if the required APIs are enabled.
{% endhint %}

{% hint style="warning" %}
Below APIs are enabled as part of the script on your projects for OneLens to be able to read usage data on the respective services:

1. `Vertex AI API` *(aiplatform.googleapis.com)*
2. `Cloud Functions API` *(cloudfunctions.googleapis.com)*
3. `Cloud SQL Admin API` *(sqladmin.googleapis.com)*
4. `Compute Engine API` *(compute.googleapis.com)*
5. `Kubernetes Engine API` *(container.googleapis.com)*
6. `Dataflow API` *(dataflow\.googleapis.com)*
7. `Cloud Dataproc API` *(dataproc.googleapis.com)*
8. `Cloud Filestore API` *(file.googleapis.com)*
9. `Cloud Monitoring API` *(monitoring.googleapis.com)*
10. `Network Management API` *(networkmanagement.googleapis.com)*
11. `Recommender API` *(recommender.googleapis.com)*
12. `Google Cloud Memorystore for Redis API` *(redis.googleapis.com)*
13. `Service Usage API` *(serviceusage.googleapis.com)*
14. `Cloud Asset API` *(cloudasset.googleapis.com)*
15. `BigQuery API` *(bigquery.googleapis.com)*
    {% endhint %}

{% stepper %}
{% step %}

### Uploading the Terraform code

* Login to the Google Cloud Platform console.

* In the top bar, click the `Cloud Shell` button to launch Google Cloud's interactive shell.<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FY5ifs4G60NeSHTWull97%2FScreenshot%202025-11-04%20at%2010.50.15%E2%80%AFAM.png?alt=media&#x26;token=7d1bee17-0620-4682-ba8b-8a678ab0d6de" alt=""><figcaption></figcaption></figure>

* In the opened pop-up window, authorize Cloud Shell to use the logged in user's credentials.<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FHhwdlTaGL0fr2SQV0Edz%2FScreenshot%202025-11-04%20at%2011.02.47%E2%80%AFAM.png?alt=media&#x26;token=13f2b055-da11-48c4-86e6-fe15c8fe597c" alt=""><figcaption></figcaption></figure>

* After your credentials are verified, you will be greeted with the opened Cloud Shell terminal.

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FCSqwscrhA1EKhDDagu9F%2FScreenshot%202025-11-04%20at%2011.06.01%E2%80%AFAM.png?alt=media&#x26;token=a9abdf2f-09a3-4cd5-a589-0053d45e52e8" alt=""><figcaption></figcaption></figure>

* Click the `3 dots` on the top right of the terminal window, and select `Upload`.

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2F5kRjzMFWiMIkXUkJsRzU%2FScreenshot%202025-11-04%20at%2011.08.37%E2%80%AFAM.png?alt=media&#x26;token=3b8ef7ef-ab6d-4ae8-9b18-22628962d3bb" alt=""><figcaption></figcaption></figure>

* Select the `Folder` option, and use the `Choose Folder` button to navigate to and select the **GCP Deployment Script folder** shared to you by the OneLens team.

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FScwgm7IT6IjnCrHzsJGT%2FScreenshot%202025-11-04%20at%2011.10.38%E2%80%AFAM.png?alt=media&#x26;token=c482dc11-ffbe-4476-92bb-77c9103d0d4d" alt=""><figcaption></figcaption></figure>

  <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p>The Terraform script would have been shared to you in a <strong>ZIP</strong> format. Please make sure to uncompress the archive into the folder named <strong>onelens-gcp-onboarding</strong>.</p></div>

* The window displays the files that are going to be uploaded to your Cloud Shell terminal instance for your confirmation. Click `Upload`.\
  \
  For more details on what each file contains, please navigate to the Appendix section at the end of this guide.<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FwTzcrV2b21lj6EqGjn9A%2FScreenshot%202025-11-04%20at%2011.15.40%E2%80%AFAM.png?alt=media&#x26;token=bb869fd5-c553-42a1-99c0-89eeecd17982" alt=""><figcaption></figcaption></figure>

* Cloud Shell provides a confirmation that the files are successfully uploaded.<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FEZg9600uaHS9t7N4gMpY%2FScreenshot%202025-11-04%20at%2011.26.07%E2%80%AFAM.png?alt=media&#x26;token=d9df69a9-2980-4335-bde3-6e00e9c72bf0" alt=""><figcaption></figcaption></figure>

* Enter the following command to navigate to the folder that was uploaded:\
  \
  `cd onelens-gcp-onboarding` <br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FNBFwMP2XUFuuZKvjoqrs%2FScreenshot%202025-11-04%20at%2011.29.03%E2%80%AFAM.png?alt=media&#x26;token=3581ad74-6a65-4bec-9c5f-9141884876e4" alt=""><figcaption></figcaption></figure>

* Enter the following command to make the .SH script file executable:\
  \
  `chmod +x deploy.sh`<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2F9QuJMkMldzHgMxMVByu4%2FScreenshot%202025-11-04%20at%2011.33.40%E2%80%AFAM.png?alt=media&#x26;token=2b436f34-b2bc-4611-95b2-8862ae192811" alt=""><figcaption></figcaption></figure>

* Enter the following command to run the script:\
  \
  `./deploy.sh`<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2F3rpGTklU69h6WqzYoRpn%2FScreenshot%202025-11-04%20at%2011.35.24%E2%80%AFAM.png?alt=media&#x26;token=d49d0456-af66-415b-bfd4-c24ee674248b" alt=""><figcaption></figcaption></figure>

{% endstep %}

{% step %}

### Configuring your settings

* The script greets the user and proceeds to the first step of checking your permissions. The logged in user's ID is displayed for confirmation.\
  \
  As prompted, enter your Organisation ID.<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FDz87Kp2brxPE5Fcr2FDZ%2FScreenshot%202025-11-04%20at%2012.04.46%E2%80%AFPM.png?alt=media&#x26;token=4d04f0ea-9fba-4635-9260-4a0c79035922" alt=""><figcaption></figcaption></figure>

* Next, enter your Billing Account ID.<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FYY8NZRBRLQszVbTwl1hH%2FScreenshot%202025-11-04%20at%2012.07.06%E2%80%AFPM.png?alt=media&#x26;token=391f427c-8917-48b4-a431-c4f24fb5b1a8" alt=""><figcaption></figcaption></figure>

  <div data-gb-custom-block data-tag="hint" data-style="success" class="hint hint-success"><p><strong>To find your Organisation ID:</strong></p><p>Go to <code>Organisations,</code> then <code>Organisation details</code>:</p></div>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2F4dxHNFwXOcZhMvueNLC7%2FScreenshot%202025-11-04%20at%201.41.21%E2%80%AFPM.png?alt=media&#x26;token=f969b8b8-8d24-47de-ad16-0cf589b94cea" alt=""><figcaption></figcaption></figure>

  <div data-gb-custom-block data-tag="hint" data-style="success" class="hint hint-success"><p><strong>To find your Billing account ID:</strong></p><p>Search for and open <code>Account management</code>, and select your Billing account in the dropdown on the left.</p></div>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FdEhhSMIysVdf7VkuCD1l%2FScreenshot%202025-11-04%20at%201.47.38%E2%80%AFPM.png?alt=media&#x26;token=b492a1b2-1b02-4a9c-9d4d-4275a2d07ccf" alt=""><figcaption></figcaption></figure>

* The script will check your permissions against the provided organisation and the billing account. It checks for the below roles and displays a confirmation if they are present:
  * `Organisation Administrator` (*roles/resourcemanager.organisationAdmin*)
  * `Billing Account Administrator` (*roles/billing.admin*)
  * `Service Usage Administrator` (*roles/serviceusage.serviceUsageAdmin*)<br>

    <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FSs0Kt6PipyaCmIGuSIEY%2FScreenshot%202025-11-04%20at%201.55.29%E2%80%AFPM.png?alt=media&#x26;token=6a667389-b168-4514-aaa9-a57e7dc24987" alt=""><figcaption></figcaption></figure>

* In case the required roles are not assigned, the script will prompt you to attempt to assign the `Billing Account Administrator` and `Service Usage Administrator` roles for you *automatically*.\
  \
  **Note:** `Organisation Administrator` role is required to attempt role assignment.<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2Fx972v1ZW4xseAeeHJtHw%2FScreenshot%202025-11-04%20at%202.01.45%E2%80%AFPM.png?alt=media&#x26;token=84b93377-5627-40d0-bd2d-6aac5689e600" alt=""><figcaption></figcaption></figure>

* On proceeding, the script will prompt you for your `company name`, to be entered in small characters. This is used to optionally create a unique billing project name.<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2F4xH36bMr5Gqo2qheHAHg%2FScreenshot%202025-11-04%20at%202.08.57%E2%80%AFPM.png?alt=media&#x26;token=aa30cad1-94fc-4bc1-abf0-f97f6eb91ff3" alt=""><figcaption></figcaption></figure>

* Previously provided **Organisation ID** and the **Billing Account ID** values are displayed to be used. The script prompts you to enter the `External User email ID`. On pressing enter, the **default value** `onelens.finops@astuto.ai` is used. \
  \
  **Note:** If another value is provided to you by the OneLens team during onboarding, please enter the same.<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FDKDAxYsvsVSzxjE1LFUK%2FScreenshot%202025-11-04%20at%202.12.27%E2%80%AFPM.png?alt=media&#x26;token=b2df87d9-e945-4bed-bcf4-c963e33bbfbe" alt=""><figcaption></figcaption></figure>

* Similarly, the script prompts you to enter the name of the Service Account ID to be created. On pressing enter, the **default value** `onelens-reader-sa` is used.\
  \
  **Note:** If another value is provided to you by the OneLens team during onboarding, please enter the same.<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FpaM6A4YzKXgcbzrfHNP5%2FScreenshot%202025-11-04%20at%202.14.39%E2%80%AFPM.png?alt=media&#x26;token=7bf07cfa-43b5-412a-96bf-6643b040a15b" alt=""><figcaption></figcaption></figure>

* The next step involves configuring the Billing project:
  * If you have an existing project set up to host Billing data through BigQuery, you can enter the full ID of the project.<br>

    <div data-gb-custom-block data-tag="hint" data-style="danger" class="hint hint-danger"><p>It is recommended to create a new project to ensure your existing resource hierarchy is unaffected by resources created by OneLens. Please check the next step on how to use the script to do so.</p></div>

    <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FNUkN5I2kNX8rgNUnIL1q%2FScreenshot%202025-11-04%20at%202.17.08%E2%80%AFPM.png?alt=media&#x26;token=f3cae758-34cc-4279-b678-3494fc3b0d8c" alt=""><figcaption></figcaption></figure>

  * **Recommended:** If you want to create a new BigQuery project and dataset to export your billing data to, then press enter without entering a value. You can press enter again to use the default generated name.<br>

    <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FouHslt7AigDcXH5yYFVc%2FScreenshot%202025-11-04%20at%202.21.41%E2%80%AFPM.png?alt=media&#x26;token=1803d854-c2ee-4cd6-93e7-7f0ece740237" alt=""><figcaption></figcaption></figure>

* In the next step, you can choose to onboard folders or projects:
  * **Folders**\
    Onboard all projects in a folder by providing a folder ID. You can provide multiple folder IDs if needed.<br>

    <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2F0YdNsst71DuLRBlpXFlI%2FScreenshot%202025-11-04%20at%202.27.48%E2%80%AFPM.png?alt=media&#x26;token=64f2273a-1d9c-43dd-a12d-33b78e4b6597" alt=""><figcaption></figcaption></figure>

    \
    When prompted to enter projects, you can provide any project that is not in the provided folder(s) to be added. If no additional projects are to be onboarded, simply press enter without entering a value.\
    \
    A summary will be displayed of all entered values.<br>

    <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2Fgap2BTl1QbpldgahprsN%2FScreenshot%202025-11-04%20at%202.36.42%E2%80%AFPM.png?alt=media&#x26;token=0c7b56e5-d7f7-49ed-9f4e-5a27ddc933c8" alt=""><figcaption></figcaption></figure>

  * **Projects**\
    Onboard one or multiple projects.\
    \
    When prompted to enter folders, simply press enter without entering a value. The script will then prompt you to enter project IDs.<br>

    <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2Fu9kCX4tX7Id6SIQIuTY7%2FScreenshot%202025-11-04%20at%202.47.34%E2%80%AFPM.png?alt=media&#x26;token=bbf734ff-a8b0-4805-a761-6365422164ae" alt=""><figcaption></figcaption></figure>

    \
    A summary will be displayed of all entered values.<br>

    <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FkfDy56sgb29KT0ChZYmb%2FScreenshot%202025-11-04%20at%202.49.15%E2%80%AFPM.png?alt=media&#x26;token=fa2e9696-8efc-402c-89a2-4e04d9788b5a" alt=""><figcaption></figcaption></figure>

* On proceeding, the script runs the `terraform init` and `terraform plan` commands. Then, a summary of the resources to be created is displayed for your reference.<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FwDNR6UkhpaRoX9vlB1Ob%2FScreenshot%202025-11-18%20at%2011.35.08%E2%80%AFAM.png?alt=media&#x26;token=4f2b0143-5d86-4382-9dd4-93674b87f162" alt=""><figcaption></figcaption></figure>

* Type **yes** and hit enter to apply the Terraform plan. This runs the `terraform apply` command.<br>

  <figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FtVEFQmuMfimx5KtzoSbx%2FScreenshot%202025-11-04%20at%202.55.03%E2%80%AFPM.png?alt=media&#x26;token=6c929478-6e59-44a8-888f-fcc9d53931ba" alt=""><figcaption></figcaption></figure>

{% endstep %}

{% step %}

### Completing the onboarding

Wait **\~2 minutes** for the script to finish enabling the required APIs, create the billing export project and assign the required roles on selected resources.

<figure><img src="https://3963693991-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiyNGpqVYfmDF6qt7Lzar%2Fuploads%2FmZwVQ7zcwF6Dspe5oN60%2FScreenshot%202025-11-04%20at%202.59.38%E2%80%AFPM.png?alt=media&#x26;token=f6009073-29d8-447d-af6f-700fb213b2b1" alt=""><figcaption></figcaption></figure>

\
\
After successfully completing, the script will display a <mark style="color:$success;">**confirmation**</mark> and the following values:

* New `billing project ID`
* New `service account email`
* New `BigQuery dataset ID`

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

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

* *Billing project ID*
* *Service Account email ID*
* *BigQuery dataset ID*
  {% endhint %}

{% endstep %}

{% step %}

### Appendix

In the below section, an overview of what the code does and what each files contain is provided at a high-level:<br>

* **deploy.sh (Bash script)**
  * This is a user-facing shell wrapper script that orchestrates the entire deployment.
  * It interactively prompts the user for required inputs, performs gcloud permission pre-checks, auto-generates the `terraform.tfvars` file, and then executes the `terraform init`, `plan`, and `apply` commands in sequence.<br>
* **`main.tf` (Terraform Configuration)**
  * This is the core file containing the declarative infrastructure-as-code (IaC) logic.

  * *Core Logic*
    * **Project:** Creates a new GCP project *or* uses/validates `var.existing_billing_export_project_id` if provided. All subsequent resources depend on this project being available.

  * *Billing Export Project & Config*
    * `google_project.billing_export`: Creates a new project if `var.existing_billing_export_project_id` is empty.
    * &#x20;`data.external.check_existing_billing_project`: Validates an existing project's accessibility.
    * `google_project_service.billing_export_apis`: Enables `serviceusage`, `cloudresourcemanager`, `billingbudgets`, `bigquery`, `cloudbilling`, and `cloudasset` APIs on the billing project.
    * `google_bigquery_dataset.billing_export_dataset`: Creates the `billing_export` dataset (in `US`) if it doesn't exist.
    * `data.external.check_billing_export_dataset`: Checks if `billing_export` dataset already exists.
    * `null_resource.configure_*_export`: Logs instructions to manually configure billing exports. **No exports are automated.**

  * *FinOps Service Account (SA)*
    * `google_service_account.finops_sa`: Creates the FinOps SA (from `var.finops_service_account_id`) in the billing project if it doesn't exist.
    * `data.external.check_existing_finops_sa`: Checks if the FinOps SA already exists.<br>

  * *Target Project Onboarding*
    * `data.google_projects.*`: Discovers all target projects (from `var.target_project_ids`, `var.target_folder_ids`, or entire Org if both are empty).
    * `null_resource.enable_billing_on_projects`: Links all target projects to `var.billing_account_id` if not already billed.
    * `google_project_service.target_project_apis_*`: Enables required APIs on all target projects.

      * **Billing Required APIs:** `compute.googleapis.com`, `container.googleapis.com`, `dataflow.googleapis.com`, `dataproc.googleapis.com`, `file.googleapis.com`, `redis.googleapis.com`
      * **No-Billing APIs:** `aiplatform.googleapis.com`, `cloudfunctions.googleapis.com`, `sqladmin.googleapis.com`, `monitoring.googleapis.com`, `networkmanagement.googleapis.com`, `recommender.googleapis.com`, `serviceusage.googleapis.com`, `cloudasset.googleapis.com`, `bigquery.googleapis.com`

  * *IAM Bindings: FinOps SA* (`serviceAccount:${local.finops_sa_email}`)
    * **Scope: Organization**
      * `roles/resourcemanager.organizationViewer`
      * `roles/cloudasset.viewer`
      * `roles/browser`
    * **Scope: Billing Account**
      * `roles/billing.viewer`
    * **Scope: Billing Export Project**
      * `roles/bigquery.dataViewer`
      * `roles/bigquery.metadataViewer`
      * &#x20;`roles/bigquery.jobUser`
      * `roles/bigquery.readSessionUser`
    * **Scope: All Target Projects & Folders**
      * `roles/aiplatform.viewer`
      * `roles/cloudfunctions.viewer`
      * `roles/cloudsql.viewer`
      * `roles/compute.viewer`
      * `roles/container.viewer`
      * `roles/dataflow.viewer`
      * `roles/dataproc.viewer`
      * `roles/file.viewer`
      * `roles/monitoring.viewer`
      * `roles/networkmanagement.viewer`
      * `roles/recommender.viewer`
      * `roles/redis.viewer`
      * `roles/serviceusage.serviceUsageViewer`
      * `roles/bigquery.metadataViewer`
      * `roles/bigquery.jobUser`
      * `roles/bigquery.resourceViewer`

  * *IAM Bindings: OneLens Backend SA* (`serviceAccount:onelens-customer-sa@astuto-prod-mum.iam.gserviceaccount.com`)
    * **Scope: FinOps SA**
      * `roles/iam.serviceAccountTokenCreator` (Allows platform to impersonate FinOps SA)

  * *IAM Bindings: External User* (`user:${var.external_user_email}`)

    * **Scope: FinOps SA**
      * `roles/iam.serviceAccountTokenCreator` (Allows user to impersonate FinOps SA)
    * **Scope: Organization**
      * `roles/resourcemanager.organizationViewer`
      * `roles/cloudasset.viewer`
      * `roles/browser`
    * **Scope: Billing Account**
      * `roles/billing.viewer`
    * **Scope: Billing Export Project**
      * `roles/bigquery.jobUser`
      * `roles/bigquery.dataViewer`
      * `roles/bigquery.metadataViewer`
    * **Scope: All Target Projects**
      * `roles/viewer`
      * `roles/bigquery.resourceViewer`
      * `roles/bigquery.metadataViewer`
      * `roles/bigquery.jobUser`
    * **Scope: All Target Folders**
      * `roles/viewer`
      * `roles/bigquery.resourceViewer`
      * `roles/bigquery.metadataViewer`
      * `roles/bigquery.jobUser`

    &#x20;
* **`provider.tf` (Terraform Configuration)**
  * This is a **mandatory** Terraform file that specifies the required providers for this configuration (e.g., `hashicorp/google`).
  * It defines provider version constraints and the basic provider configuration block, telling Terraform how to interact with the target GCP APIs.<br>
* **`variables.tf` (Terraform Configuration)**
  * This is a **mandatory** Terraform file that defines the input API for the configuration.
  * It declares all variables the module accepts (e.g., `organization_id`, `target_project_ids`), along with their types, descriptions, and default values.<br>
* **`outputs.tf` (Terraform Configuration)**
  * This is a **mandatory** Terraform file that declares values to be exported after the configuration is applied.
  * It makes key resource attributes, like the newly created `service_account_email` or `billing_project_id`, available on the command line for validation or use in other scripts.<br>
* **`terraform.tfvars` (Terraform Data)**
  * This is a **mandatory** Terraform file (or must be supplied via CLI flags) that provides the actual values for the variables defined in `variables.tf`.
  * This specific file is auto-generated by the `deploy.sh` script to separate user-specific data (like project IDs) from the resource logic in `main.tf`.
    {% endstep %}
    {% endstepper %}
