# Terraform

> Add the customer-gcp module to your own Terraform: five APIs, one IAM binding and an optional budget. Verified with Terraform 1.15 and google 6.50.

Source: https://docs.applane.dev/gcp-admins/setup/terraform/

**Who:** GCP admin who runs Terraform for the project  
**Time:** 10 minutes

Pick this when the project's IAM and APIs already live in your Terraform. A resource created by hand shows up as drift on the next plan; adding the module keeps the plan clean.

Verified with Terraform 1.15 and `hashicorp/google` 6.50.

## Add the module

```hcl
module "applane" {
  source               = "github.com/<ORG>/applane//infra/terraform/customer-gcp"
  project_id           = "<GCP_PROJECT_ID>"
  builders_group_email = "applane-builders@<YOUR_DOMAIN>"
  applane_extension_id = "<APPLANE_EXTENSION_ID>"

  # optional: budget alert at 50%, 90%, 100% of budget_amount per month
  billing_account_id = "<BILLING_ACCOUNT_ID>"
  budget_amount      = 50
}

output "applane_next_steps" {
  value = module.applane.consent_screen_instructions
}
```

The module source with the organisation filled in is on the Applane console's Setup page. Inputs and outputs are listed in the [Terraform module reference](https://docs.applane.dev/reference/terraform-module/).

If another module already manages `google_project_service` on this project, set `enable_apis = false` and enable the [five APIs](https://docs.applane.dev/gcp-admins/apis/) there instead. Two Terraform resources for the same API fight each other.

## Or run the example on its own

```bash
git clone <APPLANE_SETUP_REPO_URL> applane && cd applane/infra/terraform/customer-gcp
cp examples/basic/terraform.tfvars.example examples/basic/terraform.tfvars   # fill in project, group, extension id
cd examples/basic
gcloud auth application-default login
terraform init
terraform plan
terraform apply
terraform output consent_screen_instructions
```

## Creating the project too

The module never creates projects. If you want one config to do both, add a `google_project` in your root module and pass `existing_project = false` so the module's billing check is skipped at plan time:

```hcl
resource "google_project" "applane" {
  name            = "Applane"
  project_id      = "acme-applane"
  org_id          = var.org_id           # or folder_id
  billing_account = var.billing_account_id
}

module "applane" {
  source               = "github.com/<ORG>/applane//infra/terraform/customer-gcp"
  project_id           = google_project.applane.project_id
  builders_group_email = "applane-builders@acme.com"
  billing_account_id   = var.billing_account_id
  existing_project     = false
}
```

## What it creates

| Resource | What | Why |
|---|---|---|
| `google_project_service` x5 | `script`, `aiplatform`, `sheets`, `drive`, `docs` `.googleapis.com` | Google checks API enablement on the project that owns the OAuth client. `disable_on_destroy = false`: destroying the module never switches an API off. |
| `google_project_iam_member` | `roles/aiplatform.user` to `group:<builders_group_email>` | Lets builders call Gemini on Vertex AI. No service accounts, no keys. |
| `google_billing_budget` | 50%, 90%, 100% of `budget_amount` per month | Only when `billing_account_id` is set. Alerts go to the billing admins; nothing is cut off. Also enables `billingbudgets.googleapis.com`. |

A `data "google_project"` read checks that billing is linked and fails the plan with a clear message if it is not.

## Why the consent screen and the client are not in Terraform

Google has no API for the OAuth consent screen or for a standard OAuth 2.0 client. The provider's `google_iap_client` and `google_iap_brand` only create clients for Identity-Aware Proxy, and an IAP client does not work with the extension's sign-in flow. So two steps stay in the console: [OAuth consent screen](https://docs.applane.dev/gcp-admins/oauth-consent-screen/) and [OAuth client](https://docs.applane.dev/gcp-admins/oauth-client/). The module prints them in `consent_screen_instructions`.

## Verify

`terraform plan` after apply shows no changes. Then run the [setup checker](https://docs.applane.dev/gcp-admins/verify/).

## Remove it

`terraform destroy` removes the IAM binding and the budget. The five APIs stay enabled on purpose; disable them by hand if the project is dedicated to Applane, then delete the OAuth client in the console. See [Uninstall](https://docs.applane.dev/workspace-admins/uninstall/#gcp-admin).
