Skip to main content
skill CX Codex

gcp-cloud-functions — Claude Code skill: deploy GCP functions

Lets the agent deploy serverless functions on Google Cloud Functions: HTTP, Pub/Sub, Cloud Storage and scheduled jobs.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add BagelHole/DevOps-Security-Agent-Skills --skill gcp-cloud-functions -a claude-code
Open on GitHub

What gcp-cloud-functions does

The skill hands your agent ready gcloud functions deploy commands for both Gen1 and Gen2, plus function examples in Python and Node.js and a comparison table of the two generations. Useful when you need a webhook, a bucket upload handler or a cron task without running a server.

It covers enabling the required APIs, IAM setup, deploying with triggers, reading logs and deleting functions. There are samples built on functions-framework, work with Pub/Sub, Firestore and Cloud Vision, and a Terraform config for google_cloudfunctions2_function. Local testing is covered too: functions-framework --target=hello_http --port=8080.

Before the first deploy you need an authenticated gcloud, the Cloud Functions, Cloud Build, Artifact Registry and Cloud Run APIs enabled, and the roles/cloudfunctions.developer role (or roles/run.developer for Gen2). Skip that and the deploy fails during the build step. Gen2 functions run on top of Cloud Run, so traffic billing lands there — worth checking your quotas first.

What it helps with

  • deploy an HTTP function to Google Cloud Functions
  • wire a function to a Pub/Sub topic
  • process file uploads landing in Cloud Storage
  • run a scheduled job without keeping a server
  • pick between Gen1 and Gen2 by memory and timeout limits

Example prompts for the agent

  • Deploy the hello-http HTTP function to us-central1 on python312
  • Set up process-order with an order-events topic trigger and retries
  • Show me how to read the last 50 log entries for hello-http

How to install gcp-cloud-functions

1Skills CLI (Vercel)

npx skills add BagelHole/DevOps-Security-Agent-Skills --skill gcp-cloud-functions -a claude-code

2Manually: put the files in place

~/.claude/skills/gcp-cloud-functions/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/gcp-cloud-functions/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about gcp-cloud-functions

How do I install gcp-cloud-functions in Claude?

Run npx skills add BagelHole/DevOps-Security-Agent-Skills --skill gcp-cloud-functions -a claude-code. The skill file lands at ~/.claude/skills/gcp-cloud-functions/SKILL.md.

What does gcp-cloud-functions do?

It gives the agent deploy commands and examples for Google Cloud Functions: HTTP, Pub/Sub, Cloud Storage and scheduled triggers. It also covers managing deployed functions and Terraform config.

How is Gen2 different from Gen1?

Gen2 runs on Cloud Run: up to 60 minutes timeout, 32 GB memory, 1000 requests per instance and Eventarc triggers. Gen1 caps at 9 minutes and 8 GB.

Source text

SKILL.md · MIT
---
name: gcp-cloud-functions
description: Deploy serverless functions on Google Cloud Functions. Configure triggers and manage deployments. Use when implementing serverless workloads on GCP.
license: MIT
metadata:
  author: devops-skills
  version: "1.0"
---

# GCP Cloud Functions

Build and deploy event-driven serverless applications with Google Cloud Functions (Gen1 and Gen2).

## When to Use

- Processing webhooks, API endpoints, or lightweight HTTP backends
- Reacting to events from Pub/Sub, Cloud Storage, Firestore, or Eventarc
- Running scheduled tasks (cron) without maintaining a server
- Building data-processing pipelines triggered by file uploads
- Prototyping microservices before committing to Cloud Run or GKE

## Prerequisites

- Google Cloud SDK (`gcloud`) installed and authenticated
- APIs enabled: Cloud Functions, Cloud Build, Artifact Registry, Cloud Run (Gen2)
- IAM role `roles/cloudfunctions.developer` (or `roles/run.developer` for Gen2)

```bash
gcloud services enable cloudfunctions.googleapis.com cloudbuild.googleapis.com \
  artifactregistry.googleapis.com run.googleapis.com eventarc.googleapis.com
```

## Gen1 vs Gen2 Comparison

| Feature | Gen1 | Gen2 (recommended) |
|---------|------|---------------------|
| Runtime | Cloud Functions infra | Built on Cloud Run |
| Max timeout | 9 minutes | 60 minutes |
| Max memory | 8 GB | 32 GB |
| Concurrency | 1 request/instance | Up to 1000/instance |
| Traffic splitting | No | Yes |
| Eventarc triggers | No | Yes |

## Deploy an HTTP Function (Gen2)

```bash
# Python HTTP function
gcloud functions deploy hello-http \
  --gen2 --region=us-central1 --runtime=python312 \
  --trigger-http --allow-unauthenticated \
  --entry-point=hello_http \
  --memory=256Mi --timeout=60s \
  --min-instances=0 --max-instances=100 \
  --set-env-vars=APP_ENV=production --source=.

# Node.js HTTP function
gcloud functions deploy hello-node \
  --gen2 --region=us-central1 --runtime=nodejs20 \
  --trigger-http --allow-unauthenticated \
  --entry-point=helloNode --memory=256Mi --source=.
```

## Deploy a Pub/Sub Triggered Function

```bash
gcloud pubsub topics create order-events

gcloud functions deploy process-order \
  --gen2 --region=us-central1 --runtime=python312 \
  --trigger-topic=order-events \
  --entry-point=process_order \
  --memory=512Mi --timeout=120s --retry \
  --service-account=order-processor@${PROJECT_ID}.iam.gserviceaccount.com \
  --source=.
```

## Deploy a Cloud Storage Triggered Function

```bash
gcloud functions deploy process-upload \
  --gen2 --region=us-central1 --runtime=python312 \
  --trigger-event-filters="type=google.cloud.storage.object.v1.finalized" \
  --trigger-event-filters="bucket=my-upload-bucket" \
  --entry-point=process_upload \
  --memory=1Gi --timeout=300s --source=.
```

## Deploy a Scheduled Function

```bash
gcloud functions deploy daily-cleanup \
  --gen2 --region=us-central1 --runtime=python312 \
  --trigger-http --no-allow-unauthenticated \
  --entry-point=daily_cleanup --source=.

gcloud scheduler jobs create http daily-cleanup-job \
  --schedule="0 2 * * *" \
  --uri="https://us-central1-${PROJECT_ID}.cloudfunctions.net/daily-cleanup" \
  --http-method=POST \
  --oidc-service-account-email=scheduler-sa@${PROJECT_ID}.iam.gserviceaccount.com \
  --location=us-central1
```

## Python Function Examples

```python
# main.py
import functions_framework
import base64, json
from flask import jsonify
from google.cloud import firestore

@functions_framework.http
def hello_http(request):
    """HTTP Cloud Function."""
    name = request.args.get("name", "World")
    return jsonify({"message": f"Hello, {name}!", "status": "ok"}), 200

@functions_framework.cloud_event
def process_order(cloud_event):
    """Triggered by a Pub/Sub message."""
    data = base64.b64decode(cloud_event.data["message"]["data"]).decode("utf-8")
    order = json.loads(data)
    db = firestore.Client()
    db.collection("orders").document(order["id"]).set({
        "status": "processing", "items": order["items"], "total": order["total"],
    })

@functions_framework.cloud_event
def process_upload(cloud_event):
    """Triggered when a file is uploaded to Cloud Storage."""
    data = cloud_event.data
    bucket_name, file_name = data["bucket"], data["name"]
    if not file_name.lower().endswith((".png", ".jpg", ".jpeg")):
        return
    from google.cloud import vision
    client = vision.ImageAnnotatorClient()
    image = vision.Image(source=vision.ImageSource(
        gcs_image_uri=f"gs://{bucket_name}/{file_name}"))
    labels = [l.description for l in client.label_detection(image=image).label_annotations]
    print(f"Labels for {file_name}: {labels}")
```

```
# requirements.txt
functions-framework==3.*
google-cloud-firestore==2.*
google-cloud-storage==2.*
google-cloud-vision==3.*
flask>=2.0
```

## Node.js Function Examples

```javascript
// index.js
const functions = require("@google-cloud/functions-framework");

functions.http("helloNode", (req, res) => {
  const name = req.query.name || "World";
  res.json({ message: `Hello, ${name}!`, status: "ok" });
});

functions.cloudEvent("processMessage", (cloudEvent) => {
  const data = Buffer.from(cloudEvent.data.message.data, "base64").toString();
  console.log(`Processing: ${JSON.parse(data)}`);
});
```

## Managing Deployed Functions

```bash
gcloud functions list --gen2 --region=us-central1
gcloud functions describe hello-http --gen2 --region=us-central1
gcloud functions logs read hello-http --gen2 --region=us-central1 --limit=50
gcloud functions delete hello-http --gen2 --region=us-central1 --quiet

# Update env vars without redeploying code
gcloud functions deploy hello-http --gen2 --region=us-central1 \
  --update-env-vars=APP_ENV=staging

# Test locally before deploying
functions-framework --target=hello_http --port=8080
```

## Terraform Configuration

```hcl
resource "google_cloudfunctions2_function" "api" {
  name     = "hello-http"
  location = "us-central1"

  build_config {
    runtime     = "python312"
    entry_point = "hello_http"
    source {
      storage_source {
        bucket = google_storage_bucket.source.name
        object = google_storage_bucket_object.source.name
      }
    }
  }

  service_config {
    min_instance_count    = 0
    max_instance_count    = 100
    available_memory      = "256Mi"
    timeout_seconds       = 60
    service_account_email = google_service_account.fn.email
    environment_variables = { APP_ENV = "production" }
  }
}

resource "google_cloud_run_service_iam_member" "invoker" {
  location = google_cloudfunctions2_function.api.location
  service  = google_cloudfunctions2_function.api.name
  role     = "roles/run.invoker"
  member   = "allUsers"
}

resource "google_cloudfunctions2_function" "processor" {
  name     = "process-order"
  location = "us-central1"

  build_config {
    runtime     = "python312"
    entry_point = "process_order"
    source {
      storage_source {
        bucket = google_storage_bucket.source.name
        object = google_storage_bucket_object.source.name
      }
    }
  }

  service_config {
    max_instance_count    = 50
    available_memory      = "512Mi"
    timeout_seconds       = 120
    service_account_email = google_service_account.fn.email
  }

  event_trigger {
    trigger_region = "us-central1"
    event_type     = "google.cloud.pubsub.topic.v1.messagePublished"
    pubsub_topic   = google_pubsub_topic.orders.id
    retry_policy   = "RETRY_POLICY_RETRY"
  }
}
```

## Troubleshooting

| Symptom | Cause | Fix |
|---------|-------|-----|
| `PERMISSION_DENIED` on deploy | Missing Cloud Build or Artifact Registry perms | Grant `roles/cloudbuild.builds.builder` to Cloud Build SA |
| Function deploys but returns 403 | Missing `roles/run.invoker` for Gen2 | Add `--allow-unauthenticated` or grant invoker role |
| Cold start latency > 5s | Large dependencies or no min instances | Set `--min-instances=1`; reduce deps; use lazy imports |
| Pub/Sub messages redelivered | Function errors or times out | Increase `--timeout`; fix error handling; add dead-letter topic |
| `Build failed` during deploy | Syntax error or missing dependency | Check `gcloud builds log`; verify requirements.txt |
| Cannot connect to VPC resource | Function not on VPC connector | Add `--vpc-connector=my-connector` to deploy |

## Related Skills

- **gcp-networking** - VPC connectors for accessing private resources from functions
- **gcp-cloud-sql** - Connecting Cloud Functions to managed databases
- **terraform-gcp** - Deploy Cloud Functions with Infrastructure as Code
- **gcp-gke** - When workloads outgrow serverless and need Kubernetes

© devops-skills · MIT · BagelHole/DevOps-Security-Agent-Skills

Similar skills

All skills for DevOps and infrastructure →

From the same set129

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor