GOOGLE CLOUD FUNCTIONS → STACKIT · GUIDE

Google Cloud Functions to STACKIT

STACKIT has no generally available function-as-a-service, so a function becomes an app: a Cloud Foundry app or a container on SKE. Its code and runtime move; the trigger does not, because an event from Pub/Sub or Cloud Storage has to be rewritten as a consumer of the migrated messaging or storage service. StackToIT classes a function as CONTAINERIZE and writes the platform around it.

The migration, step by step

The steps follow the units of the example run, in the order of its waves.

  1. List functions by generation and trigger

    Google documents two generations of Cloud Functions; the second generation is described in the Cloud Run documentation. For each function note its trigger (HTTP, Pub/Sub, storage event, schedule), runtime, memory, timeout, instance limits, ingress setting, service account and secrets.

  2. Choose the target platform

    A Cloud Foundry app suits code you want to push with a buildpack; a container on SKE suits a function that already ships as an image or that needs to sit beside other workloads. The run proposes Cloud Foundry for the function and SKE for the schedule; consolidating on one platform is your call.

  3. Move the foundations first

    Service account, source bucket and topic are in wave 1 of the run; the secret follows in wave 2. The service account becomes a STACKIT service account, the bucket a STACKIT Object Storage bucket, the secret a key in Secrets Manager.

  4. Rewrite the trigger

    The topic becomes a RabbitMQ exchange and its subscription a queue. The function code switches from the Pub/Sub event to an AMQP consumer, with acknowledgement and retry behaviour set deliberately.

  5. Push the app

    Write the manifest from the not-carried list of the run. For the example that means the app name send-receipt, 256 MB of memory, at most 5 instances, the variable MAIL_FROM and the secret MAIL_API_KEY; the 60-second timeout of the function needs its own decision. Push the app into a space of the drafted organization.

  6. Recreate the schedule

    Write the CronJob, or a Cloud Foundry task, that calls the new endpoint on the old schedule. The endpoint address changes, so the schedule target changes with it.

  7. Test, cut over, keep the old function

    Publish test messages, compare the output with the function still running, switch the publishers, and remove the old function after acceptance. This is practice, not a step the run performs.

A Pub/Sub-triggered function, converted

An estate written for this page and assessed by StackToIT on 4 November 2026: a second-generation function triggered by a Pub/Sub topic, its service account, a secret, a source bucket and a nightly Cloud Scheduler job. Left: the function of the input. Right: the block the run drafted for it; the review comments above the block are left out here.

Example inputmain.tf
resource "google_cloudfunctions2_function" "receipt" {
  name     = "send-receipt"
  location = "europe-west3"

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

  service_config {
    available_memory      = "256M"
    timeout_seconds       = 60
    max_instance_count    = 5
    service_account_email = google_service_account.fn.email
    ingress_settings      = "ALLOW_INTERNAL_ONLY"

    environment_variables = {
      MAIL_FROM = "orders@example.com"
    }

    secret_environment_variables {
      key        = "MAIL_API_KEY"
      project_id = "shop-events-prod"
      secret     = google_secret_manager_secret.mail_key.secret_id
      version    = "latest"
    }
  }

  event_trigger {
    trigger_region = "europe-west3"
    event_type     = "google.cloud.pubsub.topic.v1.messagePublished"
    pubsub_topic   = google_pubsub_topic.orders_paid.id
    retry_policy   = "RETRY_POLICY_RETRY"
  }
}
STACKIT Terraform by StackToITterraform/apps.tf
resource "stackit_scf_organization" "migrated_apps" {
  project_id = var.project_id
  name       = "migrated-apps"
}
  • An organisation, not an app

    The draft creates the Cloud Foundry organization that hosts the migrated apps. The app itself is pushed into a space with a manifest, which the run does not generate.

  • What is written in comments

    Name, source location, memory, instances, environment, secrets and network settings are listed as not carried, so you can copy them into the manifest.

  • Internal-only ingress is named

    A Cloud Foundry app is reached on its route. The run says that internal-only ingress is not carried and that you must restrict who can reach the app.

The trigger and the schedule

The function does not run alone. Its topic and its scheduler job become a message broker and a cron job, and the run drafts the platforms they need. Each input block is paired with the block the run wrote for it; the review comments are left out here.

Example input: topicmain.tf
resource "google_pubsub_topic" "orders_paid" {
  name = "orders-paid"
}
STACKIT Terraform by StackToITterraform/messaging.tf
resource "stackit_rabbitmq_instance" "messaging" {
  project_id = var.project_id
  name       = "messaging"
  plan_name  = var.rabbitmq_plan_name
  version    = var.rabbitmq_version
  parameters = {
    sgw_acl = join(",", var.rabbitmq_allowed_cidrs)
  }
}
Example input: scheduler jobmain.tf
resource "google_cloud_scheduler_job" "nightly" {
  name      = "nightly-digest"
  region    = "europe-west3"
  schedule  = "0 3 * * *"
  time_zone = "Europe/Berlin"

  http_target {
    uri         = google_cloudfunctions2_function.receipt.service_config[0].uri
    http_method = "POST"
  }
}
STACKIT Terraform by StackToITterraform/kubernetes.tf
resource "stackit_ske_cluster" "containers" {
  project_id = var.project_id
  name       = "containers"
  node_pools = [{
    name               = "workloads"
    machine_type       = var.containers_machine_type
    minimum            = var.containers_nodes_min
    maximum            = var.containers_nodes_max
    availability_zones = var.availability_zones
  }]
}
  • Topic to exchange

    The topic becomes an exchange of a shared RabbitMQ instance, created in RabbitMQ by hand; subscriptions become queues.

  • Job to CronJob

    The scheduler job becomes a Kubernetes CronJob on SKE that calls the function’s new endpoint on the same schedule, 0 3 * * * in Europe/Berlin. Its manifest is not generated: name, HTTP method, body, headers, deadline and retry policy are written in by hand.

How the function estate maps

One row per unit of the run: eight resources scanned, six migration units.

Google Cloud resourceSTACKIT target in the runMigration class
Cloud Functions (2nd gen) functionSTACKIT Cloud Foundry appContainerize
Cloud Scheduler jobKubernetes CronJob on SKE, or the Cloud Foundry task schedulerContainerize
Pub/Sub topicExchange of a STACKIT RabbitMQ instanceReplatform
Service accountSTACKIT service accountReconfigure
Secret Manager secretKey in STACKIT Secrets Manager; the value is never copied into the draftReconfigure
Cloud Storage bucket (function source)STACKIT Object Storage bucketReconfigure

Classes as the run decided them. The Secret Manager accessor binding and the source archive object are not units of their own.

Decisions the architect owns

Open items of the run, found in execution/manual/actions.md.

  • Application identity

    Decide how the app gets credentials. Functions that used the metadata server need explicit STACKIT credentials or workload identity; the run lists this for the function and for its service account.

  • Network exposure

    The source function accepts internal traffic only. Decide who may reach the Cloud Foundry route, and review the open settings the run assigns to the network architect.

  • Scale-to-zero and billing

    Per-invocation scaling and billing go away. Size instances for the load, and accept an app that runs when idle.

  • Secret settings

    Recreate the secret as a key in the drafted Secrets Manager instance and decide who may read it; the run leaves secret settings to the security architect.

  • Source bucket data

    The run records the movement of the bucket as a decision with no mechanism chosen. If the bucket only holds a deployment archive, rebuilding from source may be simpler than copying it.

  • Messaging semantics

    The example trigger sets retry_policy = RETRY_POLICY_RETRY. Pub/Sub acknowledgement deadlines, retries and dead-letter topics map to acknowledgements, requeueing and dead-letter exchanges, as the run’s mapping says. Decide them for each queue, and make the consumer safe to run twice on the same message.

Questions developers ask

Does STACKIT have a service like Cloud Functions?

No function-as-a-service is generally available on STACKIT according to the run’s mapping. The function runs as a Cloud Foundry app or as a container on SKE, and per-invocation scaling and billing do not carry over.

What happens to a Pub/Sub trigger?

It is rewritten as a consumer. The topic becomes a RabbitMQ exchange and the function reads a queue bound to it, so the code moves from Pub/Sub events to AMQP messages.

Does StackToIT generate the Cloud Foundry manifest?

No. It drafts the organization and lists what a manifest needs: name, memory, instances, environment, secrets and network settings. You write the manifest and push the app.

Does the run check whether a buildpack exists for our runtime?

No. The example uses python312 with the entry point handle_paid_order, and the run keeps both in its mapping note for the manifest. Whether a buildpack for your language and version is available on STACKIT Cloud Foundry is for your team to confirm; if not, build an image and run it on SKE. STACKIT's Cloud Foundry FAQ says that cf buildpacks lists the current built-in buildpacks and that full support covers only those; a community buildpack can be named by its GitHub URL and version tag, but only as a temporary measure.

Sources

Your next move: STACKIT.

Tell us about your estate. We show you what StackToIT delivers for it: target architecture, Terraform artifacts and a structured migration plan.