Implementa una aplicación de JavaScript en Cloud Run con AlloyDB

1. Descripción general

Cloud Run es una plataforma sin servidores completamente administrada que te permite ejecutar contenedores sin estado que se pueden invocar a través de solicitudes HTTP. En este codelab, se mostrará cómo conectar una aplicación de Node.js en Cloud Run a AlloyDB de forma segura con una cuenta de servicio mediante la autenticación de IAM.

Qué aprenderás

En este lab, aprenderás a hacer lo siguiente:

  • Crea una instancia de AlloyDB (configurada para usar Private Service Connect).
  • Implementa una aplicación en Cloud Run que se conecte a tu instancia de AlloyDB
  • Usa Gemini Code Assist para agregar funcionalidad a tu aplicación

2. Requisitos previos

  1. Si aún no tienes una Cuenta de Google, debes crear una.
    • Usa una cuenta personal en lugar de una cuenta de trabajo o de institución educativa. Es posible que las cuentas de trabajo o de instituciones educativas tengan restricciones que te impidan habilitar las APIs necesarias para este lab.

3. Configura el proyecto

  1. Accede a la consola de Google Cloud.
  2. Habilita la facturación en la consola de Cloud.
    • Completar este lab debería costar menos de USD 1 en recursos de Cloud.
    • Puedes seguir los pasos que se indican al final de este lab para borrar recursos y evitar cargos adicionales.
    • Los usuarios nuevos son aptos para la prueba gratuita de USD 300.
  3. Crea un proyecto nuevo o elige reutilizar uno existente.

4. Abrir el editor de Cloud Shell

  1. Navega al Editor de Cloud Shell.
  2. Si la terminal no aparece en la parte inferior de la pantalla, ábrela:
    • Haz clic en el menú de opciones Ícono de menú de opciones.
    • Haz clic en Terminal.
    • Haz clic en Terminal nueva. Cómo abrir una terminal nueva en el editor de Cloud Shell
  3. En la terminal, configura tu proyecto con este comando:
    • Formato:
      gcloud config set project [PROJECT_ID]
      
    • Ejemplo:
      gcloud config set project lab-project-id-example
      
    • Si no recuerdas el ID de tu proyecto, haz lo siguiente:
      • Puedes enumerar todos los IDs de tu proyecto con lo siguiente:
        gcloud projects list | awk '/PROJECT_ID/{print $2}'
        
      Establece el ID del proyecto en la terminal del Editor de Cloud Shell
  4. Si se te solicita autorización, haz clic en Autorizar para continuar. Haz clic para autorizar Cloud Shell
  5. Deberías ver el siguiente mensaje:
    Updated property [core/project].
    
    Si ves un WARNING y se te pregunta Do you want to continue (Y/N)?, es probable que hayas ingresado el ID del proyecto de forma incorrecta. Presiona N, presiona Enter y vuelve a intentar ejecutar el comando gcloud config set project.

5. Habilita las APIs

En la terminal, habilita las APIs:

gcloud services enable \
  compute.googleapis.com \
  alloydb.googleapis.com \
  run.googleapis.com \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  cloudaicompanion.googleapis.com

Si se te solicita autorización, haz clic en Autorizar para continuar. Haz clic para autorizar Cloud Shell

Este comando puede tardar unos minutos en completarse, pero, en algún momento, debería mostrar un mensaje de éxito similar al siguiente:

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

6. Configura una cuenta de servicio

Crea y configura una cuenta de servicio de Google Cloud que Cloud Run pueda usar para que tenga los permisos correctos para conectarse a AlloyDB.

  1. Ejecuta el comando gcloud iam service-accounts create de la siguiente manera para crear una cuenta de servicio nueva:
    gcloud iam service-accounts create quickstart-service-account \
      --display-name="Quickstart Service Account"
    
  2. Ejecuta el comando gcloud projects add-iam-policy-binding de la siguiente manera para agregar el rol de usuario de la base de datos de AlloyDB a la cuenta de servicio de Google Cloud que acabas de crear.
    gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
      --member="serviceAccount:quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
      --role="roles/alloydb.databaseUser"
    
  3. Ejecuta el comando gcloud projects add-iam-policy-binding de la siguiente manera para agregar el rol de consumidor de Service Usage a la cuenta de servicio de Google Cloud que acabas de crear.
    gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
      --member="serviceAccount:quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
      --role="roles/serviceusage.serviceUsageConsumer"
    
  4. Ejecuta el comando gcloud projects add-iam-policy-binding de la siguiente manera para agregar el rol de escritor de registros a la cuenta de servicio de Google Cloud que acabas de crear.
    gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
      --member="serviceAccount:quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
      --role="roles/logging.logWriter"
    

7. Crea una instancia de AlloyDB

  1. Ejecuta el comando gcloud alloydb clusters create para crear una instancia de Cloud SQL
    gcloud alloydb clusters create quickstart-cluster \
      --password=$(openssl rand -base64 20) \
      --region=us-central1 \
      --project=${GOOGLE_CLOUD_PROJECT} \
      --enable-private-service-connect \
      --database-version=POSTGRES_16
    

Este comando puede tardar unos minutos en completarse.

  1. Ejecuta el comando gcloud alloydb instances create para crear una instancia de Cloud SQL
    gcloud alloydb instances create quickstart-instance \
      --project=${GOOGLE_CLOUD_PROJECT} \
      --instance-type=PRIMARY \
      --cpu-count=2 \
      --region=us-central1 \
      --cluster=quickstart-cluster \
      --allowed-psc-projects=${GOOGLE_CLOUD_PROJECT} \
      --database-flags=alloydb.iam_authentication=on
    
  2. Ejecuta el comando gcloud alloydb instances describe para obtener el vínculo del archivo adjunto de servicio de PSC y exportarlo a una variable.
    export SERVICE_ATTACHMENT=$(gcloud alloydb instances describe quickstart-instance \
        --cluster=quickstart-cluster --region=us-central1 \
        --format="value(pscInstanceConfig.serviceAttachmentLink)")
    
  3. gcloud compute addresses create quickstart-address \
      --region=us-central1 \
      --subnet=default
    
  4. gcloud compute forwarding-rules create quickstart-endpoint \
      --region=us-central1 \
      --network=default \
      --address=quickstart-address \
      --target-service-attachment=${SERVICE_ATTACHMENT}
    

Crea un usuario de la base de datos de PostgreSQL para la cuenta de servicio que creaste antes para acceder a la base de datos.

gcloud alloydb users create quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam \
  --cluster=quickstart-cluster \
  --region=us-central1 \
  --type=IAM_BASED \
  --superuser=true

8. Prepara la solicitud

Prepara una aplicación de Node.js que responda a las solicitudes HTTP.

  1. En Cloud Shell, crea un directorio nuevo llamado helloworld y, luego, cambia a ese directorio:
    mkdir helloworld
    cd helloworld
    
  2. Inicializa un archivo package.json como un módulo.
    npm init -y
    npm pkg set type="module"
    npm pkg set main="index.mjs"
    npm pkg set scripts.start="node index.mjs"
    
  3. Instala la biblioteca de Google Cloud Auth.
    npm install google-auth-library
    
  4. Instala pg para interactuar con la base de datos de PostgreSQL.
    npm install pg
    
  5. Instala Express para aceptar solicitudes HTTP entrantes.
    npm install express
    
  6. Crea un archivo index.mjs con el código de la aplicación. Este código puede hacer lo siguiente:
    • Acepta solicitudes HTTP
    • Conéctate a la base de datos
    • Almacena la hora de la solicitud HTTP en la base de datos
    • Devuelve las horas de las últimas cinco solicitudes
    Ejecuta el siguiente comando en Cloud Shell:
    cat > index.mjs << "EOF"
    import express from 'express';
    import pg from 'pg';
    const { Pool } = pg;
    import {GoogleAuth} from 'google-auth-library';
    
    const auth = new GoogleAuth({
      scopes: ['https://www.googleapis.com/auth/alloydb.login'],
    });
    
    const pool = new Pool({
      host: process.env.DB_HOST,
      user: process.env.DB_USER,
      password: async () => {
        return await auth.getAccessToken();
      },
      database: process.env.DB_NAME,
      ssl: {
        require: true,
        rejectUnauthorized: false, // required for self-signed certs
        // https://node-postgres.com/features/ssl#self-signed-cert
      }
    });
    
    const app = express();
    
    app.get('/', async (req, res) => {
      await pool.query('INSERT INTO visits(created_at) VALUES(NOW())');
      const {rows} = await pool.query('SELECT created_at FROM visits ORDER BY created_at DESC LIMIT 5');
      console.table(rows); // prints the last 5 visits
      res.send(rows);
    });
    
    const port = parseInt(process.env.PORT) || 8080;
    app.listen(port, async () => {
      console.log('process.env: ', process.env);
      await pool.query(`CREATE TABLE IF NOT EXISTS visits (
        id SERIAL NOT NULL,
        created_at timestamp NOT NULL,
        PRIMARY KEY (id)
      );`);
      console.log(`helloworld: listening on port ${port}`);
    });
    
    EOF
    

Con este código, se crea un servidor web básico que escucha en el puerto definido por la variable de entorno PORT. La aplicación ya está lista para implementarse.

9. Implementa una aplicación de Cloud Run

  1. Ejecuta el comando gcloud projects add-iam-policy-binding de la siguiente manera para agregar el rol de usuario de red a la cuenta de servicio de Cloud Run del servicio de Cloud Run que estás a punto de crear.
    gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
    --member "serviceAccount:service-$(gcloud projects describe ${GOOGLE_CLOUD_PROJECT} --format="value(projectNumber)")@serverless-robot-prod.iam.gserviceaccount.com" \
    --role "roles/compute.networkUser"
    
  1. Ejecuta el siguiente comando para implementar tu aplicación en Cloud Run:
    gcloud run deploy helloworld \
      --region=us-central1 \
      --source=. \
      --set-env-vars DB_NAME="quickstart_db" \
      --set-env-vars DB_USER="postgres" \
      --set-env-vars DB_PASSWORD=${DB_PASSWORD} \
      --set-env-vars DB_HOST="$(gcloud sql instances describe quickstart-instance --project=${GOOGLE_CLOUD_PROJECT} --format='value(settings.ipConfiguration.pscConfig.pscAutoConnections.ipAddress)')" \
      --service-account="quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
      --network=default \
      --subnet=default \
      --allow-unauthenticated
    
  2. Si se te solicita, presiona Y y Enter para confirmar que deseas continuar:
    Do you want to continue (Y/n)? Y
    

Después de unos minutos, la aplicación debería proporcionarte una URL para que la visites.

Navega a la URL para ver tu aplicación en acción. Cada vez que visites la URL o actualices la página, verás las cinco visitas más recientes que se muestran como JSON.

Después de unos minutos, la aplicación debería proporcionarte una URL para que la visites.

Navega a la URL para ver tu aplicación en acción. Cada vez que visites la URL o actualices la página, verás las cinco visitas más recientes que se muestran como JSON.

10. Felicitaciones

En este lab, aprendiste a realizar las siguientes tareas:

  • Crea una instancia de AlloyDB (configurada para usar Private Service Connect).
  • Implementa una aplicación en Cloud Run que se conecte a tu instancia de AlloyDB
  • Usa Gemini Code Assist para agregar funcionalidad a tu aplicación

Limpia

Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos usados en este instructivo, borra el proyecto que contiene los recursos o conserva el proyecto y borra los recursos individuales. Si quieres borrar todo el proyecto, puedes ejecutar lo siguiente:

gcloud projects delete ${GOOGLE_CLOUD_PROJECT}