# Helix DAX BigQuery Terraform

This Terraform root makes `deploy/data-access/datasets/*.json` the source of
truth for the active BigQuery datasets whose IAM Helix DAX must be able to
observe and reconcile.

It manages:

- the dedicated `data_access/bigquery` GCP service account;
- one identical custom `HelixDaxDatasetIamReconciler` role in every admitted
  dataset project;
- dataset-scoped reconciler membership for every active catalog dataset in the seed;
- exact table/view IAM policy reads and writes within those allowlisted datasets;
- the service account JSON key, stored as an AWS SSM SecureString at
  `/helix/prod/DAX_BIGQUERY_SERVICE_ACCOUNT_JSON` by default.

It deliberately does not grant project-level BigQuery roles, `bigquery.jobs.*`,
dataset listing, table-data reads, or table-data writes. The custom role includes
`bigquery.tables.list` and `bigquery.tables.get` for the employee-facing schema
browser plus `bigquery.tables.getIamPolicy` / `bigquery.tables.setIamPolicy` for
exact-table DAX grants. Those permissions remain constrained by the same
Terraform-managed dataset allowlist.

`requestable` is intentionally not a Terraform scope switch. It controls
whether employees may start a new request in Helix; it must not remove the
controller permission needed to observe or revoke historical grants. Terraform
removes a dataset binding only after the catalog lifecycle explicitly moves the
dataset away from `active`. This keeps the critical provider boundary in
Terraform without copying owners, lineage, tables, schemas, requests, or
approval state into Terraform.
The validation sentinel stores only the managed locator count and a stable
locator digest; local absolute paths and business metadata do not enter remote
state or create workstation-specific plan noise.

The service account lives in the primary `gcp-digital-bi` project. Project
custom roles cannot be referenced by resources in another project's hierarchy,
so Terraform creates the same least-privilege role in each admitted dataset
project and binds each dataset to its own project's role. Dataset bindings may
target only the explicit
`managed_dataset_project_ids` allowlist, currently `gcp-digital-bi` and
`gcp-digital-bi-dev`; this covers referenced source datasets without accepting
arbitrary projects from inventory input. The Terraform caller must have the
required dataset-IAM administration permission in both projects before apply.

The generated service account key is also present in Terraform state. Keep this
root on the encrypted production S3 backend and do not run it against local
state for production credentials.

## Production Apply

```bash
cd infra/gcp-dax
terraform init \
  -backend-config="bucket=${TF_STATE_BUCKET}" \
  -backend-config="key=infra/gcp-dax/terraform.tfstate" \
  -backend-config="region=ap-southeast-1" \
  -backend-config="dynamodb_table=${TF_LOCK_TABLE}"
terraform plan
terraform apply
```

After apply, run the dataset catalog seed workflow and then upsert the
`data_access/bigquery` integration credentials from the generated SSM parameter.
