Google Cloud Functions en C#

1. Introduction

Les fonctions Google Cloud Run sont une plate-forme de calcul sans serveur basée sur des événements. Les fonctions Cloud Run vous permettent d'écrire votre code sans vous soucier de provisionner des ressources ni d'ajuster la scalabilité pour répondre aux exigences changeantes.

Il existe deux types de fonctions Cloud Run :

  • Les fonctions HTTP répondent aux requêtes HTTP.
  • Les fonctions d'événement sont déclenchées par des événements, comme la publication d'un message dans Cloud Pub/Sub ou l'importation d'un fichier dans Cloud Storage.

efb3268e3b74ed4f.png

Cet atelier de programmation vous explique comment créer vos propres fonctions Cloud Run en C#. Plus précisément, vous allez déployer des fonctions C# répondant aux requêtes HTTP et CloudEvents provenant de différentes sources Google Cloud.

Points abordés

  • Framework des fonctions pour .NET
  • Écrire une fonction HTTP
  • Écrire une fonction déclenchée par événement répondant aux événements Cloud Storage
  • Écrire une fonction déclenchée par événement qui répond aux événements Cloud Pub/Sub
  • Écrire une fonction déclenchée par un événement répondant à n'importe quel type d'événement

2. Préparation

Configuration de l'environnement au rythme de chacun

  1. Connectez-vous à la console Google Cloud, puis créez un projet ou réutilisez un projet existant. (Si vous ne possédez pas encore de compte Gmail ou Google Workspace, vous devez en créer un.)

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Le nom du projet est le nom à afficher pour les participants au projet. Il s'agit d'une chaîne de caractères non utilisée par les API Google. Vous pouvez le mettre à jour à tout moment.
  • L'ID du projet doit être unique sur l'ensemble des projets Google Cloud et doit être immuable (vous ne pouvez pas le modifier une fois que vous l'avez défini). La console Cloud génère automatiquement une chaîne unique (en général, vous n'y accordez d'importance particulière). Dans la plupart des ateliers de programmation, vous devrez indiquer l'ID de votre projet (généralement identifié par PROJECT_ID). Si l'ID généré ne vous convient pas, vous pouvez en générer un autre de manière aléatoire. Vous pouvez également en spécifier un et voir s'il est disponible. Après cette étape, l'ID n'est plus modifiable et restera donc le même pour toute la durée du projet.
  • Pour information, il existe une troisième valeur (le numéro de projet) que certaines API utilisent. Pour en savoir plus sur ces trois valeurs, consultez la documentation.
  1. Vous devez ensuite activer la facturation dans la console Cloud pour utiliser les ressources/API Cloud. L'exécution de cet atelier de programmation est très peu coûteuse, voire sans frais. Pour désactiver les ressources et éviter ainsi que des frais ne vous soient facturés après ce tutoriel, vous pouvez supprimer le projet ou les ressources que vous avez créées. Les nouveaux utilisateurs de Google Cloud peuvent participer au programme d'essai gratuit pour bénéficier d'un crédit de 300 $.

Démarrer Cloud Shell

Bien que Google Cloud puisse être utilisé à distance depuis votre ordinateur portable, nous allons nous servir de Google Cloud Shell pour cet atelier de programmation, un environnement de ligne de commande exécuté dans le cloud.

Dans la console Google Cloud, cliquez sur l'icône Cloud Shell dans la barre d'outils supérieure :

55efc1aaa7a4d3ad.png

Le provisionnement et la connexion à l'environnement prennent quelques instants seulement. Une fois l'opération terminée, le résultat devrait ressembler à ceci :

7ffe5cbb04455448.png

Cette machine virtuelle contient tous les outils de développement nécessaires. Elle comprend un répertoire d'accueil persistant de 5 Go et s'exécute sur Google Cloud, ce qui améliore nettement les performances du réseau et l'authentification. Vous pouvez effectuer toutes les tâches de cet atelier de programmation dans un navigateur. Vous n'avez rien à installer.

3. Avant de commencer

Dans Cloud Shell, exécutez la commande suivante pour activer les services requis:

gcloud services enable \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  cloudfunctions.googleapis.com \
  eventarc.googleapis.com \
  run.googleapis.com

Définissez ensuite votre région.

REGION=<YOUR_REGION>

Pour cet atelier de programmation, vous allez créer un compte de service avec les autorisations Eventarc requises et le rôle de demandeur Cloud Run afin de recevoir un événement à partir de Cloud Storage et d'appeler la fonction Cloud Run.

Commencez par créer le compte de service.

PROJECT_ID=$(gcloud config get-value core/project)
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')

SERVICE_ACCOUNT="cloud-run-functions"
SERVICE_ACCOUNT_ADDRESS=$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com

gcloud iam service-accounts create $SERVICE_ACCOUNT \
  --display-name="Cloud Run functions Eventarc service account"

Ensuite, attribuez le rôle Destinataire des événements Eventarc (roles/eventarc.eventReceiver) sur le projet au compte de service associé à votre déclencheur Eventarc afin qu'il puisse recevoir des événements de fournisseurs d'événements.

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
  --role=roles/eventarc.eventReceiver

Ensuite, attribuez au compte de service le rôle de demandeur Cloud Run afin qu'il puisse appeler la fonction.

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
  --role=roles/run.invoker

4. Framework des fonctions pour .NET

Le framework des fonctions pour .NET est un framework FaaS (Functions as a Service) Open Source permettant d'écrire des fonctions .NET portables. Il est proposé par l'équipe Google Cloud Functions.

Le framework des fonctions vous permet d'écrire des fonctions légères qui s'exécutent dans de nombreux environnements, dont les suivants:

  • Fonctions Google Cloud Run
  • Votre ordinateur de développement local
  • Cloud Run et Cloud Run sur GKE
  • Environnements basés sur Knative

Dans cet atelier de programmation, vous allez utiliser le framework des fonctions pour .NET et ses modèles pour créer et déployer des fonctions Cloud en C#.

Dans Cloud Shell, exécutez la commande suivante pour installer des modèles Cloud Functions pour dotnet:

dotnet new install Google.Cloud.Functions.Templates

Trois modèles sont alors installés pour dotnet. Chaque modèle est disponible en C#, F# et VB (mais vous n'utiliserez que C# dans cet atelier). Vous pouvez vérifier que les modèles sont installés en exécutant la commande suivante:

dotnet new list

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

5. Fonction HTTP

Vous allez créer et déployer une fonction HTTP qui répond aux requêtes HTTP.

Créez une fonction HTTP à l'aide du modèle gcf-http:

mkdir HelloHttp
cd HelloHttp
dotnet new gcf-http

Un projet et un fichier Function.cs sont créés pour répondre aux requêtes HTTP.

Remplacez le framework cible par net8.0 dans le fichier .csproj:

<TargetFramework>net8.0</TargetFramework>

Pour déployer une fonction Cloud Run directement sur Cloud Run, exécutez la commande suivante:

gcloud beta run deploy hello-http-function \
    --source . \
    --function HelloHttp.Function \
    --base-image dotnet8 \
    --region $REGION \
    --allow-unauthenticated

Si vous préférez déployer en tant que Cloud Functions (2e génération), utilisez la commande suivante:

gcloud functions deploy hello-http-function \
    --allow-unauthenticated \
    --entry-point HelloHttp.Function \
    --gen2 \
    --region $REGION \
    --runtime dotnet8 \
    --trigger-http

Une fois votre fonction déployée, vous pouvez l'appeler à l'aide de la commande curl suivante:

SERVICE_URL=$(gcloud run services describe hello-http-function --platform managed --region $REGION --format 'value(status.url)')

curl $SERVICE_URL

6. Fonction CloudEvent – GCS

Vous allez créer et déployer une fonction CloudEvent qui répond aux événements Google Cloud Storage (GCS).

Commencez par créer un bucket Cloud Storage. Il s'agit du bucket à partir duquel vous écouterez les événements plus tard:

BUCKET_NAME="cloud-functions-bucket-${PROJECT_ID}"
gsutil mb -l us-central1 gs://${BUCKET_NAME}

Créez une fonction CloudEvent à l'aide du modèle gcf-event:

cd ..
mkdir HelloGcs
cd HelloGcs
dotnet new gcf-event

Cela crée un projet et un fichier Function.cs répondant aux requêtes CloudEvent. Il analyse également les données de CloudEvent dans StorageObjectData.

Remplacez le framework cible par net8.0 dans le fichier .csproj:

<TargetFramework>net8.0</TargetFramework>

Pour déployer une fonction Cloud Run directement sur Cloud Run, vous devez d'abord la déployer, puis créer un déclencheur pour elle.

gcloud beta run deploy hello-gcs-function \
      --source . \
      --function HelloGcs.Function \
      --region $REGION \
      --base-image dotnet8 \
      --no-allow-unauthenticated

Créez maintenant le déclencheur de la fonction Cloud Run.

BUCKET_REGION=$REGION

gcloud eventarc triggers create hello-gcs-function-trigger \
     --location=$REGION \
     --destination-run-service=hello-gcs-function \
    --destination-run-region=$BUCKET_REGION \
     --event-filters="type=google.cloud.storage.object.v1.finalized" \
     --event-filters="bucket=$BUCKET_NAME" \
     --service-account=$SERVICE_ACCOUNT_ADDRESS

Si vous préférez déployer la fonction en tant que fonction Cloud Functions de 2e génération, vous pouvez utiliser la commande suivante pour la déployer à l'aide des options trigger-event et trigger-resource:

gcloud functions deploy hello-gcs-function \
    --allow-unauthenticated \
    --entry-point HelloGcs.Function \
    --gen2 \
    --region $REGION \
    --runtime dotnet8 \
    --trigger-event google.storage.object.finalize \
    --trigger-resource ${BUCKET_NAME} \
    --service-account=$SERVICE_ACCOUNT_ADDRESS

Après quelques minutes, la fonction devrait être visible dans Cloud Console:

c28654d74bb31420.png

Déclenchez la fonction en important un fichier dans le bucket de stockage:

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

Vérifiez que la fonction a été déclenchée en consultant les journaux:

Pour une fonction Cloud Run, vous pouvez exécuter la commande suivante:

gcloud logging read "resource.labels.service_name=hello-gcs-function AND textPayload: Name" --format=json

Pour une fonction de 2e génération, vous pouvez exécuter la commande suivante:

gcloud functions logs read hello-gcs-function \
    --gen2 \
    --region us-central1

7. Fonction CloudEvent : Pub/Sub

Vous allez créer et déployer une fonction CloudEvent qui répond aux événements Cloud Pub/Sub.

Commencez par créer un sujet Cloud Pub/Sub qui émettra des événements:

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

Créez une fonction CloudEvent à l'aide du modèle gcf-event:

cd ..
mkdir HelloPubSub
cd HelloPubSub
dotnet new gcf-event

Cela crée un projet et un fichier Function.cs répondant aux requêtes CloudEvent. Il analyse également les données de CloudEvent dans StorageObjectData par défaut.

Remplacez le framework cible par net8.0 dans le fichier .csproj:

<TargetFramework>net8.0</TargetFramework>

Remplacez StorageObjectData par MessagePublishedData pour analyser les messages Pub/Sub. Remplacez Google.Events.Protobuf.Cloud.Storage.V1 par Google.Events.Protobuf.Cloud.PubSub.V1.

Votre fonction devrait se présenter comme suit:

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

namespace HelloPubSub;

public class Function : ICloudEventFunction<MessagePublishedData>
{
    public Task HandleAsync(CloudEvent cloudEvent, MessagePublishedData data, CancellationToken cancellationToken)
    {
        var nameFromMessage = data.Message?.TextData;
        var name = string.IsNullOrEmpty(nameFromMessage) ? "world" : nameFromMessage;
        Console.WriteLine($"Hello {name}");
        return Task.CompletedTask;
    }
}

Pour déployer une fonction Cloud Run directement sur Cloud Run, vous devez d'abord la déployer, puis créer un déclencheur pour elle.

gcloud beta run deploy hello-pubsub-function \
      --source . \
      --function HelloPubSub.Function \
      --region $REGION \
      --base-image dotnet8 \
      --no-allow-unauthenticated \
      --service-account=$SERVICE_ACCOUNT_ADDRESS

Créez maintenant le déclencheur de la fonction Cloud Run.

gcloud eventarc triggers create my-pubsub-trigger \
    --location=$REGION \
    --service-account=$SERVICE_ACCOUNT_ADDRESS \
    --destination-run-service=hello-pubsub-function \
    --destination-run-region=$REGION \
    --destination-run-path="/" \
    --event-filters="type=google.cloud.pubsub.topic.v1.messagePublished" \
    --transport-topic=projects/$PROJECT_ID/topics/$TOPIC_NAME

Si vous préférez déployer la fonction en tant que Cloud Functions 2e génération, vous pouvez utiliser la commande suivante pour la déployer à l'aide de l'indicateur trigger-topic:

gcloud functions deploy hello-pubsub-function \
    --allow-unauthenticated \
    --entry-point HelloPubSub.Function \
    --gen2 \
    --region us-central1 \
    --runtime dotnet8 \
    --trigger-topic ${TOPIC_NAME}

Après quelques minutes, la fonction devrait être visible dans Cloud Console:

3443808da7caf3bc.png

Déclenchez la fonction en publiant un message dans le sujet:

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

Vérifiez que la fonction a été déclenchée en lisant les journaux.

Pour une fonction Cloud Run, vous pouvez exécuter la commande suivante:

gcloud logging read "resource.labels.service_name=hello-pubsub-function AND textPayload: World" --format=json

Pour une fonction de 2e génération, vous pouvez exécuter la commande suivante:

gcloud functions logs read hello-pubsub-function \
    --gen2 \
    --region us-central1

8. Fonction CloudEvent – Non typée

Si vous testez CloudEvents et que vous ne disposez pas encore d'un modèle de données de charge utile que vous souhaitez utiliser, ou si vous souhaitez que votre fonction puisse gérer n'importe quel événement Cloud, vous pouvez utiliser une fonction CloudEvent non typée.

Créez une fonction CloudEvent à l'aide du modèle gcf-untyped-event:

cd ..
mkdir HelloUntyped
cd HelloUntyped
dotnet new gcf-untyped-event

Cela crée un projet et un fichier Function.cs répondant aux requêtes CloudEvent sans aucune tentative d'analyse des données de l'CloudEvent.

Remplacez le framework cible par net8.0 dans le fichier .csproj:

<TargetFramework>net8.0</TargetFramework>

Pour déployer une fonction Cloud Run directement sur Cloud Run, vous devez d'abord la déployer, puis créer un déclencheur pour elle.

gcloud beta run deploy hello-untyped-function \
      --source . \
      --function HelloUntyped.Function \
      --region $REGION \
      --base-image dotnet8 \
      --no-allow-unauthenticated

Créez maintenant le déclencheur de la fonction Cloud Run.

BUCKET_REGION=$REGION

gcloud eventarc triggers create hello-untyped-function-trigger \
     --location=$REGION \
     --destination-run-service=hello-untyped-function \
    --destination-run-region=$BUCKET_REGION \
     --event-filters="type=google.cloud.storage.object.v1.finalized" \
     --event-filters="bucket=$BUCKET_NAME" \
     --service-account=$SERVICE_ACCOUNT_ADDRESS

Si vous préférez déployer la fonction en tant que fonction Cloud Functions de 2e génération, vous pouvez utiliser la commande suivante pour la déployer à l'aide des options trigger-event et trigger-resource:

gcloud functions deploy hello-untyped-function \
    --allow-unauthenticated \
    --entry-point HelloUntyped.Function \
    --gen2 \
    --region us-central1 \
    --runtime dotnet8 \
    --trigger-event google.storage.object.finalize \
    --trigger-resource ${BUCKET_NAME}

La fonction se déclenche lorsqu'un fichier est importé dans un bucket de stockage.

Après quelques minutes, la fonction devrait être visible dans Cloud Console:

afe56530826787c6.png

Déclenchez la fonction en important un fichier dans le bucket de stockage:

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

Vérifiez que la fonction a été déclenchée en lisant les journaux.

Pour une fonction Cloud Run, vous pouvez exécuter la commande suivante:

gcloud logging read "resource.labels.service_name=hello-gcs-function AND textPayload: Name" --format=json

Pour une fonction de 2e génération, vous pouvez exécuter la commande suivante:

gcloud functions logs read hello-untyped-function \
    --gen2 \
    --region us-central1

9. Félicitations !

Bravo ! Vous avez terminé cet atelier de programmation.

Points abordés

  • Framework des fonctions pour .NET
  • Écrire une fonction Cloud HTTP
  • Écrire une fonction CloudEvent répondant aux événements Cloud Storage
  • Écrire une fonction CloudEvent qui répond aux événements Cloud Pub/Sub
  • Écrire une fonction CloudEvent répondant à n'importe quel type d'événement