# Cloud Run module reference

> What Kindgi's Cloud Run Terraform module creates and grants, the settings that change its network and secrets, how the runtime calls your pack's service, and the module's limits.

This page lists what Kindgi's Cloud Run module sets up: its network, its secrets backend, the IAM it grants, and its limits. [Deploy on Google Cloud Run](https://docs.kindgi.com/v0.1.8/deploy/cloud-run.md) walks through a deployment with it. The module's `README.md` lists every variable.

## A new VPC, or yours

`network_mode` decides how both services reach a VPC:

- **`direct`,** the default, in `example.tfvars`: the module creates a VPC, a subnet, Direct VPC egress for all traffic, and Cloud NAT. The subnet is `subnet_cidr`, `10.10.0.0/24` by default. Pick it when your tools reach only the internet, or nothing outside your pack.
- **`connector`,** in `example-connector.tfvars`: both services use a Serverless VPC Access connector you already have, for private ranges only. Name it in `vpc_connector`, as `projects/<project>/locations/<region>/connectors/<name>`. The module creates no VPC, router or NAT. Calls to the internet go out through Cloud Run's own egress: model APIs, your pack service's URL and webhooks.

Pick `connector` when your pack's tools reach private resources in a VPC you already have: a database on a private IP, an internal service. With `direct`, the pack runs in a new VPC of its own, not connected to yours.

Connector mode also needs `pack_ingress = "INGRESS_TRAFFIC_ALL"`, as in the example: the runtime reaches your pack's service through Cloud Run's own egress, not the VPC, so the pack service has to accept all traffic. IAM still admits only the runtime's service account. The module refuses connector mode without `vpc_connector` or without that ingress, and says which.

## Without a KMS key

By default, with `secrets_backend = "postgres"`, the secrets set through Kindgi's API are envelope-encrypted in its database, under a Cloud KMS key the module creates. Those are secrets such as a model's API key or a webhook's secret. With `secrets_backend = "none"`:

- **Not created:** the KMS key ring and key, their grants, and the `$N-secrets-aad-key` secret. `secrets_aad_key_version` isn't needed.
- **The runtime stores no secrets of its own.** `/v1/secrets` isn't served: it answers `404 route-not-found`, and the runtime checks no KMS key at start.
- **Who it fits:** a deployment whose pack's secrets all come by reference, in `pack_secret_env`, and whose model uses the service's own identity ([Gemini on Vertex AI](https://docs.kindgi.com/v0.1.8/deploy/cloud-run.md#use-gemini)). A provider whose API key would be stored in Kindgi doesn't fit it.
- **An existing deployment stays as it is:** changing it from `"postgres"` stops the plan at the key's `prevent_destroy`, on purpose, since the secrets stored under it would become unreadable. Move them out first.

## How the runtime calls your pack's service

The pack's service has internal ingress and requires IAM, so nothing but the runtime reaches it. `KINDGI_PACK_SERVICE_AUTH=google-id-token` makes the runtime mint a Google ID token for the pack's URL, from its own service account, on every call. Cloud Run checks it: the runtime's service account has `roles/run.invoker` on the pack's service, and no one else does. Then the pack's service checks the shared pack token.

If the pack's service refuses the token, the runtime's startup log says so: `⚠ Pack service at https://… isn't answering (pack-service-unauthorized: The pack service rejected the pack token).`

## The IAM it sets up

| Who                           | Role                                                                                                     | On                                                                                                                                                                        |
| ----------------------------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| The runtime's service account | `roles/run.invoker`                                                                                      | the pack's service (and no one else)                                                                                                                                      |
|                               | `roles/cloudkms.cryptoKeyEncrypterDecrypter`, not with `secrets_backend = "none"`                        | the KMS key (the startup check encrypts and decrypts with it)                                                                                                             |
|                               | `roles/cloudkms.viewer`                                                                                  | the KMS key; needed only by older runtimes, whose startup check read the key's metadata                                                                                   |
|                               | `roles/artifactregistry.reader`                                                                          | the repository, or yours (`image_repository`)                                                                                                                             |
|                               | `roles/cloudsql.client`                                                                                  | the project, conditioned on Kindgi's instance                                                                                                                             |
|                               | `roles/cloudsql.client`, only with `database_instance`                                                   | the project, conditioned on that instance, with a condition of its own: [serving from a restored instance](https://docs.kindgi.com/v0.1.8/deploy/cloud-run.md#operate-it) |
|                               | `roles/secretmanager.secretAccessor`                                                                     | each of its secrets, and each one in `server_secret_env`; not `database_instance`'s `url_secret`, which you grant                                                         |
|                               | `roles/aiplatform.user`, only with `vertex_ai = true`                                                    | the project: [Gemini](https://docs.kindgi.com/v0.1.8/deploy/cloud-run.md#use-gemini)                                                                                      |
|                               | `roles/cloudkms.signerVerifier` and `roles/cloudkms.publicKeyViewer`, only with `export_signing = "kms"` | the export signing key: [signed exports](https://docs.kindgi.com/v0.1.8/guides/observability/export-signed-evidence.md)                                                   |
| The pack's service account    | `roles/secretmanager.secretAccessor`                                                                     | the pack token and your pack's secrets                                                                                                                                    |
|                               | `roles/run.invoker`                                                                                      | each service in `pack_run_invokers`                                                                                                                                       |
|                               | what your tools need                                                                                     | your own resources                                                                                                                                                        |

## Limits

- **One runtime instance.** Several instances sharing one database aren't verified, so the module runs one.

## See also

- [Deploy on Google Cloud Run](https://docs.kindgi.com/v0.1.8/deploy/cloud-run.md): the deployment, step by step.
- [Operate a self-hosted runtime](https://docs.kindgi.com/v0.1.8/deploy/operate.md): health, backups and upgrades.
