Google Cloud Functions is an event-driven serverless compute platform. Cloud Functions allows you to write your code without worrying about provisioning resources or scaling to handle changing requirements.

There are two types of Cloud Functions:

This codelab will walk you through creating your own Cloud Functions in C#. More specifically, you will deploy C# functions responding to HTTP and CloudEvents from various Google Cloud sources.

What you'll learn

Codelab-at-a-conference setup

If you see a "request account button" at the top of the main Codelabs window, click it to obtain a temporary account. Otherwise ask one of the staff for a coupon with username/password.

These temporary accounts have existing projects that are set up with billing so that there are no costs associated for you with running this codelab.

Note that all these accounts will be disabled soon after the codelab is over.

Use these credentials to log into the machine or to open a new Google Cloud Console window https://console.cloud.google.com/. Accept the new account Terms of Service and any updates to Terms of Service.

Here's what you should see once logged in:

When presented with this console landing page, please select the only project available. Alternatively, from the console home page, click on "Select a Project" :

Start Cloud Shell

While Google Cloud can be operated remotely from your laptop, in this codelab you will be using Google Cloud Shell, a command line environment running in the Cloud.

From the GCP Console click the Cloud Shell icon on the top right toolbar:

It should only take a few moments to provision and connect to the environment. When it is finished, you should see something like this:

This virtual machine is loaded with all the development tools you'll need. It offers a persistent 5GB home directory, and runs on Google Cloud, greatly enhancing network performance and authentication. All of your work in this lab can be done with simply a browser.

Functions Framework for .NET is an open source FaaS (Function as a Service) framework for writing portable .NET functions -- brought to you by the Google Cloud Functions team.

The Functions Framework lets you write lightweight functions that run in many different environments, including:

In this codelab, you will use Functions Framework for .NET and its templates to create and deploy Cloud Functions in C#.

Inside Cloud Shell, run the following command to install Cloud Functions templates for dotnet:

dotnet new -i Google.Cloud.Functions.Templates::1.0.0-alpha08

This installs 3 templates for dotnet. Each template is available in C#, F# and VB (but you'll only use C# in this lab). You can verify that templates are installed by running:

dotnet new gcf

Templates                                                 Short Name            
-----------------------------------------------------------------------
Google Cloud Functions CloudEvent Function                gcf-event
Google Cloud Functions CloudEvent Function (Untyped)      gcf-untyped-event
Google Cloud Functions HttpFunction                       gcf-http

You will create and deploy an HTTP Function responding to HTTP requests.

Create an HTTP Function using the gcf-http template:

mkdir HelloHttpFunction
cd HelloHttpFunction
dotnet new gcf-http

This creates a project and a Function.cs file responding to HTTP requests:

using Google.Cloud.Functions.Framework;
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;
namespace HelloHttpFunction
{
    public class Function : IHttpFunction
    {
        public async Task HandleAsync(HttpContext context)
        {
            await context.Response.WriteAsync("Hello, Functions Framework.");
        }
    }
}

Deploy the function,using dotnet3 runtime and trigger-http flag:

gcloud functions deploy hello-http-function \
    --runtime dotnet3 \
    --trigger-http \
    --entry-point HelloHttpFunction.Function \
    --allow-unauthenticated

After a minute or two, you should see the Cloud Function deployed in Cloud Console:

You can trigger the function by sending an HTTP request with gcloud functions call:

gcloud functions call hello-http-function

executionId: tp5h7d6t2vpl
result: Hello, Functions Framework.

You will create and deploy an CloudEvent Function responding to Cloud Storage events.

First, create a Cloud Storage bucket. This is the bucket you will listen events from later:

export BUCKET_NAME="cloud-functions-bucket-$(gcloud config get-value core/project)"
gsutil mb gs://${BUCKET_NAME}

Create an CloudEvent Function using the gcf-event template:

mkdir HelloCloudEventStorageFunction
cd HelloCloudEventStorageFunction
dotnet new gcf-event

This creates a project and a Function.cs file responding to CloudEvent requests. It also parses the data of CloudEvent into StorageObjectData:

using CloudNative.CloudEvents;
using Google.Cloud.Functions.Framework;
using Google.Events.SystemTextJson.Cloud.Storage.V1;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace HelloCloudEventStorageFunction
{
    public class Function : ICloudEventFunction<StorageObjectData>
    {
        public Task HandleAsync(CloudEvent cloudEvent, StorageObjectData data, CancellationToken cancellationToken)
        {
            ...

Deploy the function, using the dotnet3 runtime and trigger-event, trigger-resource flags:

gcloud functions deploy hello-cloudevent-storage-function \
    --runtime dotnet3 \
    --entry-point HelloCloudEventStorageFunction.Function \
    --trigger-event google.storage.object.finalize \
    --trigger-resource ${BUCKET_NAME} \
    --allow-unauthenticated

After a couple of minutes, the function should be visible in Cloud Console:

Trigger the function by uploading a file to the storage bucket:

echo "Hello from Storage" > random.txt
gsutil cp random.txt gs://${BUCKET_NAME}

Verify that the function was triggered by reading the logs:

gcloud functions logs read hello-cloudevent-storage-function

You will create and deploy an CloudEvent Function responding to Cloud Pub/Sub events.

First, create a Cloud Pub/Sub topic that will emit events:

export TOPIC_NAME=cloud-functions-topic
gcloud pubsub topics create ${TOPIC_NAME}

Create an CloudEvent Function using the gcf-event template:

mkdir HelloCloudEventPubSubFunction
cd HelloCloudEventPubSubFunction
dotnet new gcf-event

This creates a project and a Function.cs file responding to CloudEvent requests. It also parses the data of CloudEvent into StorageObjectData by default. Change StorageObjectData to MessagePublishedData to parse Pub/Sub messages instead and print it out.

In the end, your function should look like this:

using CloudNative.CloudEvents;
using Google.Cloud.Functions.Framework;
using Google.Events.SystemTextJson.Cloud.PubSub.V1;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace HelloCloudEventPubSubFunction
{
    public class Function : ICloudEventFunction<MessagePublishedData>
    {
        public Task HandleAsync(CloudEvent cloudEvent, MessagePublishedData data, CancellationToken cancellationToken)
        {
            Console.WriteLine("Message published data:");
            Console.WriteLine($"  Message: {data.Message}");
            Console.WriteLine($"  Subscription: {data.Subscription}");
            Console.WriteLine($"  Message.MessageId: {data.Message.MessageId}");
            Console.WriteLine($"  Message.TextData: {data.Message.TextData}");
            Console.WriteLine("Cloud event information:");
            Console.WriteLine($"  ID: {cloudEvent.Id}");
            Console.WriteLine($"  Source: {cloudEvent.Source}");
            Console.WriteLine($"  Type: {cloudEvent.Type}");
            Console.WriteLine($"  Subject: {cloudEvent.Subject}");
            Console.WriteLine($"  DataSchema: {cloudEvent.DataSchema}");
            Console.WriteLine($"  DataContentType: {cloudEvent.DataContentType}");
            Console.WriteLine($"  Time: {cloudEvent.Time?.ToUniversalTime():yyyy-MM-dd'T'HH:mm:ss.fff'Z'}");
            Console.WriteLine($"  SpecVersion: {cloudEvent.SpecVersion}");
            
            // In this example, we don't need to perform any asynchronous operations, so the
            // method doesn't need to be declared async.
            return Task.CompletedTask;
        }
    }
}

Deploy the function, using the dotnet3 runtime and trigger-topic flag:

gcloud functions deploy hello-cloudevent-pubsub-function \
    --runtime dotnet3 \
    --entry-point HelloCloudEventPubSubFunction.Function \
    --trigger-topic ${TOPIC_NAME} \
    --allow-unauthenticated

After a couple of minutes, the function should be visible in Cloud Console:

Trigger the function by publishing a message to the topic:

gcloud pubsub topics publish ${TOPIC_NAME} --message="Hello World"

Verify that the function was triggered by reading the logs:

gcloud functions logs read hello-cloudevent-pubsub-function

If you are experimenting with CloudEvents and don't yet have a payload data model you wish to commit to, or you want your function to be able to handle any Cloud Event, you can use an untyped CloudEvent function.

Create an CloudEvent Function using the gcf-untyped-event template:

mkdir HelloCloudEventUntypedFunction
cd HelloCloudEventUntypedFunction
dotnet new gcf-untyped-event

This creates a project and a Function.cs file responding to CloudEvent requests without any attempt to parse the data of the CloudEvent:

using CloudNative.CloudEvents;
using Google.Cloud.Functions.Framework;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace HelloCloudEventUntypedFunction
{
    public class Function : ICloudEventFunction
    {
        public Task HandleAsync(CloudEvent cloudEvent, CancellationToken cancellationToken)

Deploy the function, using the dotnet3 runtime and trigger-event flag:

gcloud functions deploy hello-cloudevent-untyped-function \
    --runtime dotnet3 \
    --entry-point HelloCloudEventUntypedFunction.Function \
    --trigger-event google.storage.object.finalize \
    --trigger-resource ${BUCKET_NAME} \
    --allow-unauthenticated

The function will trigger when a file is uploaded to a storage bucket.

After a couple of minutes, the function should be visible in Cloud Console:

Trigger the function by uploading a file to the storage bucket:

echo "Hello from Storage" > random.txt
gsutil cp random.txt gs://${BUCKET_NAME}

Verify that the function was triggered by reading the logs:

gcloud functions logs read hello-cloudevent-untyped-function

Congratulations for completing the codelab.

What we've covered