Use Cases (अपडेट: 3/6/2026)

Claude Code से GCP Cloud Functions बनाना: HTTP, Secret Manager, Cloud Logging

Claude Code से Cloud Run functions बनाएं: HTTP, secrets, logging, deploy checks और आम pitfalls.

Claude Code से GCP Cloud Functions बनाना: HTTP, Secret Manager, Cloud Logging

Google Cloud की मौजूदा documentation में Cloud Functions को अक्सर Cloud Run functions के रूप में समझाया जाता है। इसका व्यावहारिक मतलब यह है कि आप source code deploy करते हैं, Google Cloud उसे container में build करता है, और वह HTTP request या event से चलने वाली Cloud Run service के रूप में चलता है।

इस guide में Claude Code से GCP Cloud Functions बनाने का पूरा flow है: Node.js की एक HTTP function, Eventarc के जरिए Cloud Storage event लेने वाली function, Secret Manager, Cloud Logging, और deploy के बाद verification। Eventarc Google Cloud में events पहुँचाने वाली layer है। Functions Framework वह adapter है जिससे वही function shape local machine और cloud दोनों जगह चलती है।

ClaudeCodeLab में मैं Cloud Run functions को तब चुनता हूँ जब काम छोटा और साफ हो: webhook receive करना, हल्की notification भेजना, CSV import trigger करना, या scheduled job का entry point बनाना। अगर कई routes, full API, Next.js या Express, WebSocket, custom Dockerfile, लंबा processing time, या container पर ज्यादा control चाहिए, तो Cloud Run बेहतर है। इस पर GCP Cloud Run guide में अलग से बात की गई है।

Claude Code repeat होने वाली चीजें बनाने में अच्छा है: package.json, Functions Framework registration, curl commands, gcloud run deploy, IAM notes, और review prompt। फिर भी authentication, Secret Manager, retries, idempotency, और logs को इंसान से review कराना जरूरी है। Idempotency का मतलब है कि वही request या event दो बार आए, फिर भी result खराब या duplicate न हो।


अच्छे use cases

Use caseEntry pointReview में क्या देखना है
Stripe, GitHub या internal tool webhooksHTTP functionSignature check, Bearer token, replay handling, Secret Manager
Cloud Storage upload के बाद CSV importEventarc + CloudEvent functionDuplicate events, bucket region, file naming rules
Contact form notificationHTTP function या Pub/Sub handoffतेज 200 response, queue handoff, rate limits
Nightly sync या report triggerCloud Scheduler + HTTP functionOIDC authentication, time zone, timeout

ये cases Claude Code के लिए अच्छे हैं क्योंकि input, validation, logging, और failure behavior को checklist में बदला जा सकता है। Design तब कमजोर होता है जब एक function में बहुत सारे काम भर दिए जाएँ, लंबे loops चलें, या उसे पूरी public API बना दिया जाए।

Team process के लिए Claude Code code review और Claude Code secrets management को भी साथ पढ़ना उपयोगी है।


Minimal project

यह example CommonJS Node.js का है ताकि build step की जरूरत न पड़े। Official docs में Functions Framework से functions register की जाती हैं, और वही framework local में भी चलता है।

functions-demo/
  index.js
  package.json
{
  "name": "claude-code-gcp-functions-demo",
  "version": "1.0.0",
  "private": true,
  "main": "index.js",
  "scripts": {
    "start:http": "functions-framework --target=handleAction --port=8080",
    "start:event": "functions-framework --target=handleStorageObject --signature-type=cloudevent --port=8081"
  },
  "dependencies": {
    "@google-cloud/firestore": "^7.11.0",
    "@google-cloud/functions-framework": "^3.4.6"
  }
}
npm install

Function code

इसे index.js के रूप में save करें। HTTP function Authorization: Bearer ... check करती है और Idempotency-Key को duplicate रोकने वाली key की तरह इस्तेमाल करती है। Storage function CloudEvent ID को Firestore में save करती है ताकि retry हुआ event वही job दो बार न बनाए।

const functions = require("@google-cloud/functions-framework");
const { Firestore } = require("@google-cloud/firestore");
const crypto = require("node:crypto");

const db = new Firestore();

function jsonLog(severity, message, extra = {}) {
  console.log(JSON.stringify({ severity, message, ...extra }));
}

function requireBearerToken(req) {
  const expected = process.env.API_TOKEN;
  const header = req.get("Authorization") || "";
  return Boolean(expected && header === `Bearer ${expected}`);
}

function stableHash(value) {
  return crypto.createHash("sha256").update(value).digest("hex");
}

functions.http("handleAction", async (req, res) => {
  if (req.method !== "POST") {
    res.status(405).json({ ok: false, error: "POST only" });
    return;
  }

  if (!requireBearerToken(req)) {
    res.status(401).json({ ok: false, error: "invalid token" });
    return;
  }

  const body = req.body || {};
  if (typeof body.userId !== "string" || typeof body.action !== "string") {
    res.status(400).json({ ok: false, error: "userId and action are required" });
    return;
  }

  const idempotencyKey =
    req.get("Idempotency-Key") ||
    stableHash(`${body.userId}:${body.action}:${body.requestedAt || ""}`);

  const requestRef = db.collection("function_requests").doc(idempotencyKey);
  const logRef = db.collection("action_logs").doc(idempotencyKey);

  try {
    let duplicate = false;
    await db.runTransaction(async (tx) => {
      const existing = await tx.get(requestRef);
      if (existing.exists) {
        duplicate = true;
        return;
      }

      tx.create(requestRef, {
        userId: body.userId,
        action: body.action,
        createdAt: new Date(),
        source: "handleAction"
      });
      tx.set(logRef, {
        userId: body.userId,
        action: body.action,
        createdAt: new Date()
      });
    });

    jsonLog("INFO", "action accepted", { userId: body.userId, duplicate });
    res.status(200).json({ ok: true, duplicate, idempotencyKey });
  } catch (error) {
    jsonLog("ERROR", "action failed", { error: String(error) });
    res.status(500).json({ ok: false, error: "internal error" });
  }
});

functions.cloudEvent("handleStorageObject", async (cloudEvent) => {
  const data = cloudEvent.data || {};
  const bucket = data.bucket;
  const name = data.name;

  if (!bucket || !name) {
    jsonLog("WARNING", "storage event missing bucket or name", { eventId: cloudEvent.id });
    return;
  }

  const eventRef = db.collection("processed_storage_events").doc(cloudEvent.id);
  const jobRef = db.collection("storage_import_jobs").doc(stableHash(`${bucket}/${name}`));

  await db.runTransaction(async (tx) => {
    const existing = await tx.get(eventRef);
    if (existing.exists) {
      jsonLog("INFO", "duplicate storage event ignored", { eventId: cloudEvent.id });
      return;
    }

    tx.create(eventRef, {
      bucket,
      name,
      eventType: cloudEvent.type,
      createdAt: new Date()
    });
    tx.set(jobRef, {
      bucket,
      name,
      status: "queued",
      updatedAt: new Date()
    }, { merge: true });
  });

  jsonLog("INFO", "storage import job queued", { bucket, name, eventId: cloudEvent.id });
});

Structured logs incident के समय Cloud Logging को उपयोगी बनाते हैं। Cloud Run stdout और stderr को अपने-आप Cloud Logging में भेजता है। severity, message, eventId, और userId वाली JSON lines plain text से कहीं बेहतर filter होती हैं।


Local tests

HTTP function start करें:

export API_TOKEN="local-token"
npm run start:http

दूसरे terminal से request भेजें:

curl -X POST http://localhost:8080 \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer local-token" \
  -H "Idempotency-Key: local-001" \
  -d '{"userId":"user-123","action":"login","requestedAt":"2026-06-03T00:00:00Z"}'

CloudEvent function start करें:

npm run start:event
curl -X POST http://localhost:8081 \
  -H "Content-Type: application/json" \
  -H "ce-id: local-event-001" \
  -H "ce-specversion: 1.0" \
  -H "ce-type: google.cloud.storage.object.v1.finalized" \
  -H "ce-source: //storage.googleapis.com/projects/_/buckets/demo-bucket" \
  -d '{"bucket":"demo-bucket","name":"inbox/sample.csv","metageneration":"1"}'

अगर local code Firestore से connect करता है, तो gcloud auth application-default login चलाएँ या अलग test project इस्तेमाल करें। Smoke tests को production data पर न चलाएँ।


Secret Manager और IAM

Token को source code या review में जाने वाली .env file में न रखें। उसे Secret Manager में रखें और access सिर्फ runtime service account को दें।

PROJECT_ID="$(gcloud config get-value project)"
REGION="asia-northeast1"
RUNTIME_SA="functions-runtime@${PROJECT_ID}.iam.gserviceaccount.com"

gcloud iam service-accounts create functions-runtime \
  --display-name="Functions runtime service account"

printf "replace-with-real-token" | gcloud secrets create api-token \
  --replication-policy="automatic" \
  --data-file=-

gcloud secrets add-iam-policy-binding api-token \
  --member="serviceAccount:${RUNTIME_SA}" \
  --role="roles/secretmanager.secretAccessor"

gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
  --member="serviceAccount:${RUNTIME_SA}" \
  --role="roles/datastore.user"

दो identities अलग रखें। Deploy करने वाले व्यक्ति को Cloud Run functions बनाने और service account इस्तेमाल करने की permission चाहिए। Runtime service account को सिर्फ वही minimum roles दें जो code सच में इस्तेमाल करता है।


gcloud run से deploy

मौजूदा flow gcloud run deploy का है। Private HTTP endpoint के लिए पहले authenticated service deploy करें:

gcloud run deploy handle-action \
  --source . \
  --function handleAction \
  --base-image nodejs24 \
  --region "${REGION}" \
  --service-account "${RUNTIME_SA}" \
  --no-allow-unauthenticated \
  --memory 512Mi \
  --timeout 60s \
  --max-instances 20

gcloud run services update handle-action \
  --region "${REGION}" \
  --update-secrets=API_TOKEN=api-token:latest

Storage event function के लिए पहले service deploy करें, फिर Eventarc trigger बनाएँ:

BUCKET="your-import-bucket"
EVENTARC_SA="eventarc-invoker@${PROJECT_ID}.iam.gserviceaccount.com"

gcloud iam service-accounts create eventarc-invoker \
  --display-name="Eventarc trigger invoker"

gcloud run deploy storage-import \
  --source . \
  --function handleStorageObject \
  --base-image nodejs24 \
  --region "${REGION}" \
  --service-account "${RUNTIME_SA}" \
  --no-allow-unauthenticated \
  --memory 512Mi \
  --timeout 120s \
  --max-instances 10

gcloud run services add-iam-policy-binding storage-import \
  --region "${REGION}" \
  --member="serviceAccount:${EVENTARC_SA}" \
  --role="roles/run.invoker"

gcloud eventarc triggers create storage-finalized-to-function \
  --location="${REGION}" \
  --destination-run-service=storage-import \
  --destination-run-region="${REGION}" \
  --event-filters="type=google.cloud.storage.object.v1.finalized" \
  --event-filters="bucket=${BUCKET}" \
  --service-account="${EVENTARC_SA}"

Eventarc trigger active होने में कुछ मिनट लग सकते हैं। Bucket region, trigger location, और Cloud Run region को साथ में design करें, क्योंकि latency, data residency, और pricing पर असर पड़ता है।


Logs और verification

Deploy के बाद सिर्फ URL देखकर रुकें नहीं। Endpoint test करें और logs पढ़ें।

SERVICE_URL="$(gcloud run services describe handle-action \
  --region "${REGION}" \
  --format='value(status.url)')"

curl -X POST "${SERVICE_URL}" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer replace-with-real-token" \
  -H "Idempotency-Key: prod-smoke-001" \
  -d '{"userId":"smoke-user","action":"deploy-check","requestedAt":"2026-06-03T00:00:00Z"}'

gcloud run services logs read handle-action \
  --region "${REGION}" \
  --limit 20

gcloud logging read \
  'resource.type="cloud_run_revision" AND resource.labels.service_name="handle-action" AND jsonPayload.message="action accepted"' \
  --limit 20 \
  --format json

Investigation के लिए जरूरी values log करें: event ID, file name, duplicate flag, external API status, और सुरक्षित business IDs। Token, पूरा message body, या personal data log न करें।


आम pitfalls

पहला, idempotency के बिना retries duplicate side effects बनाते हैं। Billing, email, inventory, और imports में saved event ID या business key जरूरी है।

दूसरा, Secret Manager access runtime service account को मिलना चाहिए। Deploy सफल हो सकता है, लेकिन production request Permission denied से fail हो सकती है।

तीसरा, public HTTP function को सिर्फ --allow-unauthenticated पर न छोड़ें। Public webhook में signature check, rate limit, और जरूरत हो तो API Gateway या Cloud Armor जोड़ें। Internal jobs के लिए authenticated calls बेहतर हैं।

चौथा, Cloud Run functions को full application host न बनाएं। कई routes, लंबे jobs, system packages, GPU, या fine container control के लिए Cloud Run, Cloud Run jobs, या Workflows बेहतर हैं।

पाँचवां, cost और cleanup को prompt में शामिल करें। Cloud Run scale to zero कर सकता है, फिर भी Artifact Registry, Cloud Build, Storage, Eventarc, और Cloud Logging cost ला सकते हैं।


Review prompt

Review this Cloud Run functions implementation.
Check:
- Functions Framework registration, gcloud run deploy --function, and package.json target match
- HTTP authentication, input validation, and error responses are safe
- Eventarc retries cannot create duplicate side effects
- Secret Manager values are not logged or returned in exceptions
- The runtime service account has only the minimum IAM roles
- Cloud Logging entries are structured enough for incident review
- Any workload that should be Cloud Run is not forced into a function

If there are issues, return severity, reason, corrected code, and verification commands.

ClaudeCodeLab ऐसी operational checklists को products और templates तथा team training में बदलता है। इससे serverless reviews repeatable बनते हैं और वे किसी एक senior engineer की memory पर निर्भर नहीं रहते।


Official docs


परिणाम

Test किया गया आकार छोटा है, लेकिन production जैसा है: Node.js 24 Cloud Run functions, local Functions Framework commands, curl से HTTP और CloudEvent checks, Secret Manager injection, Firestore based idempotency, और Cloud Logging queries। Real traffic लेने से पहले identity, logs, retries, region, और cost review करना सबसे जरूरी आदत है।

#claude-code #gcp #cloud-functions #typescript #serverless #pubsub
मुफ़्त

मुफ़्त PDF: Claude Code cheatsheet

Email डालें और commands, review habits तथा safe workflow वाली एक-page PDF पाएँ.

हम आपका data सुरक्षित रखते हैं और spam नहीं भेजते.

Masa

लेखक के बारे में

Masa

Claude Code workflow और team adoption पर काम करने वाला engineer.