# Terraform integration

> Configure Terraform for supported LocalCloud resources using generated endpoints or transparent networking.
>
> Source: https://local.cloud/docs/terraform/

LocalCloud can exercise selected `hashicorp/google` resources locally. Support depends on the resource and routing mode; a successful local apply does not prove production Google Cloud behavior.

> **Check the supported resource list**
>
> The maintained examples use `hashicorp/google ~> 7.0` (including 7.34.0). Provider v7 requires a syntactically valid fake service-account JSON file; `/dev/null` is not sufficient. Some resources ignore custom endpoints and require transparent DNS/HTTPS routing plus a trusted LocalCloud CA.

## Choose a routing mode

### Endpoint-only

Use endpoint-only mode for resources whose Google provider clients honor generated custom endpoints. Put Terraform mode in the CLI configuration **before** starting the runtime:

```yaml
# localcloud.yaml
version: 1
host:
  environment:
    LOCALCLOUD_TERRAFORM_MODE: "true"
```

```bash
localcloud start --local-only
eval "$(localcloud env --format terraform)"
export GOOGLE_APPLICATION_CREDENTIALS="$PWD/.localcloud/fake-service-account.json"
curl -fsS http://localhost:5380/terraform/readiness?mode=endpoint
terraform init
terraform plan
```

When the CLI remaps the gateway port, use the readiness URL it returns rather than hard-coding `5380`.

### Transparent network

Use transparent networking only when required, notably for BigQuery and other clients that ignore custom endpoints. Configure both settings before `localcloud start`:

```yaml
# localcloud.yaml
version: 1
host:
  transparent_network: true
  environment:
    LOCALCLOUD_TERRAFORM_MODE: "true"
tls:
  enabled: true
  port: 5381
```

It requires:

- transparent networking enabled at start;
- host DNS routing for the required `*.googleapis.com` names;
- host `53/udp` routed to container `5410/udp`, host `80` routed to gateway `5380`, and host `443` routed to `tls.port` (default `5381`);
- the LocalCloud CA trusted by the Terraform process; and
- `LOCALCLOUD_TERRAFORM_MODE=true` in the runtime.

Verify the dedicated gate:

```bash
curl -fsS http://localhost:5380/terraform/readiness?mode=transparent
```

These host/network changes can affect other processes. Use an isolated personal environment and remove the DNS/trust configuration afterward.

## Create valid fake credentials

Use a generated private key and a syntactically valid service-account document. These are fake local credentials and must never be uploaded or reused for Google Cloud.

```bash
mkdir -p .localcloud
openssl genrsa -out .localcloud/fake-key.pem 2048 2>/dev/null
node scripts/create-localcloud-fake-sa.mjs \
  .localcloud/fake-key.pem \
  .localcloud/fake-service-account.json
chmod 600 .localcloud/fake-key.pem .localcloud/fake-service-account.json
export GOOGLE_APPLICATION_CREDENTIALS="$PWD/.localcloud/fake-service-account.json"
```

The referenced helper is provided in this site repository for a deterministic, JSON-safe credential fixture. Add `.localcloud/` to `.gitignore` in projects that copy this workflow.

## Provider configuration

```hcl
terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 7.0"
    }
  }
}

provider "google" {
  project = "local-gcp-project"
  region  = "us-central1"
}
```

Use a non-production backend and project. Keep LocalCloud endpoint variables scoped to the local Terraform shell/job.

## Generated endpoint shapes

Generate the complete values from the running LocalCloud runtime:

```bash
eval "$(curl -fsS 'http://localhost:5380/env?format=terraform')"
```

Important generated shapes include:

| Variable | Canonical value/shape | Note |
| --- | --- | --- |
| `GOOGLE_STORAGE_CUSTOM_ENDPOINT` | `http://localhost:5382/storage/v1/` | Includes the Storage API path and trailing slash. |
| `GOOGLE_PUBSUB_CUSTOM_ENDPOINT` | `http://localhost:5380/` | Uses the gateway, not direct emulator port `5383`. |
| `GOOGLE_BIGTABLE_CUSTOM_ENDPOINT` | `http://localhost:5380/` | Terraform REST path uses the gateway; `BIGTABLE_EMULATOR_HOST` remains separately exported. |
| `GOOGLE_SPANNER_CUSTOM_ENDPOINT` | `http://localhost:5387/v1/` | Port `5387` is REST/grpc-gateway, not PostgreSQL wire. |
| `GOOGLE_CLOUD_TASKS_CUSTOM_ENDPOINT` | `http://localhost:5380/v2/` | Facade-specific version prefix. |
| `GOOGLE_BIGQUERY_CUSTOM_ENDPOINT` | `http://localhost:5388/` | The maintained provider path ignores this override; use transparent routing. |
| `GOOGLE_APPLICATION_CREDENTIALS` | `/dev/null` in generated output | Override it with the valid fake JSON file for provider v7. |

Do not hand-maintain a complete endpoint table; `/env?format=terraform` is derived from the enabled runtime registry and may include additional facade-specific paths.

## Supported Terraform resources

Maintained LocalCloud examples cover:

- `google_project`;
- `google_secret_manager_secret`;
- `google_secret_manager_secret_version`;
- `google_cloud_tasks_queue`;
- `google_sql_database_instance`;
- `google_sql_database`; and
- `google_sql_user`.

Rely on the resources listed above, or on resources whose service page documents the exact operation. BigQuery requires transparent routing. IAM, organization policy, quotas, regional managed behavior, networking, and production recovery must be validated in Google Cloud.

## Terraform mode and seed data

Set `LOCALCLOUD_TERRAFORM_MODE=true` in the **runtime container** for Terraform-managed resources. Seed operations are skipped to avoid creating resources outside Terraform state. The dedicated `/terraform/readiness` response checks routing prerequisites; generic `/health` alone is insufficient.

## Cleanup and production validation

```bash
terraform destroy -auto-approve
unset GOOGLE_APPLICATION_CREDENTIALS
# Start a clean process before any real-Google-Cloud validation.
```

Do not merely unset a few endpoint variables in a long-lived shell. Use a clean environment, explicitly configure an isolated real project and credentials, review the plan, and validate IAM, networking, and quota behavior against Google Cloud before release. Review the governing proprietary license before using LocalCloud.

Confirm `/terraform/readiness` succeeds for the routing mode you selected before running `terraform plan` or `terraform apply`.
