Create a Cloud Run function that returns Spanner results Stay organized with collections Save and categorize content based on your preferences.
This tutorial shows you how to write an HTTP Cloud Run functionthat returns Spanner results.
Objectives
Write, deploy, and trigger anHTTP function that accessesSpanner.
Costs
This document uses Spanner and Cloud Run,which are billable components of Google Cloud.
For information on the cost of using Spanner, seeSpanner pricing.
For information on the cost of using Cloud Run, including freeinvocations, seeCloud Run pricing.
Before you begin
This document assumes you have a Spanner instance named
Note: After this step, you should have two tables,test-instanceand a database namedexample-dbthat uses the musicapplicationschema.For instructions on creating an instance and database with the music applicationschema, seeQuickstart using the console orthe tutorials for Getting Started inNode.js,orPython.SingersandAlbums,in your database with the sample data specified in the music applicationschema.Enable the Cloud Run and Cloud Build APIs.
Install and initialize the gcloud CLI.
If you already have the gcloud CLI installed, update it by running thefollowing command:
gcloud components updatePrepare your development environment:
Node.js
See theNode.js setup guide.
Python
See thePython setup guide.
Required roles
To get the permissions that you need to deploy Cloud Run services from source, ask your administrator to grant you the following IAM roles:
- Cloud Run Source Developer (
roles/run.sourceDeveloper) on your project - Service Usage Consumer (
roles/serviceusage.serviceUsageConsumer) on the Cloud Run service - Service Account User (
roles/iam.serviceAccountUser) on the service identity - Spanner Admin (
roles/spanner.admin) on the Spanner instance
For a list of IAM roles and permissions that are associated withCloud Run, seeCloud Run IAM rolesandCloud Run IAM permissions.If your Cloud Run service interfaces withGoogle Cloud APIs, such as Cloud Client Libraries, see theservice identity configuration guide.For more information about granting roles, seedeployment permissionsandmanage access.
Roles for the Cloud Build service account
You or your administrator must grant the Cloud Build service account thefollowing IAM role.
Click to view required roles for the Cloud Build service account
Cloud Build automatically uses theCompute Engine default service account as the default Cloud Build service account to build your source code and Cloud Run resource, unless you override this behavior. For Cloud Build to build your sources, ask your administrator to grantCloud Run Builder (roles/run.builder) to the Compute Engine default service account on your project:
gcloudprojectsadd-iam-policy-bindingPROJECT_ID\--member=serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com\--role=roles/run.builder
ReplacePROJECT_NUMBER with your Google Cloud project number, andPROJECT_ID with your Google Cloud project ID. For detailed instructions on how to find your project ID, and project number, seeCreating and managing projects.
Granting the Cloud Run builder role to the Compute Engine default service account takes a couple of minutes topropagate.
Note: Theiam.automaticIamGrantsForDefaultServiceAccounts organization policy constraint prevents the Editor role from being automatically granted to default service accounts. If you created your organization after May 3, 2024, this constraint is enforced by default.
We strongly recommend that you enforce this constraint to disable the automatic role grant. If you disable the automatic role grant, you must decide which roles to grant to the default service accounts, and thengrant these roles yourself.
If the default service account already has the Editor role, we recommend that you replace the Editor role with less permissive roles.To safely modify the service account's roles, usePolicy Simulator to see the impact of the change, and thengrant and revoke the appropriate roles.
Roles for the service identity
You must grant the service identity that you use for the Cloud Run service thefollowing IAM role.
- Spanner Database Reader (
roles/spanner.databaseReader)
For more information on granting roles, seeManage access to projects, folders, and organizations.
Prepare the application
Clone the sample app repository to your local machine:
Node.js
gitclonehttps://github.com/GoogleCloudPlatform/nodejs-docs-samples.gitAlternatively, you candownload the sampleas a zip file and extract it.
Python
gitclonehttps://github.com/GoogleCloudPlatform/python-docs-samples.gitAlternatively, you candownload the sampleas a zip file and extract it.
Change to the directory that contains the Cloud Run functionssample code for accessing Spanner:
Node.js
cdnodejs-docs-samples/functions/spannerPython
cdpython-docs-samples/functions/spannerTake a look at the sample code:
Node.js
// Imports the Google Cloud client libraryconst{Spanner}=require('@google-cloud/spanner');// Imports the functions framework to register your HTTP functionconstfunctions=require('@google-cloud/functions-framework');// Instantiates a clientconstspanner=newSpanner();// Your Cloud Spanner instance IDconstinstanceId='test-instance';// Your Cloud Spanner database IDconstdatabaseId='example-db';/** * HTTP Cloud Function. * * @param {Object} req Cloud Function request context. * @param {Object} res Cloud Function response context. */functions.http('spannerQuickstart',async(req,res)=>{// Gets a reference to a Cloud Spanner instance and databaseconstinstance=spanner.instance(instanceId);constdatabase=instance.database(databaseId);// The query to executeconstquery={sql:'SELECT * FROM Albums',};// Execute the querytry{constresults=awaitdatabase.run(query);constrows=results[0].map(row=>row.toJSON());rows.forEach(row=>{res.write(`SingerId:${row.SingerId}, `+`AlbumId:${row.AlbumId}, `+`AlbumTitle:${row.AlbumTitle}\n`);});res.status(200).end();}catch(err){res.status(500).send(`Error querying Spanner:${err}`);}});Python
importfunctions_frameworkfromgoogle.cloudimportspannerinstance_id="test-instance"database_id="example-db"client=spanner.Client()instance=client.instance(instance_id)database=instance.database(database_id)@functions_framework.httpdefspanner_read_data(request):query="SELECT * FROM Albums"outputs=[]withdatabase.snapshot()assnapshot:results=snapshot.execute_sql(query)forrowinresults:output="SingerId:{}, AlbumId:{}, AlbumTitle:{}".format(*row)outputs.append(output)return"\n".join(outputs)The function sends a SQL query to fetch all
Albumsdata from yourdatabase. The function is executed when you make an HTTP requestto the function's endpoint.
Deploy the function
To deploy the function with an HTTP trigger, run the followingcommand in thespanner directory:
Node.js
gcloudrundeploynodejs-spanner-function\--source.\--regionREGION\--functionspannerQuickstart\--base-imageRUNTIME_ID\--log-httpPython
gcloudrundeploypython-spanner-function\--source.\--regionREGION\--functionspanner_read_data\--base-imageRUNTIME_ID\--log-httpReplace:
REGION with the name of theGoogle Cloud region where you want to deploy your function(for example,
us-west1).RUNTIME_ID with the appropriate runtime ID (forexample,
nodejs22). SeeSupported language runtimes and base images.
Function deployment might take up to two minutes.
Note theurl value returned when your function finishes deploying. You willuse it when you trigger the function.
You can view your deployed functions on theCloud Run page in theGoogle Cloud console. You can also create and edit functions on that page, and getdetails and diagnostics for your functions.
Trigger the function
Make an HTTP request to your function:
curlURLReplaceURL with the URL value returned when your functionfinishes deploying.
You should see output that shows the results of theSQL query, assuming you worked through aGetting Started tutorialand populated the database:
SingerId:2,AlbumId:2,AlbumTitle:ForeverHoldYourPeaceSingerId:1,AlbumId:2,AlbumTitle:Go,Go,GoSingerId:2,AlbumId:1,AlbumTitle:GreenSingerId:2,AlbumId:3,AlbumTitle:TerrifiedSingerId:1,AlbumId:1,AlbumTitle:TotalJunkYou can also visit the function's URL in your browser to see the result ofyour SQL query.
Success: You created an HTTP Cloud Run functionthat returns Spanner results.Clean up
To avoid incurring additional charges to your Google Cloud account for theSpanner and Cloud Run functions resources used inthis document:
Delete the instance:
gcloud CLI instances delete test-instanceDelete the Cloud Run service you deployed in this tutorial:
Node.js
gcloudrunservicesdeletenodejs-spanner-functionPython
gcloudrunservicesdeletepython-spanner-function
What's next
- Learn more about writing Cloud Run functions.
- Learn more about deploying Cloud Run functions.
- Learn more about triggering Cloud Run functions.
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.