Déployer un site Web d'interface utilisateur générative sur Cloud Run

1. Introduction

Présentation

Dans cet atelier, vous allez créer et déployer un site Web dont le contenu est généré à la volée par les grands modèles de langage Gemini de Google. Le site Web sera un simple navigateur de type "choisissez votre propre aventure" pour explorer des thèmes. Chaque clic générera une nouvelle page avec de nouveaux liens en fonction de votre sélection. Vous allez créer cette application avec Node.js et Fastify, utiliser le SDK Vertex AI pour appeler Gemini, la déployer en tant que service sécurisé et prêt pour la production sur Cloud Run, et la sécuriser à l'aide d'Identity-Aware Proxy (IAP).

Objectifs de l'atelier

  • Créez une application Node.js Fastify qui utilise Vertex AI.
  • Déployez l'application sur Cloud Run à partir de la source, sans fichier Dockerfile.
  • Sécurisez le point de terminaison Cloud Run à l'aide d'Identity-Aware Proxy (IAP).

Points abordés

  • Découvrez comment utiliser le SDK Vertex AI pour Node.js afin de générer du contenu.
  • Déployer une application Node.js sur Cloud Run
  • Sécuriser une application Cloud Run avec IAP

2. Configuration du projet

  1. Si vous ne possédez pas encore de compte Google, vous devez en créer un.
    • Utilisez un compte personnel au lieu d'un compte professionnel ou scolaire. Il est possible que des restrictions s'appliquent aux comptes professionnels et scolaires, ce qui vous empêche d'activer les API nécessaires pour cet atelier.
  2. Connectez-vous à la console Google Cloud.
  3. Activez la facturation dans la console Cloud.
    • Cet atelier devrait vous coûter moins de 1 USD en ressources Cloud.
    • Vous pouvez suivre les étapes à la fin de cet atelier pour supprimer les ressources et éviter ainsi des frais supplémentaires.
    • Les nouveaux utilisateurs peuvent bénéficier d'un essai sans frais pour bénéficier d'un crédit de 300$.
  4. Créez un projet ou réutilisez-en un existant.
    • Si vous voyez une erreur concernant le quota de projet, réutilisez un projet existant ou supprimez-en un pour en créer un.

3. Ouvrir l'éditeur Cloud Shell

  1. Cliquez sur ce lien pour accéder directement à l'éditeur Cloud Shell.
  2. Si vous êtes invité à autoriser l'accès à un moment donné aujourd'hui, cliquez sur Autoriser pour continuer. Cliquez pour autoriser Cloud Shell.
  3. Si le terminal ne s'affiche pas en bas de l'écran, ouvrez-le :
    • Cliquez sur Afficher.
    • Cliquez sur TerminalOuvrir un nouveau terminal dans l'éditeur Cloud Shell.
  4. Dans le terminal, définissez votre projet à l'aide de la commande suivante :
    • Format :
      gcloud config set project [PROJECT_ID]
      
    • Exemple :
      gcloud config set project lab-project-id-example
      
    • Si vous ne vous souvenez pas de l'ID de votre projet :
      • Vous pouvez lister tous vos ID de projet avec la commande suivante :
        gcloud projects list | awk '/PROJECT_ID/{print $2}'
        
      Définir l'ID du projet dans le terminal de l'éditeur Cloud Shell
  5. Le message suivant doit s'afficher :
    Updated property [core/project].
    
    Si le message WARNING s'affiche et que vous êtes invité à Do you want to continue (Y/n)?, cela signifie probablement que vous avez saisi l'ID de projet de manière incorrecte. Appuyez sur n, puis sur Enter, et réessayez d'exécuter la commande gcloud config set project.
  1. Définir la variable d'environnement GOOGLE_CLOUD_PROJECT
    export GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project)
    

4. Activer les API

Dans le terminal, activez les API :

gcloud services enable \
  run.googleapis.com \
  aiplatform.googleapis.com \
  cloudresourcemanager.googleapis.com \
  iap.googleapis.com

Si vous êtes invité à autoriser l'accès, cliquez sur Autoriser pour continuer. Cliquez pour autoriser Cloud Shell.

L'exécution de cette commande peut prendre quelques minutes, mais un message semblable à celui qui suit devrait s'afficher pour vous indiquer que l'opération s'est correctement déroulée :

Operation "operations/acf.p2-73d90d00-47ee-447a-b600" finished successfully.

5. Préparer votre projet Node.js

  1. Créez un dossier nommé gen-ui-on-cloudrun pour stocker le code source du déploiement :
    mkdir gen-ui-on-cloudrun && cd gen-ui-on-cloudrun
    
  2. Initialisez un projet Node.js :
    npm init -y
    
  3. Configurez le projet pour qu'il utilise les modules ES et définissez un script de démarrage en exécutant les commandes suivantes :
    npm pkg set type="module"
    
  4. Installez fastify pour le serveur Web et @google/genai pour le SDK Vertex AI :
    npm install fastify @google/genai
    

6. Créer le code de l'application

  1. Créez et ouvrez un fichier index.ts pour le code source de l'application :
    cloudshell edit ~/gen-ui-on-cloudrun/index.ts
    
    La commande cloudshell edit ouvre le fichier index.ts dans l'éditeur au-dessus du terminal.
  2. Ajoutez le code source du serveur d'UI générative suivant dans le fichier index.ts :
    import fastifyLib from 'fastify';
    import { GoogleGenAI } from '@google/genai';
    
    const fastify = fastifyLib({ logger: true });
    
    const ai = new GoogleGenAI({
        vertexai: true,
        project: process.env.GOOGLE_CLOUD_PROJECT,
        location: process.env.GOOGLE_CLOUD_LOCATION || 'europe-west1',
    });
    
    const SYSTEM_INSTRUCTION = `The user should have submitted an html page and the id of the element just clicked.
    Given the next page description, create a new webpage with a link back to "Start Over" (the / route), a brief overview of the topic, and a list of clickable link elements related to the page.
    When an element is clicked, the webpage should link to the base route / with the nextPageDescription as a query string parameter.
    All information needed to generate the next page should be included in the nextPageDescription without additional context.
    Each nextPageDescription should be less than 1500 characters.
    
    Example:
    If the current HTML page is for a small pet store, it might include a link to an "About" page.
    The href for the about page link should be /?nextPageDescription=about%20page%20for%20small%20pet%20store%20website
    
    All responses should be valid HTML without markdown backticks.`;
    
    interface QueryParams {
        nextPageDescription?: string;
    }
    
    fastify.get<{ Querystring: QueryParams }>('/', async (request, reply) => {
        const {
            nextPageDescription = 'A web page with interesting fun facts where I can select a fact to learn more about that topic.'
        } = request.query;
    
        try {
            const response = await ai.models.generateContent({
                model: 'gemini-2.5-flash',
                contents: nextPageDescription,
                config: {
                    systemInstruction: SYSTEM_INSTRUCTION,
                    temperature: 0.9,
                }
            });
    
            reply.type('text/html; charset=utf-8').send(response.text);
        } catch (error: any) {
            request.log.error(error);
            reply.status(500).send('An error occurred calling the AI.');
        }
    });
    
    const start = async () => {
        try {
            await fastify.listen({ port: Number(process.env.PORT) || 8080, host: '0.0.0.0' });
        } catch (err) {
            fastify.log.error(err);
            process.exit(1);
        }
    };
    
    start();
    

Ce code configure un serveur Web qui écoute les requêtes HTTP GET sur le chemin racine (/). Lorsqu'une requête est reçue, il utilise le paramètre de requête nextPageDescription (ou une valeur par défaut) comme requête pour le modèle Gemini 2.5 Flash via Vertex AI. Le modèle est invité par SYSTEM_INSTRUCTION à renvoyer une page HTML contenant des liens, où chaque lien inclut un nextPageDescription pour générer la page suivante.

7. Créer un compte de service

Vous avez besoin d'un compte de service pour que votre service Cloud Run s'authentifie auprès de l'API Vertex AI.

  1. Créez un compte de service nommé gen-navigator-sa :
    gcloud iam service-accounts create gen-navigator-sa --display-name="Generative Navigator Service Account"
    
  2. Accordez au compte de service l'autorisation d'utiliser Vertex AI :
    gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
        --member="serviceAccount:gen-navigator-sa@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com" \
        --role="roles/aiplatform.user"
    

8. Déployer dans Cloud Run

Déployez maintenant l'application sur Cloud Run directement à partir du code source, sans avoir besoin d'un fichier Dockerfile.

  1. Exécutez la commande gcloud pour déployer l'application :
    cd ~/gen-ui-on-cloudrun
    gcloud beta run deploy generative-web-navigator \
        --source . \
        --no-build \
        --base-image=nodejs24 \
        --command="node" \
        --args="index.ts" \
        --region=europe-west1 \
        --no-allow-unauthenticated \
        --iap \
        --service-account="gen-navigator-sa@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com" \
        --set-env-vars GOOGLE_CLOUD_PROJECT="$GOOGLE_CLOUD_PROJECT",GOOGLE_CLOUD_LOCATION="europe-west1"
    
    Nous utilisons quelques options importantes ici :
    • --source . --no-build --base-image=nodejs24 : indique à Cloud Run de déployer le code source à partir du répertoire actuel, d'ignorer la phase de compilation et d'exécuter l'application à l'aide d'une image de base Node.js 24 prédéfinie.
    • --no-allow-unauthenticated : cela garantit que seuls les utilisateurs authentifiés peuvent accéder au service.
    • --iap : permet à Identity-Aware Proxy (IAP) de gérer l'accès à votre application. IAP vous permet de contrôler les accès en fonction de l'identité d'un utilisateur et du contexte, et pas seulement des adresses IP.
  2. Au bout de quelques minutes, un message semblable à celui-ci s'affiche :
    Service [generative-web-navigator] revision [generative-web-navigator-12345-abc] has been deployed and is serving 100 percent of traffic.
    

Vous avez déployé votre application, mais vous devez encore configurer IAP pour autoriser l'accès.

9. Configurer l'accès à IAP

Lorsque vous activez IAP sur Cloud Run, IAP intercepte toutes les requêtes et exige que les utilisateurs s'authentifient et soient autorisés avant de pouvoir accéder à votre service. Pour que cela fonctionne, vous devez accorder deux autorisations :

  • Autorisez le service IAP lui-même à appeler votre service Cloud Run.
  • Autorisez-vous (ou d'autres utilisateurs/groupes) à accéder à l'application via IAP.
  1. Obtenez le numéro de votre projet, qui est nécessaire pour identifier l'agent de service IAP :
    export PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format="value(projectNumber)")
    
  2. Attribuez le rôle roles/run.invoker à l'agent de service IAP sur votre service Cloud Run. Cela permet à IAP d'appeler votre service après avoir authentifié et autorisé un utilisateur.
    gcloud run services add-iam-policy-binding generative-web-navigator \
        --region=europe-west1 \
        --member="serviceAccount:service-$PROJECT_NUMBER@gcp-sa-iap.iam.gserviceaccount.com" \
        --role="roles/run.invoker"
    
  3. Attribuez le rôle roles/iap.httpsResourceAccessor à votre compte utilisateur. Vous pouvez ainsi accéder aux ressources HTTPS sécurisées par IAP.
    gcloud beta iap web add-iam-policy-binding \
        --resource-type=cloud-run \
        --region=europe-west1 \
        --service=generative-web-navigator \
        --member="user:$(gcloud config get-value account)" \
        --role="roles/iap.httpsResourceAccessor"
    

10. Tester l'application

  1. Obtenez l'URL de votre service déployé :
    gcloud run services describe generative-web-navigator --format='value(status.url)' --region=europe-west1
    
  2. Copiez l'URL et ouvrez-la dans votre navigateur Web. Étant donné que le service est sécurisé avec IAP, vous serez invité à vous connecter avec votre compte Google si vous ne l'avez pas déjà fait. Une fois l'authentification effectuée, la première page générée automatiquement devrait s'afficher.
  3. Cliquez sur un lien pour accéder à une nouvelle page, qui sera générée par l'IA en fonction du lien sur lequel vous avez cliqué.

Vous avez réussi ! Vous avez déployé un site Web d'UI générative sur Cloud Run et l'avez sécurisé à l'aide d'IAP.

11. Conclusion

Félicitations ! Vous avez déployé et sécurisé un site Web d'interface utilisateur générative à l'aide de Cloud Run, Vertex AI et IAP.

(Facultatif) Effectuer un nettoyage

Si vous souhaitez nettoyer ce que vous avez créé, vous pouvez supprimer votre projet Cloud pour éviter que des frais supplémentaires ne soient facturés.

Bien que le service Cloud Run ne soit pas facturé lorsqu'il n'est pas utilisé, il se peut que des frais vous incombent pour le stockage des artefacts de compilation, le cas échéant. La suppression de votre projet Cloud arrête la facturation de toutes les ressources utilisées dans ce projet.

Si vous le souhaitez, supprimez le projet :

gcloud projects delete $GOOGLE_CLOUD_PROJECT

Vous pouvez également supprimer les ressources inutiles de votre disque Cloud Shell. Vous pouvez :

  1. Supprimez le répertoire du projet de l'atelier de programmation :
    rm -rf ~/gen-ui-on-cloudrun
    
  2. Avertissement ! Cette prochaine action est irréversible. Si vous souhaitez supprimer tous les éléments de votre Cloud Shell pour libérer de l'espace, vous pouvez supprimer l'intégralité de votre répertoire d'accueil. Veillez à ce que tout ce que vous souhaitez conserver soit enregistré ailleurs.
    sudo rm -rf $HOME