0

So im only just starting with GCP/Python. and am still in the learning phase.

I'm using Terraform/Github to deploy my packages to GCP.

I'm trying to get a pub/sub to trigger a Cloud Run Function to run a Python script to connect to a PostgreSQL DB and do a simple count on a table and print it to the log. But it looks like it doesn't want to connect.

I have a few TF files to keep things a bit tidy, but put them all in the block below to show together

I don't want to go down the private IP via connector. its an extra $36 a month which i don't want to pay for something i'm just playing around with.

resource "google_cloudfunctions2_function" "monster_count_fn" {
  name     = var.function_name
  project  = var.project              # <— was var.project_id
  location = var.region

  build_config {
    runtime     = "python311"
    entry_point = "count_tmonsters"
    source {
      storage_source {
        bucket = var.code_bucket
        object = var.code_object
      }
    }
  }

  service_config {
    available_memory      = "256M"
    timeout_seconds       = 60
    max_instance_count    = 1
    service_account_email = google_service_account.game_engine.email
    environment_variables = {
      INSTANCE_CONNECTION_NAME = var.instance_connection_name
      DB_USER                  = var.db_user
      DB_NAME                  = var.db_name
    }
    ingress_settings = "ALLOW_ALL"
  }

  event_trigger {
    trigger_region = var.region
    event_type     = "google.cloud.pubsub.topic.v1.messagePublished"
    pubsub_topic   = google_pubsub_topic.monster_count.id
    retry_policy   = "RETRY_POLICY_RETRY"
  }

  # Make this function wait for your API enables
  depends_on = [
    google_project_service.cloudresourcemanager,
    google_project_service.project_apis
  ]
}

variable "db_user"    { 
  type = string 
  default = "[email protected]"
}

# Ensure the necessary APIs are enabled for the game_engine service account.
locals {
  game_engine_roles = {
    "roles/cloudsql.client"        = "sqladmin.googleapis.com"
    "roles/cloudsql.instanceUser"  = "sqladmin.googleapis.com"
    "roles/logging.logWriter"      = "logging.googleapis.com"
    "roles/eventarc.eventReceiver" = "eventarc.googleapis.com" # Required for Pub/Sub triggered Gen 2 functions
    # Add more if needed later (e.g. storage, secrets)
  }
}

# Grant the game engine service account the necessary roles for its operations.
# These roles are required for the game engine to interact with Cloud SQL, Pub/Sub, and other services. 
resource "google_project_iam_member" "game_engine_access" {
  for_each = local.game_engine_roles

  project  = var.project
  role     = each.key
  member   = "serviceAccount:${google_service_account.game_engine.email}"

  depends_on = [google_project_service.project_apis]
}

And below is the Python script i'm trying to run via the cloud function:

import base64
import json
import logging, sys, os
from google.cloud.sql.connector import Connector, IPTypes
import pg8000

logging.basicConfig(
    level=logging.DEBUG,
    format="%(levelname)s %(asctime)s %(filename)s:%(lineno)d - %(message)s",
    stream=sys.stdout,
    force=True,
)

connector = Connector()

def _get_conn():
    inst = os.environ["INSTANCE_CONNECTION_NAME"]
    db   = os.environ["DB_NAME"]
    user = os.environ["DB_USER"]
    logging.debug("Using instance=%s user=%s db=%s", inst, user, db)
    # Public IP path; IAM DB Auth
    return connector.connect(
        inst,
        "pg8000",
        user=user,
        db=db,
        enable_iam_auth=True,
        ip_type=IPTypes.PUBLIC,
    )

def _decode_event(event):
    try:
        if isinstance(event, dict) and "data" in event:
            return base64.b64decode(event["data"]).decode("utf-8", "ignore")
    except Exception as e:
        logging.warning("event decode failed: %s", e, exc_info=True)
    return None

def count_tmonsters(event, context):
    logging.debug("Handler start. eventId=%s, event=%s", getattr(context, "event_id", None), event)

    # Helpful runtime identity / env diagnostics
    logging.debug("ENV PROJECT_ID=%s, SERVICE_ACCOUNT=%s",
                  os.getenv("GCP_PROJECT") or os.getenv("GOOGLE_CLOUD_PROJECT"),
                  os.getenv("K_SERVICE_ACCOUNT") or os.getenv("GOOGLE_SERVICE_ACCOUNT") or "unknown")
    logging.debug("INSTANCE_CONNECTION_NAME=%s, DB_USER=%s, DB_NAME=%s",
                  os.getenv("INSTANCE_CONNECTION_NAME"), os.getenv("DB_USER"), os.getenv("DB_NAME"))

    msg = _decode_event(event)
    if msg:
        logging.info("Pub/Sub message: %s", msg)

    conn = None
    cur = None
    try:
        logging.debug("Attempting DB connection with IAM auth...")
        conn = _get_conn()
        logging.info("DB connection established")
        cur = conn.cursor()
        logging.debug("Running query…")
        cur.execute("SELECT COUNT(*) FROM tmonsters;")
        row = cur.fetchone()
        logging.info("monster_count=%s", row[0] if row else None)
    except Exception as e:
        logging.error("DB operation failed: %s", e, exc_info=True)
        # Surface a short line as well (some platforms trim long traces)
        logging.error("FAIL_REASON: %r", e)
    finally:
        try:
            if cur:
                cur.close()
        except Exception as e:
            logging.warning("cursor close error: %s", e, exc_info=True)
        try:
            if conn:
                conn.close()
        except Exception as e:
            logging.warning("conn close error: %s", e, exc_info=True)

    logging.debug("Handler end")

And when i check the log, all it shows is:

         monster-count-fn                2025-08-25 11:57:47.324  DEBUG 2025-08-25 11:57:47,325 main.py:25 - Using instance=cso-rpg-dev:europe-west2:cso-rpg-sql [email protected] db=rpg
         monster-count-fn                2025-08-25 11:57:47.323  DEBUG 2025-08-25 11:57:47,325 main.py:19 - Attempting DB connection with IAM auth...
         monster-count-fn                2025-08-25 11:57:47.323  DEBUG 2025-08-25 11:57:47,324 main.py:45 - Handler start. eventId=15973659715120867, event={'data': 'dGVzdA==', 'message_id': '15973659715120867', 'publish_time': '2025-08-25T11:19:58.156Z'}
E        monster-count-fn                2025-08-25 11:57:47.304
         monster-count-fn                2025-08-25 11:56:40.205  DEBUG 2025-08-25 11:56:40,206 main.py:25 - Using instance=cso-rpg-dev:europe-west2:cso-rpg-sql [email protected] db=rpg
         monster-count-fn                2025-08-25 11:56:40.205  DEBUG 2025-08-25 11:56:40,206 main.py:19 - Attempting DB connection with IAM auth...
         monster-count-fn                2025-08-25 11:56:40.205  DEBUG 2025-08-25 11:56:40,206 main.py:45 - Handler start. eventId=15975546303899728, event={'data': 'dGVzdA==', 'message_id': '15975546303899728', 'publish_time': '2025-08-25T11:55:50.993Z'}
E        monster-count-fn                2025-08-25 11:56:38.272
         monster-count-fn                2025-08-25 11:55:40.211  DEBUG 2025-08-25 11:55:40,212 main.py:25 - Using instance=cso-rpg-dev:europe-west2:cso-rpg-sql [email protected] db=rpg
         monster-count-fn                2025-08-25 11:55:40.211  DEBUG 2025-08-25 11:55:40,212 main.py:19 - Attempting DB connection with IAM auth...
         monster-count-fn                2025-08-25 11:55:40.211  DEBUG 2025-08-25 11:55:40,212 main.py:45 - Handler start. eventId=15973204489076835, event={'data': 'dGVzdA==', 'message_id': '15973204489076835', 'publish_time': '2025-08-25T11:22:56.173Z'}
E        monster-count-fn                2025-08-25 11:55:40.175
I        monster-count-fn                2025-08-25 11:52:32.048  Default STARTUP TCP probe succeeded after 1 attempt for container "worker" on port 8080.
         monster-count-fn                2025-08-25 11:52:31.933  DEBUG 2025-08-25 11:52:31,934 connectionpool.py:544 - http://metadata.google.internal:80 "GET /computeMetadata/v1/universe/universe-domain HTTP/1.1" 200 14
         monster-count-fn                2025-08-25 11:52:31.932  DEBUG 2025-08-25 11:52:31,932 connectionpool.py:241 - Starting new HTTP connection (1): metadata.google.internal:80
         monster-count-fn                2025-08-25 11:52:31.883  DEBUG 2025-08-25 11:52:31,884 _default.py:256 - Cloud SDK credentials not found on disk; not using them
         monster-count-fn                2025-08-25 11:52:31.883  DEBUG 2025-08-25 11:52:31,884 _default.py:250 - Checking Cloud SDK credentials as part of auth process...
         monster-count-fn                2025-08-25 11:52:31.883  DEBUG 2025-08-25 11:52:31,883 _default.py:278 - Checking None for explicit credentials as part of auth process...
         monster-count-fn                2025-08-25 11:52:31.797  DEBUG 2025-08-25 11:52:31,797 selector_events.py:54 - Using selector: EpollSelector
I        monster-count-fn                2025-08-25 11:52:28.304  Starting new instance. Reason: DEPLOYMENT_ROLLOUT - Instance started due to traffic shifting between revisions due to deployment, traffic split adjustment, or deployment health check.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.