Use Pub/Sub with Cloud Run tutorial

This tutorial shows how to write, deploy, and call a Cloud Runservice from aPub/Sub push subscription.

Objectives

  • Write, build, and deploy a service to Cloud Run
  • Call the service by publishing a message to aPub/Sub topic.

Costs

In this document, you use the following billable components of Google Cloud:

To generate a cost estimate based on your projected usage, use thepricing calculator.

New Google Cloud users might be eligible for afree trial.

Before you begin

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.create permission.Learn how to grant roles.
    Note: If you don't plan to keep the resources that you create in this procedure, create a project instead of selecting an existing project. After you finish these steps, you can delete the project, removing all resources associated with the project.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.create permission.Learn how to grant roles.
    Note: If you don't plan to keep the resources that you create in this procedure, create a project instead of selecting an existing project. After you finish these steps, you can delete the project, removing all resources associated with the project.

    Go to project selector

  5. Verify that billing is enabled for your Google Cloud project.

  6. Enable the Artifact Registry, Cloud Build, Pub/Sub andCloud Run APIs.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enable permission.Learn how to grant roles.

    Enable the APIs

  7. Install and initialize the gcloud CLI.
  8. Update components:
    gcloudcomponentsupdate

Required roles

To get the permissions that you need to complete the tutorial, ask your administrator to grant you the following IAM roles on your project:

For more information about granting roles, seeManage access to projects, folders, and organizations.

You might also be able to get the required permissions throughcustom roles or otherpredefined roles.

Note:IAM basic roles might also contain permissions to complete the tutorial. You shouldn't grant basic roles in a production environment, but you can grant them in a development or test environment.

Set up gcloud defaults

To configure gcloud with defaults for your Cloud Run service:

  1. Set your default project:

    gcloudconfigsetprojectPROJECT_ID

    ReplacePROJECT_ID with the name of the project you created forthis tutorial.

  2. Configure gcloud for your chosen region:

    gcloudconfigsetrun/regionREGION

    ReplaceREGION with the supported Cloud Runregionof your choice.

Cloud Run locations

Cloud Run is regional, which means the infrastructure thatruns your Cloud Run services is located in a specific region and ismanaged by Google to be redundantly available acrossall the zones within that region.

Meeting your latency, availability, or durability requirements are primaryfactors for selecting the region where your Cloud Run services are run.You can generally select the region nearest to your users but you should considerthe location of theother Google Cloudproducts that are used by your Cloud Run service.Using Google Cloud products together across multiple locations can affectyour service's latency as well as cost.

Cloud Run is available in the following regions:

Subject toTier 1 pricing

  • asia-east1 (Taiwan)
  • asia-northeast1 (Tokyo)
  • asia-northeast2 (Osaka)
  • asia-south1 (Mumbai, India)
  • asia-southeast3 (Bangkok)
  • europe-north1 (Finland)leaf iconLow CO2
  • europe-north2 (Stockholm)leaf iconLow CO2
  • europe-southwest1 (Madrid)leaf iconLow CO2
  • europe-west1 (Belgium)leaf iconLow CO2
  • europe-west4 (Netherlands)leaf iconLow CO2
  • europe-west8 (Milan)
  • europe-west9 (Paris)leaf iconLow CO2
  • me-west1 (Tel Aviv)
  • northamerica-south1 (Mexico)
  • us-central1 (Iowa)leaf iconLow CO2
  • us-east1 (South Carolina)
  • us-east4 (Northern Virginia)
  • us-east5 (Columbus)
  • us-south1 (Dallas)leaf iconLow CO2
  • us-west1 (Oregon)leaf iconLow CO2

Subject toTier 2 pricing

  • africa-south1 (Johannesburg)
  • asia-east2 (Hong Kong)
  • asia-northeast3 (Seoul, South Korea)
  • asia-southeast1 (Singapore)
  • asia-southeast2 (Jakarta)
  • asia-south2 (Delhi, India)
  • australia-southeast1 (Sydney)
  • australia-southeast2 (Melbourne)
  • europe-central2 (Warsaw, Poland)
  • europe-west10 (Berlin)
  • europe-west12 (Turin)
  • europe-west2 (London, UK)leaf iconLow CO2
  • europe-west3 (Frankfurt, Germany)
  • europe-west6 (Zurich, Switzerland)leaf iconLow CO2
  • me-central1 (Doha)
  • me-central2 (Dammam)
  • northamerica-northeast1 (Montreal)leaf iconLow CO2
  • northamerica-northeast2 (Toronto)leaf iconLow CO2
  • southamerica-east1 (Sao Paulo, Brazil)leaf iconLow CO2
  • southamerica-west1 (Santiago, Chile)leaf iconLow CO2
  • us-west2 (Los Angeles)
  • us-west3 (Salt Lake City)
  • us-west4 (Las Vegas)

If you already created a Cloud Run service, you can view theregion in the Cloud Run dashboard in theGoogle Cloud console.

Create an Artifact Registry standard repository

Create an Artifact Registry standard repository to store your container image:

gcloudartifactsrepositoriescreateREPOSITORY\--repository-format=docker\--location=REGION

Replace:

  • REPOSITORY with a unique name for the repository.
  • REGION with the Google Cloud region to be used for the Artifact Registry repository.

Create a Pub/Sub topic

The sample service is triggered by messages published to a Pub/Subtopic, so you'll need to create a topic in Pub/Sub.

gcloud

To create a new Pub/Sub topic, use the command:

gcloudpubsubtopicscreatemyRunTopic

You can usemyRunTopic or replace with a topic name unique withinyour Google Cloud project.

Terraform

To learn how to apply or remove a Terraform configuration, seeBasic Terraform commands.

To create a Pub/Sub topic, add the following to your existingmain.tf file:

resource"google_pubsub_topic""default"{name="pubsub_topic"}

You can use a topic name unique within your Cloud project.

Retrieve the code sample

To retrieve the code sample for use:

  1. Clone the sample app repository to your local machine:

    Node.js

    gitclonehttps://github.com/GoogleCloudPlatform/nodejs-docs-samples.git

    Alternatively, you can download the sample as a zip file and extract it.

    Python

    gitclonehttps://github.com/GoogleCloudPlatform/python-docs-samples.git

    Alternatively, you can download the sample as a zip file and extract it.

    Go

    gitclonehttps://github.com/GoogleCloudPlatform/golang-samples.git

    Alternatively, you can download the sample as a zip file and extract it.

    Java

    gitclonehttps://github.com/GoogleCloudPlatform/java-docs-samples.git

    Alternatively, you can download the sample as a zip file and extract it.

    C#

    gitclonehttps://github.com/GoogleCloudPlatform/dotnet-docs-samples.git

    Alternatively, you can download the sample as a zip file and extract it.

  2. Change to the directory that contains the Cloud Run samplecode:

    Node.js

    cdnodejs-docs-samples/run/pubsub/

    Python

    cdpython-docs-samples/run/pubsub/

    Go

    cdgolang-samples/run/pubsub/

    Java

    cdjava-docs-samples/run/pubsub/

    C#

    cddotnet-docs-samples/run/Run.Samples.Pubsub.MinimalApi/

Review the code

The code for this tutorial consists of the following:

  • A server that handles incoming requests.

    Node.js

    To keep the Node.js service easy to test, the server configuration is separatefrom the server startup.

    The Node.js web server is set up inapp.js.

    constexpress=require('express');constapp=express();// This middleware is available in Express v4.16.0 onwardsapp.use(express.json());

    The web server is started inindex.js:

    constapp=require('./app.js');constPORT=parseInt(parseInt(process.env.PORT))||8080;app.listen(PORT,()=>console.log(`nodejs-pubsub-tutorial listening on port${PORT}`));

    Python

    importbase64fromflaskimportFlask,requestapp=Flask(__name__)

    Go

    // Sample run-pubsub is a Cloud Run service which handles Pub/Sub messages.packagemainimport("encoding/json""io""log""net/http""os")funcmain(){http.HandleFunc("/",HelloPubSub)// Determine port for HTTP service.port:=os.Getenv("PORT")ifport==""{port="8080"log.Printf("Defaulting to port %s",port)}// Start HTTP server.log.Printf("Listening on port %s",port)iferr:=http.ListenAndServe(":"+port,nil);err!=nil{log.Fatal(err)}}

    Java

    importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublicclassPubSubApplication{publicstaticvoidmain(String[]args){SpringApplication.run(PubSubApplication.class,args);}}

    C#

    varbuilder=WebApplication.CreateBuilder(args);varapp=builder.Build();varport=Environment.GetEnvironmentVariable("PORT");if(port!=null){app.Urls.Add($"http://0.0.0.0:{port}");}

  • A handler that processes the Pub/Sub message and logs a greeting.

    Node.js

    app.post('/',(req,res)=>{if(!req.body){constmsg='no Pub/Sub message received';console.error(`error:${msg}`);res.status(400).send(`Bad Request:${msg}`);return;}if(!req.body.message){constmsg='invalid Pub/Sub message format';console.error(`error:${msg}`);res.status(400).send(`Bad Request:${msg}`);return;}constpubSubMessage=req.body.message;constname=pubSubMessage.data?Buffer.from(pubSubMessage.data,'base64').toString().trim():'World';console.log(`Hello${name}!`);res.status(204).send();});

    Python

    @app.route("/",methods=["POST"])defindex():"""Receive and parse Pub/Sub messages."""envelope=request.get_json()ifnotenvelope:msg="no Pub/Sub message received"print(f"error:{msg}")returnf"Bad Request:{msg}",400ifnotisinstance(envelope,dict)or"message"notinenvelope:msg="invalid Pub/Sub message format"print(f"error:{msg}")returnf"Bad Request:{msg}",400pubsub_message=envelope["message"]name="World"ifisinstance(pubsub_message,dict)and"data"inpubsub_message:name=base64.b64decode(pubsub_message["data"]).decode("utf-8").strip()print(f"Hello{name}!")return("",204)

    Go

    // WrappedMessage is the payload of a Pub/Sub event.//// For more information about receiving messages from a Pub/Sub event// see: https://cloud.google.com/pubsub/docs/push#receive_pushtypeWrappedMessagestruct{Messagestruct{Data[]byte`json:"data,omitempty"`IDstring`json:"id"`}`json:"message"`Subscriptionstring`json:"subscription"`}// HelloPubSub receives and processes a Pub/Sub push message.funcHelloPubSub(whttp.ResponseWriter,r*http.Request){varmWrappedMessagebody,err:=io.ReadAll(r.Body)deferr.Body.Close()iferr!=nil{log.Printf("io.ReadAll: %v",err)http.Error(w,"Bad Request",http.StatusBadRequest)return}// byte slice unmarshalling handles base64 decoding.iferr:=json.Unmarshal(body,&m);err!=nil{log.Printf("json.Unmarshal: %v",err)http.Error(w,"Bad Request",http.StatusBadRequest)return}name:=string(m.Message.Data)ifname==""{name="World"}log.Printf("Hello %s!",name)}

    Java

    importcom.example.cloudrun.Body;importjava.util.Base64;importorg.apache.commons.lang3.StringUtils;importorg.springframework.http.HttpStatus;importorg.springframework.http.ResponseEntity;importorg.springframework.web.bind.annotation.RequestBody;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RequestMethod;importorg.springframework.web.bind.annotation.RestController;// PubsubController consumes a Pub/Sub message.@RestControllerpublicclassPubSubController{@RequestMapping(value="/",method=RequestMethod.POST)publicResponseEntity<String>receiveMessage(@RequestBodyBodybody){// Get PubSub message from request body.Body.Messagemessage=body.getMessage();if(message==null){Stringmsg="Bad Request: invalid Pub/Sub message format";System.out.println(msg);returnnewResponseEntity<>(msg,HttpStatus.BAD_REQUEST);}Stringdata=message.getData();Stringtarget=!StringUtils.isEmpty(data)?newString(Base64.getDecoder().decode(data)):"World";Stringmsg="Hello "+target+"!";System.out.println(msg);returnnewResponseEntity<>(msg,HttpStatus.OK);}}

    C#

    app.MapPost("/",(Envelopeenvelope)=>{if(envelope?.Message?.Data==null){app.Logger.LogWarning("Bad Request: Invalid Pub/Sub message format.");returnResults.BadRequest();}vardata=Convert.FromBase64String(envelope.Message.Data);vartarget=System.Text.Encoding.UTF8.GetString(data);app.Logger.LogInformation($"Hello {target}!");returnResults.NoContent();});

    You must code the service to return an accurate HTTP response code. Successcodes, such as HTTP200 or204, acknowledge complete processing of thePub/Sub message. Error codes, such as HTTP400 or500, indicatethe message will be retried, as described inReceiving messages using Push guide. Unlike functionscreated with theCloud Functions v2 API, you cannot disable retriesfor functions created with theCloud Run Admin API.To learn more, seeConfigure event-driven function retries.

  • ADockerfile that defines the operating environment for the service. Thecontents of theDockerfile vary by language.

    Node.js

    #UsetheofficiallightweightNode.jsimage.#https://hub.docker.com/_/nodeFROMnode:20-slim#Createandchangetotheappdirectory.WORKDIR/usr/src/app#Copyapplicationdependencymanifeststothecontainerimage.#Awildcardisusedtoensurebothpackage.jsonANDpackage-lock.jsonarecopied.#Copyingthisseparatelypreventsre-runningnpminstalloneverycodechange.COPYpackage*.json./#Installdependencies.#ifyouneedadeterministicandrepeatablebuildcreatea#package-lock.jsonfileandusenpmci:#RUNnpmci--omit=dev#ifyouneedtoincludedevelopmentdependenciesduringdevelopment#ofyourapplication,use:#RUNnpminstall--devRUNnpminstall--omit=dev#Copylocalcodetothecontainerimage.COPY..#Runthewebserviceoncontainerstartup.CMD["npm","start"]

    Python

    # Use the official Python image.# https://hub.docker.com/_/pythonFROMpython:3.11# Allow statements and log messages to immediately appear in the Cloud Run logsENVPYTHONUNBUFFEREDTrue# Copy application dependency manifests to the container image.# Copying this separately prevents re-running pip install on every code change.COPYrequirements.txt./# Install production dependencies.RUNpipinstall-rrequirements.txt# Copy local code to the container image.ENVAPP_HOME/appWORKDIR$APP_HOMECOPY../# Run the web service on container startup.# Use gunicorn webserver with one worker process and 8 threads.# For environments with multiple CPU cores, increase the number of workers# to be equal to the cores available.# Timeout is set to 0 to disable the timeouts of the workers to allow Cloud Run to handle instance scaling.CMDexecgunicorn--bind:$PORT--workers1--threads8--timeout0main:app

    Go

    #UsetheofficialGoimagetocreateabinary.#ThisisbasedonDebianandsetstheGOPATHto/go.#https://hub.docker.com/_/golangFROMgolang:1.24-bookwormasbuilder#Createandchangetotheappdirectory.WORKDIR/app#Retrieveapplicationdependencies.#Thisallowsthecontainerbuildtoreusecacheddependencies.#Expectingtocopygo.modandifpresentgo.sum.COPYgo.*./RUNgomoddownload#Copylocalcodetothecontainerimage.COPY../#Buildthebinary.RUNgobuild-v-oserver#UsetheofficialDebianslimimageforaleanproductioncontainer.#https://hub.docker.com/_/debian#https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-buildsFROMdebian:bookworm-slimRUNset-x &&apt-getupdate &&DEBIAN_FRONTEND=noninteractiveapt-getinstall-y\ca-certificates &&\rm-rf/var/lib/apt/lists/*#Copythebinarytotheproductionimagefromthebuilderstage.COPY--from=builder/app/server/server#Runthewebserviceoncontainerstartup.CMD["/server"]

    Java

    This sample usesJib to buildDocker images using common Java tools. Jib optimizes container builds withoutthe need for a Dockerfile or havingDockerinstalled. Learn more aboutbuilding Java containers with Jib.

    <plugin><groupId>com.google.cloud.tools</groupId><artifactId>jib-maven-plugin</artifactId><version>3.4.0</version><configuration><to><image>gcr.io/PROJECT_ID/pubsub</image></to></configuration></plugin>

    C#

    #BuildinSDKbaseimageFROMmcr.microsoft.com/dotnet/sdk:6.0ASbuild-envWORKDIR/appCOPY*.csproj./RUNdotnetrestoreCOPY../RUNdotnetpublish-rlinux-x64--no-self-contained-p:PublishReadyToRun=true-cRelease-oout#CopytoruntimeimageFROMmcr.microsoft.com/dotnet/aspnet:6.0WORKDIR/appCOPY--from=build-env/app/out.#PortpassedinbyCloudRunviaenvironmentvariablePORT.Default8080.ENVPORT=8080ENTRYPOINT["dotnet","Run.Samples.Pubsub.MinimalApi.dll"]

For details on how to authenticate the origin of Pub/Sub requests, seeIntegrate with Pub/Sub.

Ship the code

Shipping code consists of three steps: building a container image withCloud Build, uploading the container image to Artifact Registry, anddeploying the container image to Cloud Run.

To ship your code:

  1. Build your container and publish on Artifact Registry:

    Node.js

    gcloudbuildssubmit--tagREGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/pubsub
    Replace:
    • PROJECT_ID with your Google Cloud project ID.
    • REPOSITORY with the name of the Artifact Registry repository.
    • REGION with the Google Cloud region to be used for the Artifact Registry repository.

    pubsub is the image name.

    Upon success, you should see a SUCCESS message containing the ID, creation time, and image name. The image is stored in Artifact Registry and can be re-used if required.

    Python

    gcloudbuildssubmit--tagREGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/pubsub
    Replace:
    • PROJECT_ID with your Google Cloud project ID.
    • REPOSITORY with the name of the Artifact Registry repository.
    • REGION with the Google Cloud region to be used for the Artifact Registry repository.

    pubsub is the image name.

    Upon success, you should see a SUCCESS message containing the ID, creation time, and image name. The image is stored in Artifact Registry and can be re-used if required.

    Go

    gcloudbuildssubmit--tagREGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/pubsub
    Replace:
    • PROJECT_ID with your Google Cloud project ID.
    • REPOSITORY with the name of the Artifact Registry repository.
    • REGION with the Google Cloud region to be used for the Artifact Registry repository.

    pubsub is the image name.

    Upon success, you should see a SUCCESS message containing the ID, creation time, and image name. The image is stored in Artifact Registry and can be re-used if required.

    Java

    • Use thegcloud CLI credential helper to authorize Docker to push to your Artifact Registry.
      gcloudauthconfigure-docker
    • Use the Jib Maven Plugin to build and push the container to Artifact Registry.
      mvncompilejib:build-Dimage=REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/pubsub
      Replace:
      • PROJECT_ID with your Google Cloud project ID.
      • REPOSITORY with the name of the Artifact Registry repository.
      • REGION with the Google Cloud region to be used for the Artifact Registry repository.

      pubsub is the image name.

      Upon success, you should see a BUILD SUCCESS message. The image is stored in Artifact Registry and can be re-used if required.

    C#

    gcloudbuildssubmit--tagREGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/pubsub
    Replace:
    • PROJECT_ID with your Google Cloud project ID.
    • REPOSITORY with the name of the Artifact Registry repository.
    • REGION with the Google Cloud region to be used for the Artifact Registry repository.

    pubsub is the image name.

    Upon success, you should see a SUCCESS message containing the ID, creation time, and image name. The image is stored in Artifact Registry and can be re-used if required.

  2. Deploy your application:

    Command line

    1. Run the following command to deploy your app:

      gcloudrundeploypubsub-tutorial--imageREGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/pubsub--no-allow-unauthenticated
      Replace:
      • PROJECT_ID with your Google Cloud project ID.
      • REPOSITORY with the name of the Artifact Registry repository.
      • REGION with the Google Cloud region to be used for the Artifact Registry repository.

      pubsub is the image name andpubsub-tutorial is the name of the service. Notice that the container image is deployed to the service and region that you configured previously underSetting up gcloud

      The--no-allow-unauthenticated flag restricts unauthenticated access to the service. By keeping the service private you can rely on Cloud Run's automatic Pub/Sub integration to authenticate requests. SeeIntegrate with Pub/Sub for more details on how this is configured. For more details about authentication that is based on Identity and Access Management (IAM), seeManaging access using IAM.

      Wait until the deployment is complete: this can take about half a minute. On success, the command line displays the service URL. This URL is used to configure a Pub/Sub subscription.

    2. If you want to deploy a code update to the service, repeat the previous steps. Each deployment to a service creates a new revision and automatically starts serving traffic when ready.

    Terraform

    To create a Cloud Run service, add the following to your existing.tf file.

    resource"google_project_service""cloudrun_api"{service="run.googleapis.com"disable_on_destroy=false}resource"google_cloud_run_v2_service""default"{name="pubsub-tutorial"location="REGION"template{containers{image="IMAGE_URL"}}depends_on=[google_project_service.cloudrun_api]}
    Replace:
    • IMAGE_URL with your image URL:REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/pubsub
    • REGION with the Google Cloud region to be used for the Artifact Registry repository.

Integrate with Pub/Sub

Important: If your project was created on or before April 8, 2021, you must granttheiam.serviceAccountTokenCreatorrole to theservice agentservice-{PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com on the projectin order to allow Pub/Sub to create tokens. However, ifyour project was created after that date, you do not need to grant it this rolebecause it has theroles/pubsub.serviceAgentrole with identical permissions.

To integrate the service with Pub/Sub:

gcloud

  1. Create or select a service account to represent the Pub/Subsubscription identity.

    gcloudiamservice-accountscreatecloud-run-pubsub-invoker\--display-name"Cloud Run Pub/Sub Invoker"

    You can usecloud-run-pubsub-invoker or replace with a name unique withinyour Google Cloud project.

  2. Create a Pub/Sub subscription with the service account:

    1. Give the invoker service account permission to invoke yourpubsub-tutorial service:

      gcloudrunservicesadd-iam-policy-bindingpubsub-tutorial\--member=serviceAccount:cloud-run-pubsub-invoker@PROJECT_ID.iam.gserviceaccount.com\--role=roles/run.invoker

      It can take several minutes for the IAM changes topropagate. In the meantime, you might seeHTTP 403 errors in theservice logs.

    2. Allow Pub/Sub to create authentication tokens in your project:

      gcloudprojectsadd-iam-policy-bindingPROJECT_ID\--member=serviceAccount:service-PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com\--role=roles/iam.serviceAccountTokenCreator

      Replace:

      • PROJECT_ID with your Google Cloud project ID.
      • PROJECT_NUMBER with your Google Cloud project number.

      Project ID and project number are listed in theProject info panel intheGoogle Cloud console for your project.

    3. Create a Pub/Sub subscription with the service account:

      gcloudpubsubsubscriptionscreatemyRunSubscription--topicmyRunTopic\--ack-deadline=600\--push-endpoint=SERVICE-URL/\--push-auth-service-account=cloud-run-pubsub-invoker@PROJECT_ID.iam.gserviceaccount.com

      Replace:

      • myRunTopic with the topic youpreviously created.
      • SERVICE-URL with the HTTPS URL provided on deploying theservice. This URL works even if you have alsoadded a domain mapping.
      • PROJECT_ID with your Google Cloud project ID.

      The--push-auth-service-account flag activates the Pub/Sub pushfunctionality forAuthentication and authorization.

      Your Cloud Run service domain is automatically registered for usewith Pub/Sub subscriptions.

      For Cloud Run only, there is a built-in authentication checkthat the token is valid and an authorization check that the serviceaccount has permission to invoke the Cloud Run service.

Your service is now fully integrated with Pub/Sub.

Terraform

  1. Create or select a service account to represent the Pub/Subsubscription identity.

    resource"google_service_account""sa"{account_id="cloud-run-pubsub-invoker"display_name="Cloud Run Pub/Sub Invoker"}
  2. Create a Pub/Sub subscription with the service account:

    1. Give the invoker service account permission to invoke yourpubsub-tutorial service:

      resource"google_cloud_run_service_iam_binding""binding"{location=google_cloud_run_v2_service.default.locationservice=google_cloud_run_v2_service.default.namerole="roles/run.invoker"members=["serviceAccount:${google_service_account.sa.email}"]}
    2. Allow Pub/Sub to create authentication tokens in your project:

      resource"google_project_service_identity""pubsub_agent"{provider=google-betaproject=data.google_project.project.project_idservice="pubsub.googleapis.com"}resource"google_project_iam_binding""project_token_creator"{project=data.google_project.project.project_idrole="roles/iam.serviceAccountTokenCreator"members=["serviceAccount:${google_project_service_identity.pubsub_agent.email}"]}
    3. Create a Pub/Sub subscription with the service account:

      resource"google_pubsub_subscription""subscription"{name="pubsub_subscription"topic=google_pubsub_topic.default.namepush_config{push_endpoint=google_cloud_run_v2_service.default.urioidc_token{service_account_email=google_service_account.sa.email}attributes={x-goog-version="v1"}}depends_on=[google_cloud_run_v2_service.default]}

Your service is now fully integrated with Pub/Sub.

Try it out

To test the end-to-end solution:

  1. Send a Pub/Sub message to the topic:

    gcloudpubsubtopicspublishmyRunTopic--message"Runner"

    You can also publish messages programmatically instead of using thecommand-line as shown in this tutorial. For more information, seePublishing messages.

  2. Navigate to the service logs:

    1. Navigate to theGoogle Cloud console
    2. Click thepubsub-tutorial service.
    3. Select theLogs tab.

      Logs might take a few moments to appear. If you don't see themimmediately, check again after a few moments.

  3. Look for the "Hello Runner!" message.

Success: You deployed a Cloud Run service that automatically responds to Pub/Sub messages.

Clean up

To walk through a more in-depth use case of usingCloud Run with Pub/Sub, skip cleanup for now and continue withtheImage Processing with Cloud Run tutorial.

To avoid additional charges to your Google Cloud account, delete all the resourcesyou deployed with this tutorial.

Delete the project

If you created a new project for this tutorial, delete the project.If you used an existing project and need to keep it without the changes you addedin this tutorial,delete resources that you created for the tutorial.

The easiest way to eliminate billing is to delete the project that you created for the tutorial.

To delete the project:

    Caution: Deleting a project has the following effects:
    • Everything in the project is deleted. If you used an existing project for the tasks in this document, when you delete it, you also delete any other work you've done in the project.
    • Custom project IDs are lost. When you created this project, you might have created a custom project ID that you want to use in the future. To preserve the URLs that use the project ID, such as anappspot.com URL, delete selected resources inside the project instead of deleting the whole project.

    If you plan to explore multiple architectures, tutorials, or quickstarts, reusing projects can help you avoid exceeding project quota limits.

  1. In the Google Cloud console, go to theManage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then clickDelete.
  3. In the dialog, type the project ID, and then clickShut down to delete the project.

Delete tutorial resources

  1. Delete the Cloud Run service you deployed in this tutorial.Cloud Run services don't incur costs until they receive requests.

    To delete your Cloud Run service, run the following command:

    gcloudrunservicesdeleteSERVICE-NAME

    ReplaceSERVICE-NAME with the name of your service.

    You can also delete Cloud Run services from theGoogle Cloud console.

  2. Remove thegcloud default region configuration you added during tutorialsetup:

    gcloudconfigunsetrun/region
  3. Remove the project configuration:

     gcloud config unset project
  4. Delete other Google Cloud resources created in this tutorial:

What's next

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2026-02-18 UTC.