AnythingLLM on Google Cloud Run
This document provides a comprehensive reference for the modules/AnythingLLM_CloudRun Terraform module. It covers architecture, IAM, configuration variables, AnythingLLM-specific behaviours, and operational patterns for deploying AnythingLLM on Google Cloud Run (v2).
1. Module Overview
AnythingLLM is a private AI workspace and Retrieval-Augmented Generation (RAG) platform. It allows teams to chat with documents, connect to any LLM provider (OpenAI, Anthropic, Ollama, and others), and build AI-powered knowledge assistants — without sending data to third-party services. AnythingLLM CloudRun is a wrapper module built on top of App CloudRun. It uses App CloudRun for all GCP infrastructure provisioning and injects AnythingLLM-specific application configuration, secrets, and storage configuration via AnythingLLM Common.
Key Capabilities:
- Compute: Cloud Run v2 (Gen2 recommended), 2 vCPU / 4 Gi by default.
min_instance_count = 1to keep AnythingLLM warm for AI workloads. - Data Persistence: Cloud SQL PostgreSQL 15 (required by AnythingLLM's Prisma ORM). GCS document storage bucket auto-provisioned by
AnythingLLM Common. Optional NFS for persistent document/vector store data. - Security: Four application-level secrets are auto-generated by
AnythingLLM Common—JWT_SECRET,AUTH_TOKEN,SIG_KEY, andSIG_SALT— and injected into the container via Secret Manager. Inherits Cloud Armor WAF, IAP, Binary Authorization, and VPC Service Controls fromApp CloudRun. - Caching: Redis is disabled by default (
enable_redis = false). Enable for session or cache workloads if required. - CI/CD: Cloud Build custom image pipeline by default; Cloud Deploy progressive delivery optional.
- Reliability: Health probes target
/api/pingwith a 60-second initial delay to allow model loading and database migration on first boot.
Project & Application Identity
| Variable | Group | Type | Default | Description |
|---|---|---|---|---|
project_id | 1 | string | — | GCP project ID. Required. |
tenant_deployment_id | 2 | string | 'demo' | Short suffix appended to all resource names. |
support_users | 2 | list(string) | [] | Email recipients for monitoring alerts. |
resource_labels | 2 | map(string) | {} | Labels applied to all provisioned resources. |
application_name | 3 | string | 'anythingllm' | Base resource name. Do not change after initial deployment. |
application_display_name | 3 | string | 'AnythingLLM' | Human-readable name shown in dashboards. |
application_description | 3 | string | 'AnythingLLM Private AI Workspace on Cloud Run' | Service description. |
application_version | 3 | string | 'latest' | Container image version tag. |
Wrapper architecture: AnythingLLM CloudRun calls AnythingLLM Common to build an application_config object containing AnythingLLM-specific environment variables, probe configuration, and the db-init job definition. AnythingLLM Common generates and stores JWT_SECRET, AUTH_TOKEN, SIG_KEY, and SIG_SALT in Secret Manager and returns their IDs via module.anythingllm_app.secret_ids. The GOOGLE_CLOUD_STORAGE_BUCKET_NAME environment variable is automatically set from module.anythingllm_app.storage_buckets[0].name. The scripts_dir is resolved to abspath("${module.anythingllm_app.path}/scripts") at apply time.
PostgreSQL note: AnythingLLM uses Prisma ORM and requires PostgreSQL. database_type = "POSTGRES_15" is the default. Do not set this to a MySQL or SQL Server variant.
2. IAM & Access Control
AnythingLLM CloudRun delegates all IAM provisioning to App CloudRun. The Cloud Run SA, Cloud Build SA, IAP service agent, and password rotation role sets are identical to those in App CloudRun.
Application secrets: AnythingLLM Common auto-generates four secrets on first apply:
JWT_SECRET— signs AnythingLLM authentication tokens.AUTH_TOKEN— optional API bearer token for programmatic access.SIG_KEY— HMAC signing key for request signatures (32+ characters).SIG_SALT— salt used alongsideSIG_KEYfor HMAC signatures (32+ characters).
These secrets are stored in Secret Manager and injected natively at Cloud Run revision start. Plaintext is never written to Terraform state.
Database initialisation identity: The db-init Cloud Run Job runs under the Cloud Run SA. It connects to Cloud SQL PostgreSQL via the Auth Proxy Unix socket (since enable_cloudsql_volume = true by default), using DB_HOST (the socket path under /cloudsql), DB_USER, and ROOT_PASSWORD (from Secret Manager).
120-second IAM propagation delay: Inherited from App CloudRun — the AnythingLLM service is not deployed until the delay completes, preventing secret-read failures on the first revision start.
3. Core Service Configuration
A. Compute (Cloud Run)
AnythingLLM is a Node.js application that performs AI embedding and LLM inference operations. It has higher resource requirements than typical web applications.
min_instance_count = 1 is recommended to keep AnythingLLM warm and avoid cold starts for AI document ingestion and chat operations. max_instance_count = 1 is the default — AnythingLLM's local storage model means multiple instances require NFS for consistent document access.
Startup CPU Boost is always enabled (hardcoded in App CloudRun).
Container image: container_image_source defaults to 'custom', meaning Cloud Build compiles a custom AnythingLLM image using AnythingLLM_Common's Dockerfile. Set container_image_source = 'prebuilt' and container_image = '<image-uri>' to skip the build and deploy an existing image.
| Variable | Group | Default | Description |
|---|---|---|---|
deploy_application | 4 | true | Set false for infrastructure-only deployment (SQL, storage, secrets). |
container_image_source | 4 | 'custom' | 'custom' builds via Cloud Build. 'prebuilt' deploys an existing image URI. |
container_image | 4 | "" | Override image URI. Leave empty for Cloud Build to manage the image. |
container_build_config | 4 | { enabled=true } | Cloud Build configuration: dockerfile_path, context_path, build_args, artifact_repo_name. |
enable_image_mirroring | 4 | true | Mirrors the container image into Artifact Registry before deployment. |
cpu_limit | 4 | '2000m' | CPU per instance. 2 vCPU minimum for AI workloads. |
memory_limit | 4 | '4Gi' | Memory per instance. 4 Gi minimum for embedding and inference. |
min_instance_count | 4 | 1 | Minimum instances. Set to 1 to avoid cold starts. |
max_instance_count | 4 | 1 | Maximum instances. Increase with NFS for shared document access. |
container_port | 4 | 3001 | AnythingLLM's native HTTP port. |
container_protocol | 4 | 'http1' | 'http1' or 'h2c'. |
execution_environment | 4 | 'gen2' | Gen2 required for NFS mounts and GCS Fuse. |
timeout_seconds | 4 | 300 | Max request duration. Increase for long-running document ingestion. |
enable_cloudsql_volume | 4 | true | Injects Cloud SQL Auth Proxy sidecar for database connectivity. |
cloudsql_volume_mount_path | 4 | '/cloudsql' | Container path for the Auth Proxy Unix socket. |
traffic_split | 4 | [] | Percentage-based canary/blue-green traffic allocation. |
service_annotations | 4 | {} | Advanced Cloud Run annotations. |
service_labels | 4 | {} | Labels applied to the Cloud Run service. |
Differences from App CloudRun defaults:
| Variable | App CloudRun | AnythingLLM CloudRun | Reason |
|---|---|---|---|
container_port | 8080 | 3001 | AnythingLLM's native port. |
cpu_limit | '1000m' | '2000m' | AI workloads require more CPU for embedding and inference. |
memory_limit | '512Mi' | '4Gi' | LLM context, document vectors, and Prisma ORM require more RAM. |
min_instance_count | 0 | 1 | Keep warm for AI operations; cold starts are expensive. |
health probe path | '/healthz' | '/api/ping' | AnythingLLM's health endpoint. |
B. Database (Cloud SQL — PostgreSQL 15)
AnythingLLM uses Prisma ORM and requires PostgreSQL. database_type = "POSTGRES_15" is the default set by AnythingLLM Common. The entrypoint script constructs the DATABASE_URL Prisma connection string from the platform-injected DB_* variables at container start time, working correctly on both Unix socket (Cloud Run) and TCP (GKE) connections.
| Variable | Group | Default | Description |
|---|---|---|---|
database_type | 12 | 'POSTGRES_15' | Cloud SQL engine. AnythingLLM requires PostgreSQL. |
application_database_name | 12 | 'anythingllmdb' | PostgreSQL database name. Do not change after initial deployment. |
application_database_user | 12 | 'anythingllmuser' | Database user. Password auto-generated and stored in Secret Manager. |
database_password_length | 12 | 32 | Auto-generated password length. Range: 16–64. |
enable_auto_password_rotation | 12 | false | Automated zero-downtime password rotation. |
rotation_propagation_delay_sec | 12 | 90 | Seconds to wait after rotation before restarting the service. |
db_host_env_var_name | 12 | "" | Additional env var name to expose DB_HOST. Leave empty to inject only DB_HOST. |
db_user_env_var_name | 12 | "" | Additional env var name to expose DB_USER. |
db_name_env_var_name | 12 | "" | Additional env var name to expose DB_NAME. |
db_port_env_var_name | 12 | "" | Additional env var name to expose DB_PORT. |
service_url_env_var_name | 12 | "" | Additional env var name to expose CLOUDRUN_SERVICE_URL. |
C. Storage (NFS & GCS)
NFS is disabled by default (enable_nfs = false). For multi-instance deployments or persistent document/vector store access, enable NFS. Requires execution_environment = 'gen2'.
GCS document bucket: AnythingLLM Common automatically provisions a dedicated anythingllm-docs GCS bucket. The GOOGLE_CLOUD_STORAGE_BUCKET_NAME environment variable is set to this bucket name automatically. This bucket is separate from any additional buckets in storage_buckets.
| Variable | Group | Default | Description |
|---|---|---|---|
create_cloud_storage | 11 | true | Set false to skip bucket creation. The anythingllm-docs bucket from AnythingLLM Common is always provisioned. |
storage_buckets | 11 | [{ name_suffix = "data" }] | Additional GCS buckets beyond the auto-provisioned docs bucket. |
enable_nfs | 11 | false | Provisions a Cloud Filestore NFS instance. Required for multi-instance AnythingLLM deployments. |
nfs_mount_path | 11 | '/mnt/nfs' | Container path where the NFS share is mounted. |
nfs_instance_name | 11 | "" | Name of an existing NFS GCE VM. Leave empty to auto-discover. |
nfs_instance_base_name | 11 | 'app-nfs' | Base name for an inline NFS GCE VM when none exists. |
gcs_volumes | 11 | [] | GCS buckets to mount via GCS Fuse (requires gen2). |
manage_storage_kms_iam | 11 | false | Creates a CMEK KMS keyring/key and enables CMEK on all storage buckets. |
enable_artifact_registry_cmek | 11 | false | Creates an Artifact Registry KMS key and enables at-rest CMEK encryption. |
D. Networking
Cloud Run uses Direct VPC Egress to reach Cloud SQL's internal IP. With enable_cloudsql_volume = true, the Auth Proxy sidecar handles the Cloud SQL connection via Unix socket.
| Variable | Group | Default | Description |
|---|---|---|---|
ingress_settings | 5 | 'all' | 'all' — public internet; 'internal' — VPC only; 'internal-and-cloud-load-balancing' — forces traffic through the HTTPS LB. |
vpc_egress_setting | 5 | 'PRIVATE_RANGES_ONLY' | 'PRIVATE_RANGES_ONLY' routes only RFC 1918 traffic via VPC. 'ALL_TRAFFIC' routes all egress via VPC. |
E. Initialization & Bootstrap
A db-init Cloud Run Job is automatically provisioned by AnythingLLM Common when initialization_jobs is left as the default empty list ([]). It uses the postgres:15-alpine image and executes AnythingLLM_Common/scripts/create-db-and-user.sh, which performs the following idempotent operations:
- Connects to Cloud SQL PostgreSQL via the Auth Proxy Unix socket.
- Creates the AnythingLLM database user with the password from Secret Manager.
- Creates the AnythingLLM database if it does not exist.
- Grants the user full privileges on the database.
Override initialization_jobs with a non-empty list to replace this default with custom jobs.
| Variable | Group | Default | Description |
|---|---|---|---|
initialization_jobs | 13 | [] | One-shot Cloud Run Jobs. Leave empty for AnythingLLM Common to supply the default db-init job. Each entry: name, description, image, command, args, env_vars, secret_env_vars, cpu_limit, memory_limit, timeout_seconds, max_retries, task_count, execution_mode, mount_nfs, mount_gcs_volumes, depends_on_jobs, execute_on_apply, script_path. |
cron_jobs | 13 | [] | Recurring jobs triggered by Cloud Scheduler. Each entry: name, schedule (cron UTC), image, command, args, env_vars, secret_env_vars, cpu_limit, memory_limit, timeout_seconds, max_retries, task_count, parallelism, mount_nfs, mount_gcs_volumes, script_path, paused. |
additional_services | 13 | [] | Additional Cloud Run services deployed alongside AnythingLLM. |
4. Advanced Security
A. Cloud Armor WAF
When enable_cloud_armor = true, a Global HTTPS Load Balancer with a Cloud Armor WAF policy (OWASP Top 10, adaptive DDoS, 500 req/min rate limiting) is provisioned in front of Cloud Run.
| Variable | Group | Default | Description |
|---|---|---|---|
enable_cloud_armor | 10 | false | Provisions Global HTTPS LB + Cloud Armor WAF. Required for custom domains and DDoS protection. |
admin_ip_ranges | 10 | [] | CIDR ranges exempted from WAF rules (e.g., office VPN, CI/CD egress IPs). |
B. Identity-Aware Proxy (IAP)
When enable_iap = true, Cloud Run's native IAP integration is enabled. Google identity authentication is required before requests reach AnythingLLM. Recommended for internal AI workspace deployments.
| Variable | Group | Default | Description |
|---|---|---|---|
enable_iap | 5 | false | Enables IAP natively on the Cloud Run service. |
iap_authorized_users | 5 | [] | Users/service accounts granted access. Format: 'user:email' or 'serviceAccount:sa@...'. |
iap_authorized_groups | 5 | [] | Google Groups granted access. Format: 'group:name@example.com'. |
C. Binary Authorization
When enable_binary_authorization = true, Cloud Run enforces that deployed images carry a valid cryptographic attestation.
| Variable | Group | Default | Description |
|---|---|---|---|
enable_binary_authorization | 8 | false | Enforces image attestation. Requires a Binary Authorization policy and attestor pre-configured in the project. |
D. VPC Service Controls
When enable_vpc_sc = true, all GCP API calls from this module are bound within an existing VPC-SC perimeter.
| Variable | Group | Default | Description |
|---|---|---|---|
enable_vpc_sc | 22 | false | Registers module API calls within the project's VPC-SC perimeter. |
vpc_cidr_ranges | 22 | [] | VPC subnet CIDR ranges for the VPC-SC network access level. |
vpc_sc_dry_run | 22 | true | Logs VPC-SC violations without blocking. Set false to enforce. |
organization_id | 22 | "" | GCP Organization ID for VPC-SC. Required when enable_vpc_sc = true. |
enable_audit_logging | 22 | false | Enables detailed Cloud Audit Logs. |
E. Secret Manager Integration
Four AnythingLLM application secrets are auto-generated by AnythingLLM Common and stored in Secret Manager:
| Secret | Purpose |
|---|---|
JWT_SECRET | Signs AnythingLLM authentication tokens. |
AUTH_TOKEN | Optional API bearer token for programmatic access. |
SIG_KEY | HMAC signing key for request signatures (32+ characters). |
SIG_SALT | Salt used alongside SIG_KEY for HMAC request signatures. |
Additional user-defined secrets can be added via secret_environment_variables (e.g., LLM API keys).
| Variable | Group | Default | Description |
|---|---|---|---|
secret_environment_variables | 6 | {} | Map of env var name → Secret Manager secret ID. (e.g., { OPENAI_API_KEY = "anythingllm-openai-key" }) |
secret_rotation_period | 6 | '2592000s' | Frequency at which Secret Manager emits rotation notifications. Default: 30 days. |
secret_propagation_delay | 6 | 30 | Seconds to wait after secret creation before dependent resources proceed. |
5. Traffic & Ingress
A. HTTPS Load Balancer
When enable_cloud_armor = true, a Global HTTPS Load Balancer backed by a Serverless NEG is provisioned. Traffic flows: Internet → Cloud Armor → Global HTTPS LB → Serverless NEG → Cloud Run.
Setting ingress_settings = 'internal-and-cloud-load-balancing' forces all AnythingLLM traffic through the LB, preventing direct *.run.app URL access.
B. Cloud CDN
When enable_cdn = true (requires enable_cloud_armor = true), Cloud CDN is attached to the HTTPS Load Balancer backend.
AnythingLLM consideration: AnythingLLM is primarily an API-driven application with authenticated sessions. CDN caching is only appropriate for static assets. Ensure proper Cache-Control headers are in place before enabling CDN on the AnythingLLM API endpoints.
| Variable | Group | Default | Description |
|---|---|---|---|
enable_cdn | 10 | false | Enables Cloud CDN on the HTTPS LB backend. Only effective when enable_cloud_armor = true. |
max_images_to_retain | 10 | 7 | Maximum container images to keep in Artifact Registry. |
delete_untagged_images | 10 | true | Automatically deletes untagged images from Artifact Registry. |
image_retention_days | 10 | 30 | Days after which images are eligible for deletion. |
C. Custom Domains
| Variable | Group | Default | Description |
|---|---|---|---|
application_domains | 10 | [] | Custom domain names for the HTTPS LB. Google-managed SSL certificates provisioned per domain. |
6. CI/CD & Delivery
A. Cloud Build Triggers
When enable_cicd_trigger = true, a Cloud Build GitHub connection and push trigger are provisioned.
| Variable | Group | Default | Description |
|---|---|---|---|
enable_cicd_trigger | 8 | false | Provisions a Cloud Build GitHub trigger. Requires github_repository_url and credentials. |
github_repository_url | 8 | "" | Full HTTPS URL of the GitHub repository. |
github_token | 8 | "" | GitHub PAT (repo, admin:repo_hook scopes). Required on first apply. Sensitive. |
github_app_installation_id | 8 | "" | GitHub App installation ID (preferred for organisation repos). |
cicd_trigger_config | 8 | { branch_pattern = "^main$" } | Advanced trigger config: branch_pattern, included_files, ignored_files, trigger_name, substitutions. |
B. Cloud Deploy Pipeline
| Variable | Group | Default | Description |
|---|---|---|---|
enable_cloud_deploy | 8 | false | Provisions a Cloud Deploy pipeline. Requires enable_cicd_trigger = true. |
cloud_deploy_stages | 8 | [dev, staging, prod(approval)] | Ordered promotion stages. Each: name, target_name, service_name, require_approval, auto_promote. |
7. Reliability & Scheduling
A. Health Probes & Uptime Monitoring
AnythingLLM exposes /api/ping as its health endpoint. Both the startup and liveness probes target this path. AnythingLLM requires additional startup time for AI model loading and database migration.
| Variable | Group | Default | Description |
|---|---|---|---|
startup_probe | 14 | { enabled=true, path="/api/ping", initial_delay_seconds=60, timeout_seconds=5, period_seconds=10, failure_threshold=30 } | Startup readiness probe. Container receives no traffic until this succeeds. |
liveness_probe | 14 | { enabled=true, path="/api/ping", initial_delay_seconds=30, timeout_seconds=5, period_seconds=30, failure_threshold=3 } | Liveness probe. Container is restarted after failure_threshold consecutive failures. |
startup_probe_config | 14 | Same as startup_probe | Alias passed to App CloudRun health probe configuration. |
health_check_config | 14 | Same as liveness_probe | Alias passed to App CloudRun liveness probe configuration. |
uptime_check_config | 14 | { enabled=true, path="/" } | Cloud Monitoring uptime check. Alerts notify support_users if unreachable. |
alert_policies | 14 | [] | Cloud Monitoring metric alert policies. |
B. Auto Password Rotation
When enable_auto_password_rotation = true, a zero-downtime password rotation pipeline is provisioned.
| Variable | Group | Default | Description |
|---|---|---|---|
enable_auto_password_rotation | 12 | false | Enables automated password rotation. |
rotation_propagation_delay_sec | 12 | 90 | Seconds to wait after writing the new secret before restarting the service. |
8. Integrations
A. LLM Provider Configuration
AnythingLLM connects to LLM providers via environment variables. Use environment_variables for non-sensitive provider configuration and secret_environment_variables for API keys.
Common AnythingLLM environment variables:
| Variable | Purpose | Example |
|---|---|---|
LLM_PROVIDER | LLM backend | openai, anthropic, ollama, native |
EMBEDDING_ENGINE | Embedding provider | native, openai, ollama |
VECTOR_DB | Vector database backend | lancedb, chroma, qdrant, pinecone |
SERVER_PORT | HTTP port (fixed by AnythingLLM Common) | 3001 |
STORAGE_DIR | Document storage path (fixed) | /app/server/storage |
Store provider API keys in Secret Manager and reference them via secret_environment_variables:
secret_environment_variables = {
OPENAI_API_KEY = "anythingllm-openai-key"
ANTHROPIC_API_KEY = "anythingllm-anthropic-key"
}
B. Redis Cache
Redis is disabled by default for AnythingLLM. Enable it if your deployment requires session caching or a shared cache layer.
| Variable | Group | Default | Description |
|---|---|---|---|
enable_redis | 21 | false | Enables Redis. Not required for AnythingLLM core functionality. |
redis_host | 21 | null | Redis server hostname or IP. Required when enable_redis = true. |
redis_port | 21 | '6379' | Redis server TCP port (string). |
redis_auth | 21 | "" | Redis AUTH password. Sensitive — leave empty if not required. |
C. Backup Import & Recovery
| Variable | Group | Default | Description |
|---|---|---|---|
backup_schedule | 7 | '0 2 * * *' | Cron expression (UTC) for automated daily backups. |
backup_retention_days | 7 | 7 | Days to retain backup files in GCS. |
enable_backup_import | 7 | false | Triggers a one-time restore on apply. Set false after a successful import. |
backup_source | 7 | 'gcs' | 'gcs' or 'gdrive'. |
backup_file | 7 | 'backup.sql' | Filename of the backup to import. |
backup_format | 7 | 'sql' | Backup file format. Options: sql, tar, gz, tgz, tar.gz, zip, auto. |
D. Custom SQL Scripts
| Variable | Group | Default | Description |
|---|---|---|---|
enable_custom_sql_scripts | 9 | false | Runs custom SQL scripts from a GCS bucket against the application database. |
custom_sql_scripts_bucket | 9 | "" | GCS bucket containing SQL scripts. |
custom_sql_scripts_path | 9 | "" | Path prefix within the bucket. |
custom_sql_scripts_use_root | 9 | false | Run scripts as the root DB user. |
9. Platform-Managed Behaviours
The following behaviours are applied automatically by AnythingLLM CloudRun regardless of variable values. They cannot be overridden via tfvars.
| Behaviour | Implementation | Detail |
|---|---|---|
| PostgreSQL 15 required | database_type = "POSTGRES_15" fixed by AnythingLLM Common | AnythingLLM's Prisma ORM requires PostgreSQL. MySQL is not supported. |
| Prisma DATABASE_URL | Constructed by anythingllm-entrypoint.sh at container start | The entrypoint script builds the PostgreSQL connection string from DB_* vars injected by App CloudRun. |
| Application secrets auto-generated | JWT_SECRET, AUTH_TOKEN, SIG_KEY, SIG_SALT provisioned by AnythingLLM Common | Generated with random_password (32 chars, alphanumeric). Secret IDs are forwarded to App CloudRun via module_secret_env_vars. |
| GCS document bucket | anythingllm-docs bucket provisioned by AnythingLLM Common | The GOOGLE_CLOUD_STORAGE_BUCKET_NAME env var is set automatically in module_env_vars. |
| Fixed environment variables | SERVER_PORT=3001, STORAGE_DIR=/app/server/storage, UID=1000, GID=1000 | Set by AnythingLLM Common. Do not override these in environment_variables. |
| Unix socket by default | enable_cloudsql_volume = true default | AnythingLLM connects to Cloud SQL via the Auth Proxy Unix socket. |
| Image mirroring enabled | enable_image_mirroring = true default | Mirrors the AnythingLLM image into Artifact Registry to avoid Docker Hub rate limits. |
| Default db-init job | Supplied by AnythingLLM Common when initialization_jobs = [] | PostgreSQL database and user are created automatically. Override with a non-empty initialization_jobs list to replace. |
| Scripts directory | scripts_dir = abspath("${module.anythingllm_app.path}/scripts") | Initialization scripts are sourced from AnythingLLM Common. |
10. Variable Reference
All user-configurable variables exposed by AnythingLLM CloudRun, sorted by UI group then order. Group 0 variables are reserved for platform metadata — leave them at their defaults for standard deployments.
| Variable | Group | Default | Description |
|---|---|---|---|
module_description | 0 | (AnythingLLM platform text) | Platform metadata: module description. |
module_documentation | 0 | (docs URL) | Platform metadata: documentation URL. |
module_dependency | 0 | ['Services GCP'] | Platform metadata: required modules. |
module_services | 0 | (GCP service list) | Platform metadata: GCP services consumed. |
credit_cost | 0 | 50 | Platform metadata: deployment credit cost. |
require_credit_purchases | 0 | false | Platform metadata: enforces credit balance check. |
enable_purge | 0 | true | Permits full deletion of module resources on destroy. |
public_access | 0 | false | Platform catalogue visibility. |
deployment_id | 0 | "" | Deployment ID suffix. Auto-generated if empty. |
resource_creator_identity | 0 | (platform SA) | Service account used by Terraform to manage resources. |
impersonation_service_account | 0 | "" | Service account to impersonate for GCP API calls. |
project_id | 1 | — | GCP project ID. Required. |
region | 1 | 'us-central1' | GCP region for all resources. |
tenant_deployment_id | 2 | 'demo' | Short suffix appended to all resource names. |
support_users | 2 | [] | Email addresses for monitoring alerts. |
resource_labels | 2 | {} | Labels applied to all provisioned resources. |
application_name | 3 | 'anythingllm' | Base resource name. Do not change after initial deployment. |
application_display_name | 3 | 'AnythingLLM' | Human-readable name. |
application_description | 3 | 'AnythingLLM Private AI Workspace on Cloud Run' | Service description. |
application_version | 3 | 'latest' | Container image version tag. |
deploy_application | 4 | true | Set false for infrastructure-only deployment. |
container_image_source | 4 | 'custom' | 'custom' (Cloud Build) or 'prebuilt' (existing image). |
container_image | 4 | "" | Container image URI. Leave empty for Cloud Build to manage. |
container_build_config | 4 | { enabled=true } | Cloud Build configuration object. |
enable_image_mirroring | 4 | true | Mirrors the container image into Artifact Registry. |
cpu_limit | 4 | '2000m' | CPU per instance. 2 vCPU minimum for AI workloads. |
memory_limit | 4 | '4Gi' | Memory per instance. 4 Gi minimum for AnythingLLM. |
min_instance_count | 4 | 1 | Minimum instances. Set to 1 to keep AnythingLLM warm. |
max_instance_count | 4 | 1 | Maximum instances. |
container_port | 4 | 3001 | AnythingLLM's native port. |
container_protocol | 4 | 'http1' | 'http1' or 'h2c'. |
execution_environment | 4 | 'gen2' | Gen2 required for NFS mounts and GCS Fuse. |
timeout_seconds | 4 | 300 | Max request duration. Increase for document ingestion. |
enable_cloudsql_volume | 4 | true | Injects Cloud SQL Auth Proxy sidecar. |
cloudsql_volume_mount_path | 4 | '/cloudsql' | Container path for the Auth Proxy socket. |
traffic_split | 4 | [] | Canary/blue-green traffic allocation. |
service_annotations | 4 | {} | Advanced Cloud Run annotations. |
service_labels | 4 | {} | Labels applied to the Cloud Run service. |
ingress_settings | 5 | 'all' | 'all', 'internal', or 'internal-and-cloud-load-balancing'. |
vpc_egress_setting | 5 | 'PRIVATE_RANGES_ONLY' | 'PRIVATE_RANGES_ONLY' or 'ALL_TRAFFIC'. |
enable_iap | 5 | false | Enables IAP on the Cloud Run service. |
iap_authorized_users | 5 | [] | Users/SAs granted IAP access. |
iap_authorized_groups | 5 | [] | Google Groups granted IAP access. |
environment_variables | 6 | {} | Plain-text env vars. Do not include secret values. |
secret_environment_variables | 6 | {} | Secret Manager references (e.g., { OPENAI_API_KEY = "anythingllm-openai-key" }). |
secret_rotation_period | 6 | '2592000s' | Secret rotation notification frequency. |
secret_propagation_delay | 6 | 30 | Seconds to wait after secret creation. |
backup_schedule | 7 | '0 2 * * *' | Cron expression (UTC) for automated backups. |
backup_retention_days | 7 | 7 | Days to retain backup files in GCS. |
enable_backup_import | 7 | false | Triggers a one-time restore on apply. |
backup_source | 7 | 'gcs' | 'gcs' or 'gdrive'. |
backup_file | 7 | 'backup.sql' | Backup filename to import. |
backup_format | 7 | 'sql' | Backup format. Options: sql, tar, gz, tgz, tar.gz, zip, auto. |
enable_cicd_trigger | 8 | false | Provisions a Cloud Build GitHub trigger. |
github_repository_url | 8 | "" | Full HTTPS URL of the GitHub repository. |
github_token | 8 | "" | GitHub PAT. Sensitive. |
github_app_installation_id | 8 | "" | GitHub App installation ID. |
cicd_trigger_config | 8 | { branch_pattern = "^main$" } | Advanced Cloud Build trigger config. |
enable_cloud_deploy | 8 | false | Provisions a Cloud Deploy pipeline. |
cloud_deploy_stages | 8 | [dev, staging, prod(approval)] | Ordered Cloud Deploy promotion stages. |
enable_binary_authorization | 8 | false | Enforces image attestation on deployment. |
enable_custom_sql_scripts | 9 | false | Runs SQL scripts from GCS after provisioning. |
custom_sql_scripts_bucket | 9 | "" | GCS bucket containing SQL scripts. |
custom_sql_scripts_path | 9 | "" | Path prefix within the bucket. |
custom_sql_scripts_use_root | 9 | false | Run scripts as the root DB user. |
enable_cloud_armor | 10 | false | Provisions Global HTTPS LB + Cloud Armor WAF. |
admin_ip_ranges | 10 | [] | CIDR ranges exempted from WAF rules. |
application_domains | 10 | [] | Custom domains with Google-managed SSL certificates. |
enable_cdn | 10 | false | Enables Cloud CDN on the HTTPS LB backend. |
max_images_to_retain | 10 | 7 | Maximum container images to keep in Artifact Registry. |
delete_untagged_images | 10 | true | Automatically deletes untagged images. |
image_retention_days | 10 | 30 | Days after which images are eligible for deletion. |
create_cloud_storage | 11 | true | Set false to skip GCS bucket creation. |
storage_buckets | 11 | [{ name_suffix = "data" }] | Additional GCS buckets to provision. |
enable_nfs | 11 | false | Provisions NFS shared storage. Requires gen2. |
nfs_mount_path | 11 | '/mnt/nfs' | Container path where NFS is mounted. |
nfs_instance_name | 11 | "" | Name of an existing NFS GCE VM. |
nfs_instance_base_name | 11 | 'app-nfs' | Base name for inline NFS VM. |
gcs_volumes | 11 | [] | GCS buckets to mount via GCS Fuse (requires gen2). |
manage_storage_kms_iam | 11 | false | Creates CMEK KMS key and enables CMEK on storage buckets. |
enable_artifact_registry_cmek | 11 | false | Creates Artifact Registry KMS key for at-rest image encryption. |
database_type | 12 | 'POSTGRES_15' | Cloud SQL engine. AnythingLLM requires PostgreSQL. |
application_database_name | 12 | 'anythingllmdb' | PostgreSQL database name. |
application_database_user | 12 | 'anythingllmuser' | Database user. |
database_password_length | 12 | 32 | Auto-generated password length. Range: 16–64. |
enable_auto_password_rotation | 12 | false | Automated zero-downtime password rotation. |
rotation_propagation_delay_sec | 12 | 90 | Seconds to wait after rotation before restarting. |
db_host_env_var_name | 12 | "" | Additional env var name for DB_HOST. |
db_user_env_var_name | 12 | "" | Additional env var name for DB_USER. |
db_name_env_var_name | 12 | "" | Additional env var name for DB_NAME. |
db_port_env_var_name | 12 | "" | Additional env var name for DB_PORT. |
service_url_env_var_name | 12 | "" | Additional env var name for CLOUDRUN_SERVICE_URL. |
initialization_jobs | 13 | [] | One-shot Cloud Run Jobs. Leave empty for default db-init. |
cron_jobs | 13 | [] | Recurring scheduled Cloud Run Jobs. |
additional_services | 13 | [] | Additional Cloud Run services alongside AnythingLLM. |
startup_probe | 14 | { path="/api/ping", initial_delay_seconds=60, failure_threshold=30, ... } | Startup probe. Long delay for AI model loading. |
liveness_probe | 14 | { path="/api/ping", initial_delay_seconds=30, failure_threshold=3, ... } | Liveness probe. |
startup_probe_config | 14 | (same as startup_probe) | Alias passed to App CloudRun. |
health_check_config | 14 | (same as liveness_probe) | Alias passed to App CloudRun. |
uptime_check_config | 14 | { enabled=true, path="/" } | Cloud Monitoring uptime check. |
alert_policies | 14 | [] | Cloud Monitoring metric alert policies. |
enable_redis | 21 | false | Enables Redis. Not required for AnythingLLM core functionality. |
redis_host | 21 | null | Redis hostname or IP. Required when enable_redis = true. |
redis_port | 21 | '6379' | Redis TCP port (string). |
redis_auth | 21 | "" | Redis AUTH password. Sensitive. |
enable_vpc_sc | 22 | false | Registers API calls within the project's VPC-SC perimeter. |
vpc_cidr_ranges | 22 | [] | VPC subnet CIDR ranges for VPC-SC network access level. |
vpc_sc_dry_run | 22 | true | Logs VPC-SC violations without blocking. |
organization_id | 22 | "" | GCP Organization ID for VPC-SC. |
enable_audit_logging | 22 | false | Enables detailed Cloud Audit Logs. |
11. Outputs
| Output | Description |
|---|---|
service_name | Name of the Cloud Run service. |
service_url | Public URL of the Cloud Run service. |
service_location | GCP region where the Cloud Run service is deployed. |
project_id | GCP project ID. |
deployment_id | Deployment ID suffix used in resource names. |
database_instance_name | Name of the Cloud SQL PostgreSQL instance. |
database_name | Name of the application database. |
database_user | Name of the application database user. |
database_password_secret | Secret Manager secret name for the database password. |
database_host | Database host IP address (sensitive). |
database_port | Database port. |
storage_buckets | Created GCS storage buckets. |
nfs_server_ip | NFS server internal IP (sensitive). |
nfs_mount_path | NFS mount path inside containers. |
container_image | Container image used for the deployment. |
container_registry | Artifact Registry repository name. |
deployment_summary | Summary of the deployment. |
initialization_jobs | Created initialization job names. |
cicd_enabled | Whether the CI/CD pipeline is enabled. |
github_repository_url | GitHub repository URL connected for CI/CD. |
artifact_registry_repository | Artifact Registry repository for container images. |
cloudbuild_trigger_name | Cloud Build trigger name for CI/CD. |
monitoring_enabled | Whether monitoring is configured. |
Configuration Pitfalls & Sensible Defaults
Risk levels: Critical (data loss, full outage, security breach) — High (service unavailable or significant degradation) — Medium (degraded function or increased cost) — Low (minor impact).
| Variable | Sensible Default | Risk | Consequence of Incorrect Value |
|---|---|---|---|
JWT_SECRET (auto-generated) | Random secret stored in Secret Manager | Critical | AnythingLLM uses JWT_SECRET to sign all user authentication tokens. Rotating or changing it immediately invalidates all active sessions and logs out every user. Treat as immutable after first login. |
AUTH_TOKEN (optional) | "" (no token required) | High | AUTH_TOKEN acts as a global API bearer token for AnythingLLM's REST API. If left empty, the API is unauthenticated (only protected by network-level controls). Set a strong value and distribute it only to authorised callers. |
STORAGE_DIR / document storage | GCS Fuse mount | Critical | AnythingLLM stores all workspace documents, vector embeddings, and LLM configuration under STORAGE_DIR. If this directory is not on a persistent volume (GCS Fuse or NFS), all data is lost on every container restart. Never point STORAGE_DIR to the container's local filesystem without a persistent backend. |
enable_nfs | false | High | Without NFS or GCS Fuse, vector indices and uploaded documents are ephemeral. For multi-instance deployments (max_instance_count > 1) shared storage is required or each pod has an inconsistent view of the workspace data. |
nfs_mount_path | "/mnt/nfs" | High | Must match the STORAGE_DIR environment variable passed to AnythingLLM. A mismatch means the app writes to a local path while the NFS mount is unused, and data is lost on restart. |
LLM_PROVIDER (via environment_variables) | "native" (built-in) | Critical | Without setting the correct LLM_PROVIDER value and corresponding API key, AnythingLLM falls back to its built-in model or errors on all AI requests. When using OpenAI, set LLM_PROVIDER = "openai" and provide OPENAI_API_KEY via secret_environment_variables. |
EMBEDDING_ENGINE (via environment_variables) | "native" | High | The embedding engine must be consistent across all documents in a workspace. Changing EMBEDDING_ENGINE after ingesting documents makes existing vector indices incompatible — re-ingest all documents after any change. |
secret_environment_variables (API keys) | {} (none) | Critical | AI provider API keys (OPENAI_API_KEY, ANTHROPIC_API_KEY, etc.) must be provided via secret_environment_variables pointing to existing Secret Manager secrets. Providing them as plain environment_variables exposes them in Cloud Run revision metadata. |
memory_limit | 4Gi | High | AnythingLLM loads embedding models into memory during document ingestion. Running the native embedding engine with less than 4 Gi causes OOM-kills during ingestion of large documents. |
cpu_limit | 2000m | Medium | AnythingLLM AI workloads are CPU-intensive. With less than 2 vCPU, embedding and inference operations run slowly and Cloud Run requests may time out. |
min_instance_count | 1 | High | Scale-to-zero causes 30–60 s cold starts. For a knowledge workspace used interactively, set to 1 to keep a warm instance. With scale-to-zero, in-memory vector index state is rebuilt on each cold start from the persistent storage. |
timeout_seconds | 300 | High | Document ingestion for large files (PDFs, long text) can take several minutes. Requests time out with a 504 if timeout_seconds is too low. Increase to 600–3600 for document-heavy workloads. |
database_type | "POSTGRES" | Critical | AnythingLLM requires PostgreSQL for workspace metadata, user accounts, and conversation history. Using "NONE" causes the application to fall back to SQLite which is not persistent on Cloud Run. |
enable_cloudsql_volume | true | Critical | Disabling the Cloud SQL Auth Proxy while relying on Cloud SQL causes all database connections to fail at startup. |
ingress_settings | "all" | High | "all" exposes the AnythingLLM workspace publicly. Only the login form protects it. Enable IAP (enable_iap = true) for production deployments, especially if AUTH_TOKEN is not set. |
enable_iap | false | High | Without IAP, access control relies solely on the application login. Enabling IAP provides an additional authentication layer before the application is reached. |
gcs_volumes | Auto-provisioned for document storage | High | The GCS volume stores all workspace documents. Without implicit-dirs in the mount options, AnythingLLM cannot list files stored in subdirectories and document browsing fails. |
execution_environment | "gen2" | High | NFS mounts require gen2. If enable_nfs = true with gen1, the NFS volume silently fails to mount and all document writes go to the ephemeral container filesystem. |
backup_schedule | "" (disabled) | High | Without automated backups, the PostgreSQL metadata database (workspaces, users, settings) is unprotected. Enable and set backup_retention_days for production. |
enable_redis | false | Low | Redis is optional for AnythingLLM core functionality. If enabled, redis_host must be set or the container will fail to start with a connection error on Redis initialisation. |
VECTOR_DB (via environment_variables) | "lancedb" (built-in) | High | Changing the vector database engine after workspaces have been populated requires re-ingesting all documents. Existing vectors are stored in the previous engine's format and are not automatically migrated. |
application_version | "latest" | Medium | AnythingLLM releases may change the database schema. An unplanned upgrade can run migrations that are incompatible with the current schema, crashing startup. Pin to a specific release in production. |
Destroying Resources
Known Deletion Issue: Serverless IPv4 Address Release
When destroying a Cloud Run deployment, you may encounter an error similar to:
Error: Error waiting for Subnetwork to be deleted: The following serverless IPv4 address(es) on subnet ... are still in use.
Cause: GCP holds serverless IPv4 addresses on the VPC subnet asynchronously after a Cloud Run service is deleted. These addresses are released by GCP approximately 20–30 minutes after the Cloud Run service is removed.
Resolution: Wait 20–30 minutes after the initial destroy attempt, then re-run:
tofu destroy
The second run will succeed once GCP has released the reserved addresses.