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 sujets. Chaque clic générera une nouvelle page avec de nouveaux liens en fonction de votre sélection. Vous allez créer ce site Web avec Node.js et Fastify, utiliser le SDK Vertex AI pour appeler Gemini, le déployer en tant que service sécurisé et prêt pour la production sur Cloud Run, et le sécuriser à l'aide d'Identity-Aware Proxy (IAP).

Objectifs de l'atelier

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

Points abordés

  • 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. Les comptes professionnels et scolaires peuvent être soumis à des restrictions qui vous empêchent d'activer les API nécessaires à cet atelier.
  2. Connectez-vous à la console Google Cloud.
  3. Activez la facturation dans la console Cloud.
    • La réalisation de cet atelier devrait coûter moins de 1 $en ressources cloud.
    • Vous pouvez suivre les étapes à la fin de cet atelier pour supprimer les ressources et éviter des frais supplémentaires.
    • Les nouveaux utilisateurs peuvent bénéficier de l'essai sans frais de 300$.
  4. Créez un projet ou réutilisez un projet existant.
    • Si une erreur concernant le quota de projet s'affiche, 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 une action à un moment donné, 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 afficher la liste de 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 un WARNING s'affiche et que vous êtes invité à répondre Do you want to continue (Y/n)?, vous avez probablement saisi l'ID de projet de manière incorrecte. Appuyez sur n, puis sur Enter, et essayez d'exécuter à nouveau la commande gcloud config set project.
  1. Définissez 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 une action, cliquez sur Autoriser pour continuer. Cliquez pour autoriser Cloud Shell.

L'exécution de cette commande peut prendre quelques minutes, mais elle devrait finir par générer un message de réussite semblable à celui-ci :

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 à déployer :
    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 des 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'interface utilisateur 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-west4',
    });
    
    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, elle utilise le paramètre de requête nextPageDescription (ou une valeur par défaut) comme invite 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. Autorisez le compte de service à 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 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-west4 \
        --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-west4"
    
    Nous utilisons ici quelques indicateurs importants :
    • --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éconfigurée.
    • --no-allow-unauthenticated : garantit que seuls les utilisateurs authentifiés peuvent accéder au service.
    • --iap : active Identity-Aware Proxy (IAP) pour gérer l'accès à votre application. IAP vous permet de contrôler l'accès en fonction de l'identité et du contexte de l'utilisateur, et pas seulement des adresses IP.
  2. Après 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 :

  • Autoriser le service IAP lui-même à appeler votre service Cloud Run.
  • Vous autoriser (ou autoriser 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-west4 \
        --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. Cela vous permet d'accéder aux ressources HTTPS sécurisées par IAP.
    gcloud beta iap web add-iam-policy-binding \
        --resource-type=cloud-run \
        --region=europe-west4 \
        --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-west4
    
  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'êtes pas déjà. Une fois authentifié, la première page générée automatiquement devrait s'afficher.
  3. Cliquez sur n'importe quel 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 terminé ! Vous avez déployé un site Web d'interface utilisateur 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, de Vertex AI et d'IAP.

(Facultatif) Effectuer un nettoyage

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

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. Supprimer le répertoire du projet de l'atelier :
    rm -rf ~/gen-ui-on-cloudrun
    
  2. Avertissement ! Cette action est irréversible. Si vous souhaitez tout supprimer de votre Cloud Shell pour libérer de l'espace, vous pouvez supprimer l'intégralité de votre répertoire personnel. Assurez-vous que tout ce que vous souhaitez conserver est enregistré ailleurs.
    sudo rm -rf $HOME