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.