feat: add GCP serverless and containerized deployment#263
feat: add GCP serverless and containerized deployment#263kavindu-yl wants to merge 1 commit intodevelopfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds initial GCP deployment support to mirror existing AWS patterns, introducing Terraform modules for Cloud Run + API Gateway and example OpenAI agent deployments.
Changes:
- Added GCP “serverless” and “containerized” Terraform modules (Cloud Run + API Gateway), including VPC connector and optional Redis/Firestore.
- Added shared GCP infrastructure modules (VPC, Artifact Registry build/push, GCS, Memorystore, Firestore).
- Added runnable example OpenAI deployments for both GCP modes (packaging scripts, Dockerfiles, Terraform deploy configs).
Reviewed changes
Copilot reviewed 66 out of 68 changed files in this pull request and generated 36 comments.
Show a summary per file
| File | Description |
|---|---|
| examples/gcp-serverless/openai/pyproject.toml | Python deps/tooling for serverless GCP OpenAI example |
| examples/gcp-serverless/openai/deploy/variables.tf | Terraform inputs for serverless example |
| examples/gcp-serverless/openai/deploy/terraform.tfvars | Sample values for serverless example |
| examples/gcp-serverless/openai/deploy/outputs.tf | Exposes invocation URL output for example |
| examples/gcp-serverless/openai/deploy/main.tf | Wires example to ak-gcp/serverless module |
| examples/gcp-serverless/openai/deploy/deploy.sh | Builds example dist package for deployment |
| examples/gcp-serverless/openai/deploy/Dockerfile | Runtime container image for serverless example |
| examples/gcp-serverless/openai/config.yaml | Example runtime configuration |
| examples/gcp-serverless/openai/build.sh | Local venv + dependency sync for example |
| examples/gcp-serverless/openai/app.py | Example agent + custom routes |
| examples/gcp-serverless/openai/.gitignore | Ignores local build/terraform artifacts |
| examples/gcp-containerized/openai/pyproject.toml | Python deps/tooling for containerized GCP OpenAI example |
| examples/gcp-containerized/openai/deploy/variables.tf | Terraform inputs for containerized example |
| examples/gcp-containerized/openai/deploy/terraform.tfvars | Sample values for containerized example |
| examples/gcp-containerized/openai/deploy/outputs.tf | Exposes invocation URL output for example |
| examples/gcp-containerized/openai/deploy/main.tf | Wires example to ak-gcp/containerized module |
| examples/gcp-containerized/openai/deploy/deploy.sh | Builds example dist package for deployment |
| examples/gcp-containerized/openai/deploy/Dockerfile | Runtime container image for containerized example |
| examples/gcp-containerized/openai/config.yaml | Example runtime configuration |
| examples/gcp-containerized/openai/build.sh | Local venv + dependency sync for example |
| examples/gcp-containerized/openai/app.py | Example agent + custom routes/handler |
| examples/gcp-containerized/openai/.gitignore | Ignores local build/terraform artifacts |
| ak-deployment/ak-gcp/serverless/variables.tf | Inputs for serverless Cloud Run + API Gateway module |
| ak-deployment/ak-gcp/serverless/state.tf | Locals + wiring to common modules (VPC/AR/Redis/FS) |
| ak-deployment/ak-gcp/serverless/run.md | How-to guide for running serverless module |
| ak-deployment/ak-gcp/serverless/outputs.tf | Outputs for Cloud Run + API Gateway deployment |
| ak-deployment/ak-gcp/serverless/main.tf | Providers + version constraints for module |
| ak-deployment/ak-gcp/serverless/cloud_function.tf | Cloud Run service, IAM, VPC connector, probes |
| ak-deployment/ak-gcp/serverless/api_gateway.tf | OpenAPI spec generation + API Gateway resources |
| ak-deployment/ak-gcp/serverless/README.md | Module documentation for serverless deployment |
| ak-deployment/ak-gcp/serverless/.gitignore | Ignores terraform state/artifacts |
| ak-deployment/ak-gcp/containerized/variables.tf | Inputs for containerized Cloud Run + API Gateway module |
| ak-deployment/ak-gcp/containerized/state.tf | Locals + wiring to common modules (VPC/AR/Redis/FS) |
| ak-deployment/ak-gcp/containerized/run.md | How-to guide for running containerized module |
| ak-deployment/ak-gcp/containerized/outputs.tf | Outputs for Cloud Run + API Gateway deployment |
| ak-deployment/ak-gcp/containerized/main.tf | Providers + version constraints for module |
| ak-deployment/ak-gcp/containerized/cloud_run.tf | Cloud Run service, IAM, VPC connector, probes |
| ak-deployment/ak-gcp/containerized/api_gateway.tf | OpenAPI spec generation + API Gateway resources |
| ak-deployment/ak-gcp/containerized/README.md | Module documentation for containerized deployment |
| ak-deployment/ak-gcp/containerized/.gitignore | Ignores terraform state/artifacts |
| ak-deployment/ak-gcp/common/versions.tf | Shared provider/version constraints |
| ak-deployment/ak-gcp/common/variables.tf | Placeholder root module variables |
| ak-deployment/ak-gcp/common/run.md | Validation/how-to for common modules |
| ak-deployment/ak-gcp/common/outputs.tf | Placeholder root module outputs |
| ak-deployment/ak-gcp/common/main.tf | Dummy root module definition |
| ak-deployment/ak-gcp/common/README.md | Documentation for common module collection |
| ak-deployment/ak-gcp/common/modules/vpc/variables.tf | VPC module inputs |
| ak-deployment/ak-gcp/common/modules/vpc/outputs.tf | VPC module outputs |
| ak-deployment/ak-gcp/common/modules/vpc/main.tf | VPC/subnets/router/NAT/firewall resources |
| ak-deployment/ak-gcp/common/modules/vpc/README.md | VPC module documentation |
| ak-deployment/ak-gcp/common/modules/memorystore/variables.tf | Memorystore module inputs |
| ak-deployment/ak-gcp/common/modules/memorystore/outputs.tf | Memorystore module outputs (URLs/secrets) |
| ak-deployment/ak-gcp/common/modules/memorystore/main.tf | Redis instance + peering route export |
| ak-deployment/ak-gcp/common/modules/memorystore/README.md | Memorystore module documentation |
| ak-deployment/ak-gcp/common/modules/gcs/variables.tf | GCS module inputs |
| ak-deployment/ak-gcp/common/modules/gcs/outputs.tf | GCS module outputs |
| ak-deployment/ak-gcp/common/modules/gcs/main.tf | GCS bucket creation/config |
| ak-deployment/ak-gcp/common/modules/gcs/README.md | GCS module documentation |
| ak-deployment/ak-gcp/common/modules/firestore/variables.tf | Firestore module inputs |
| ak-deployment/ak-gcp/common/modules/firestore/outputs.tf | Firestore module outputs |
| ak-deployment/ak-gcp/common/modules/firestore/main.tf | Firestore DB + TTL field + index |
| ak-deployment/ak-gcp/common/modules/firestore/README.md | Firestore module documentation |
| ak-deployment/ak-gcp/common/modules/artifact-registry/variables.tf | Artifact Registry module inputs |
| ak-deployment/ak-gcp/common/modules/artifact-registry/outputs.tf | Artifact Registry module outputs (image/repo) |
| ak-deployment/ak-gcp/common/modules/artifact-registry/main.tf | AR repo + docker build/push (dir hash tag) |
| ak-deployment/ak-gcp/common/modules/artifact-registry/README.md | Artifact Registry module documentation |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "x-google-backend" = { | ||
| address = "${local.service_url}${ep.overwrite_path}" | ||
| path_translation = "APPEND_PATH_TO_ADDRESS" | ||
| } |
There was a problem hiding this comment.
For ANY endpoints, path_translation = "APPEND_PATH_TO_ADDRESS" is used even though address already includes ${ep.overwrite_path}. That combination appends the incoming request path to an already-pathed backend URL and will generate incorrect backend requests. Use CONSTANT_ADDRESS when overwrite_path is a complete target path, or set address to the bare service URI if path-appending is intended.
| function_name = "run" | ||
| function_description = "OpenAI Agent Function" | ||
|
|
||
| package_type = "Image" | ||
| package_path = "${path.module}/deploy" |
There was a problem hiding this comment.
The usage example sets function_name / function_description / package_type, but this module’s variables.tf doesn’t define those inputs (it’s Cloud Run-based). Update the example to only reference supported variables so copy/paste works.
| | Name | Description | | ||
| |------|-------------| | ||
| | function_url | Direct Cloud Function HTTPS URL | | ||
| | function_name | Cloud Function resource name | | ||
| | function_service_account | Service account email | |
There was a problem hiding this comment.
The Outputs table lists Cloud Function outputs (function_url, function_name, function_service_account), but the module exports Cloud Run outputs (service_url, service_name, service_account_email). Align the README outputs with outputs.tf.
| project = var.project_id | ||
| location = var.region | ||
| name = google_cloud_run_v2_service.service.name | ||
| role = "roles/run.invoker" | ||
| member = "allUsers" |
There was a problem hiding this comment.
This IAM binding makes the Cloud Run service directly public (member = "allUsers"), which bypasses API Gateway controls via service_url. Make unauthenticated invocation configurable and default to granting roles/run.invoker only to the API Gateway service account.
| "x-google-backend" = { | ||
| address = "${local.service_url}${ep.overwrite_path}" | ||
| path_translation = "APPEND_PATH_TO_ADDRESS" | ||
| } |
There was a problem hiding this comment.
For ANY endpoints, path_translation = "APPEND_PATH_TO_ADDRESS" is used while address already includes ${ep.overwrite_path}. This will append the incoming request path onto an address that already has a fixed path segment, producing incorrect backend URLs. Prefer CONSTANT_ADDRESS when using a fixed overwrite_path, or set address to just the service URI when you truly want path-appending behavior.
| module_name = "chatbot" | ||
| function_name = "my-agent" | ||
| package_path = "../../../examples/aws-serverless/openai/dist" |
There was a problem hiding this comment.
The sample dev.tfvars includes function_name and points package_path at an AWS example directory. Update the tfvars example to match this module’s variables and point at a Cloud Run Docker build context for the GCP examples.
| @router.post("/app_info") | ||
| def custom_app_info_handler(): | ||
| return {"response": "Hello! from AK 'app_info'"} |
There was a problem hiding this comment.
With disallow_untyped_defs = true in mypy config, this handler also needs a return type annotation (and any parameter types) to avoid mypy failures for the example.
| output "agent_invoke_url" { | ||
| description = "The URL to invoke the agent Cloud Function" | ||
| value = module.serverless_agents.agent_invoke_url |
There was a problem hiding this comment.
The output description says “Cloud Function”, but this example deploys to Cloud Run + API Gateway. Updating the wording avoids confusion when users read terraform output.
| gcloud services enable compute.googleapis.com | ||
| gcloud services enable cloudfunctions.googleapis.com | ||
| gcloud services enable cloudbuild.googleapis.com | ||
| gcloud services enable run.googleapis.com |
There was a problem hiding this comment.
This section enables cloudfunctions.googleapis.com / cloudbuild.googleapis.com, but the module provisions Cloud Run (google_cloud_run_v2_service) + API Gateway. Update the enabled APIs list to the minimal set required for Cloud Run + API Gateway to avoid misleading setup steps.
| ```bash | ||
| # Cloud Function logs | ||
| gcloud functions logs read myapp-dev-chatbot-function \ | ||
| --region=us-central1 --gen2 --limit=50 | ||
|
|
There was a problem hiding this comment.
This module deploys Cloud Run, but the log command shown is for Cloud Functions (gcloud functions logs ...). Replace with the equivalent Cloud Run logs command (e.g. gcloud run services logs read ...) so the guide matches what’s actually deployed.
|
@kavindu-yl Can you please add the following also,
|
Description
Initial GCP deployment implementation with serverless and containerized modules using Cloud Run and API Gateway.
Type of Change
Related Issues
Relates to #
Changes Made
Testing
Checklist
Additional Notes
Basic GCP deployment implementation to match AWS serverless and containerized modules.