Cómo conectar una aplicación de Node.js en Cloud Run a una base de datos de Cloud SQL para PostgreSQL

1. Descripción general

El conector de Cloud SQL para Node.js es la forma más sencilla de conectar de forma segura tu aplicación de Node.js a tu base de datos de Cloud SQL. 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 de forma segura una aplicación de Node.js en Cloud Run a una base de datos de Cloud SQL para PostgreSQL con una cuenta de servicio que use la autenticación de IAM.

Qué aprenderás

En este lab, aprenderás a realizar las siguientes tareas:

  • Crea una instancia de Cloud SQL para la base de datos de PostgreSQL
  • Implementa una aplicación de Node.js en Cloud Run
  • Conecta tu aplicación a la base de datos con la biblioteca del conector de Node.js de Cloud SQL

Requisitos previos

  • Para este lab, se da por sentado que el usuario tiene conocimientos previos sobre los entornos de shell y la consola de Cloud.

2. Antes de comenzar

Configuración del proyecto de Cloud

  1. Accede a Google Cloud Console y crea un proyecto nuevo o reutiliza uno existente. Si aún no tienes una Cuenta de Google, debes crear una.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • El Nombre del proyecto es el nombre visible de los participantes de este proyecto. Es una cadena de caracteres que no se utiliza en las APIs de Google. Puedes actualizarla en cualquier momento.
  • El ID del proyecto es único en todos los proyectos de Google Cloud y es inmutable (no se puede cambiar después de configurarlo). La consola de Cloud genera automáticamente una cadena única. Por lo general, no importa cuál sea. En la mayoría de los codelabs, deberás hacer referencia al ID del proyecto (suele identificarse como PROJECT_ID). Si no te gusta el ID que se generó, podrías generar otro aleatorio. También puedes probar uno propio y ver si está disponible. No se puede cambiar después de este paso y se usará el mismo durante todo el proyecto.
  • Recuerda que hay un tercer valor, un número de proyecto, que usan algunas APIs. Obtén más información sobre estos tres valores en la documentación.
  1. A continuación, deberás habilitar la facturación en la consola de Cloud para usar las APIs o los recursos de Cloud. Ejecutar este codelab no debería costar mucho, tal vez nada. Para cerrar recursos y evitar que se generen cobros más allá de este instructivo, puedes borrar los recursos que creaste o borrar todo el proyecto. Los usuarios nuevos de Google Cloud son aptos para participar en el programa Prueba gratuita de USD 300.

Configuración del entorno

Para activar Cloud Shell, haz clic en el ícono que se encuentra a la derecha de la barra de búsqueda.

ecdc43ada29e91b.png

En Cloud Shell, habilita las APIs:

gcloud services enable compute.googleapis.com sqladmin.googleapis.com \
  run.googleapis.com artifactregistry.googleapis.com \
  cloudbuild.googleapis.com servicenetworking.googleapis.com

Si se te solicita autorización, haz clic en "Autorizar" para continuar.

6356559df3eccdda.png

Este comando puede tardar unos minutos en completarse, pero, finalmente, debería producir un mensaje de éxito similar a este:

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

3. Configura una cuenta de servicio

Crea y configura una cuenta de servicio de Google Cloud para que la use Cloud Run y tenga los permisos correctos para conectarse a Cloud SQL.

  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 cliente de Cloud SQL a la cuenta de servicio de Google Cloud que acabas de crear. En Cloud Shell, la expresión ${GOOGLE_CLOUD_PROJECT} se reemplazará por el nombre de tu proyecto. También puedes realizar este reemplazo de forma manual si te sientes más cómodo con esa opción.
    gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
      --member="serviceAccount:quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
      --role="roles/cloudsql.client"
    
  3. Ejecuta el comando gcloud projects add-iam-policy-binding de la siguiente manera para agregar el rol de usuario de la instancia de Cloud SQL 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/cloudsql.instanceUser"
    
  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"
    

4. Configura Cloud SQL

Ejecuta el comando gcloud sql instances create para crear una instancia de Cloud SQL.

  • --database-version: Es el tipo y la versión del motor de la base de datos. Si no se especifica, se usa la configuración predeterminada de API. Consulta la documentación de las versiones de la base de datos de gcloud para ver las versiones disponibles actuales.
  • --cpu: Es la cantidad de núcleos deseados en la máquina.
  • --memory: Es un valor de número entero que indica la cantidad de memoria que se desea en la máquina. Se debe proporcionar una unidad de tamaño (por ejemplo, 3,072 MB o 9 GB). Si no se especifican unidades, se supone que es GB.
  • --region: Es la ubicación regional de la instancia (por ejemplo, us-central1, asia-east1, us-east1).
  • --database-flags: Permite establecer marcas. En este caso, activamos cloudsql.iam_authentication para permitir que Cloud Run se conecte a Cloud SQL con la cuenta de servicio que creamos antes.
    gcloud sql instances create quickstart-instance \
      --database-version=POSTGRES_18 \
      --tier=db-custom-1-3840 \
      --region=us-central1 \
      --edition=ENTERPRISE \
      --database-flags=cloudsql.iam_authentication=on
    

Este comando puede tardar unos minutos en completarse.

Ejecuta el comando gcloud sql databases create para crear una base de datos de Cloud SQL dentro de quickstart-instance.

gcloud sql databases create quickstart_db \
  --instance=quickstart-instance

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

gcloud sql users create quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam \
  --instance=quickstart-instance \
  --type=cloud_iam_service_account \
  --database-roles=postgres

Advertencia: No uses --database-roles=postgres en aplicaciones de producción. Usamos esto para proporcionar los privilegios necesarios para crear y descartar tablas de forma programática para el código de este lab.

5. Prepara la aplicación

Prepara una aplicación de Node.js que responda a 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 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 dependencia del conector de Node.js de Cloud SQL.
    npm install @google-cloud/cloud-sql-connector
    
  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:
    • Aceptar solicitudes HTTP
    • Conéctate a la base de datos
    • Almacena la hora de la solicitud HTTP en la base de datos
    • Devuelve los horarios de las últimas cinco solicitudes
    Ejecuta el siguiente comando en Cloud Shell:
    cat > index.mjs << "EOF"
    import express from 'express';
    import pg from 'pg';
    import {Connector} from '@google-cloud/cloud-sql-connector';
    
    const {Pool} = pg;
    
    const connector = new Connector();
    const clientOpts = await connector.getOptions({
        instanceConnectionName: process.env.INSTANCE_CONNECTION_NAME,
        authType: 'IAM'
    });
    
    const pool = new Pool({
        ...clientOpts,
        user: process.env.DB_USER,
        database: process.env.DB_NAME
    });
    
    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.

6. Implementa la aplicación de Cloud Run

Ejecuta el siguiente comando para implementar tu aplicación en Cloud Run:

  • --region: Es la ubicación regional de la instancia (por ejemplo, us-central1, asia-east1, us-east1).
  • --source: Es el código fuente que se implementará. En este caso, . hace referencia al código fuente de la carpeta actual helloworld.
  • --set-env-vars: Establece las variables de entorno que usa la aplicación para dirigirla a la base de datos de Cloud SQL.
  • --service-account: Vincula la implementación de Cloud Run a la cuenta de servicio con permisos para conectarse a la base de datos de Cloud SQL creada al principio de este codelab.
  • --allow-unauthenticated: Permite solicitudes no autenticadas para que se pueda acceder a la aplicación desde Internet.
gcloud run deploy helloworld \
  --region=us-central1 \
  --source=. \
  --set-env-vars INSTANCE_CONNECTION_NAME="${GOOGLE_CLOUD_PROJECT}:us-central1:quickstart-instance" \
  --set-env-vars DB_NAME="quickstart_db" \
  --set-env-vars DB_USER="quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam" \
  --service-account="quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
  --allow-unauthenticated

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.

7. Felicitaciones

Implementaste una aplicación de Node.js en Cloud Run que puede conectarse a una base de datos de PostgreSQL que se ejecuta en Cloud SQL.

Temas abordados:

  • Crea una base de datos de Cloud SQL para PostgreSQL
  • Implementa una aplicación de Node.js en Cloud Run
  • Conecta tu aplicación a Cloud SQL con el conector de Node.js de Cloud SQL

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 el siguiente comando:

gcloud projects delete ${GOOGLE_CLOUD_PROJECT}