Conéctate desde Cloud Functions a Cloud SQL

En esta página, se muestran información y ejemplos para conectarse a una instancia de Cloud SQL desde un servicio que se ejecuta en Cloud Functions.

Cloud SQL es un servicio de base de datos completamente administrado que te ayuda a configurar, mantener, controlar y administrar tus bases de datos relacionales en la nube.

Cloud Functions es una solución de procesamiento ligera que permite a los desarrolladores crear funciones independientes y de un solo propósito que respondan a eventos de Cloud sin necesidad de administrar un servidor o entorno de ejecución.

Configura una instancia de Cloud SQL

  1. Habilita la API de Administrador de Cloud SQL en el proyecto desde el que te conectas, si aún no lo has hecho:

    Habilita la API

  2. Crea una instancia de Cloud SQL para MySQL

    De forma predeterminada, Cloud SQL asigna una dirección IP pública a una instancia nueva. También puedes asignar una dirección IP privada. Para obtener más información sobre las opciones de conectividad de ambas, consulta la página Descripción general de las conexiones.

Configura Cloud Functions

Los pasos para configurar Cloud Functions dependen del tipo de dirección IP que hayas asignado a la instancia de Cloud SQL.

IP pública (opción predeterminada)

Para configurar Cloud Functions a fin de habilitar conexiones a una instancia de Cloud SQL, haz lo siguiente:

  • Asegúrate de que la instancia creada anteriormente tenga una dirección IP pública. Puedes verificarlo en la página Descripción general de tu instancia en Google Cloud Console. Si necesitas agregar una, consulta la página Configura IP públicas para obtener instrucciones.
  • Obtén el INSTANCE_CONNECTION_NAME de tu instancia. Puedes encontrarlo en la página Descripción general de la instancia en Google Cloud Console o mediante la ejecución del siguiente comando: gcloud sql instances describe [INSTANCE_NAME].
  • Asegúrate de que la cuenta de servicio que usa tu función para autenticar llamadas a Cloud SQL tenga los permisos y funciones de Cloud SQL adecuados.
    • La cuenta de servicio para tu servicio necesita una de las siguientes funciones de IAM:
      • Cloud SQL Client (opción recomendada)
      • Cloud SQL Editor
      • Cloud SQL Admin
      O bien, puedes asignar los siguientes permisos de IAM de forma manual:
      • cloudsql.instances.connect
      • cloudsql.instances.get
      Para obtener instrucciones detalladas sobre cómo agregar funciones de IAM a una cuenta de servicio, consulta la sección sobre cómo asignar funciones a cuentas de servicio.

    De forma predeterminada, la app autorizará las conexiones mediante la cuenta de servicio de Cloud Functions. La cuenta de servicio tiene el formato service-PROJECT_NUMBER@gcf-admin-robot.iam.gserviceaccount.com.

    Si la cuenta de servicio de autorización pertenece a un proyecto distinto al de la instancia de Cloud SQL, se deberán agregar los permisos de IAM y la API de Administrador de Cloud SQL para ambos proyectos.

IP privada

El conector de acceso a VPC sin servidores controla la comunicación con la red de VPC. Para conectarte directamente con una IP privada, debes hacer lo siguiente:

  1. Asegúrate de que la instancia de Cloud SQL que creaste antes tenga una dirección IP privada. Si necesitas agregar una, consulta la página sobre cómo configurar IP privadas para obtener instrucciones.
  2. Crea un conector de Acceso a VPC sin servidores en la misma red de VPC en la que se encuentra tu instancia de Cloud SQL.
  3. El conector debe estar en el mismo proyecto y la misma región que los recursos que lo usan, pero puede enviar tráfico a recursos de regiones diferentes.

    El acceso a VPC sin servidores admite la comunicación con las redes de VPC conectadas a través de Cloud VPN y el intercambio de tráfico entre redes de VPC.

    El acceso a VPC sin servidores no admite redes heredadas ni VPC compartida.

  4. Configura Cloud Functions para usar el conector.
  5. Conéctate mediante la IP privada y el puerto 3306 de tu instancia.

Conéctate a Cloud SQL

Después de configurar Cloud Functions, puedes conectarte a la instancia de Cloud SQL. Cloud Functions proporciona un mecanismo que se conecta mediante el proxy de Cloud SQL.

IP pública (opción predeterminada)

Conéctate con sockets Unix

Una vez que el servicio esté configurado de forma correcta, puedes conectarlo al socket de dominio Unix de la instancia de Cloud SQL con este formato: /cloudsql/INSTANCE_CONNECTION_NAME.

Estas conexiones se encriptan de forma automática sin ninguna configuración adicional. Las muestras de código que aparecen a continuación son extractos de ejemplos más completos que aparecen en el sitio de GitHub. Haz clic en View on GitHub para obtener más información.

Python

Para ver este fragmento en el contexto de una aplicación web, consulta el archivo README en GitHub.

# Remember - storing secrets in plaintext is potentially unsafe. Consider using
# something like https://cloud.google.com/secret-manager/docs/overview to help keep
# secrets secret.
db_user = os.environ["DB_USER"]
db_pass = os.environ["DB_PASS"]
db_name = os.environ["DB_NAME"]
db_socket_dir = os.environ.get("DB_SOCKET_DIR", "/cloudsql")
cloud_sql_connection_name = os.environ["CLOUD_SQL_CONNECTION_NAME"]

pool = sqlalchemy.create_engine(
    # Equivalent URL:
    # mysql+pymysql://<db_user>:<db_pass>@/<db_name>?unix_socket=<socket_path>/<cloud_sql_instance_name>
    sqlalchemy.engine.url.URL(
        drivername="mysql+pymysql",
        username=db_user,  # e.g. "my-database-user"
        password=db_pass,  # e.g. "my-database-password"
        database=db_name,  # e.g. "my-database-name"
        query={
            "unix_socket": "{}/{}".format(
                db_socket_dir,  # e.g. "/cloudsql"
                cloud_sql_connection_name)  # i.e "<PROJECT-NAME>:<INSTANCE-REGION>:<INSTANCE-NAME>"
        }
    ),
    # ... Specify additional properties here.

)

Java

Para ver este fragmento en el contexto de una aplicación web, consulta el archivo README en GitHub.

// The configuration object specifies behaviors for the connection pool.
HikariConfig config = new HikariConfig();

// Configure which instance and what database user to connect with.
config.setJdbcUrl(String.format("jdbc:mysql:///%s", DB_NAME));
config.setUsername(DB_USER); // e.g. "root", "postgres"
config.setPassword(DB_PASS); // e.g. "my-password"

// For Java users, the Cloud SQL JDBC Socket Factory can provide authenticated connections.
// See https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory for details.
config.addDataSourceProperty("socketFactory", "com.google.cloud.sql.mysql.SocketFactory");
config.addDataSourceProperty("cloudSqlInstance", CLOUD_SQL_CONNECTION_NAME);

// ... Specify additional connection properties here.
// ...

// Initialize the connection pool using the configuration object.
DataSource pool = new HikariDataSource(config);

Node.js

Para ver este fragmento en el contexto de una aplicación web, consulta el archivo README en GitHub.

const createUnixSocketPool = async (config) => {
  const dbSocketPath = process.env.DB_SOCKET_PATH || "/cloudsql"

  // Establish a connection to the database
  return await mysql.createPool({
    user: process.env.DB_USER, // e.g. 'my-db-user'
    password: process.env.DB_PASS, // e.g. 'my-db-password'
    database: process.env.DB_NAME, // e.g. 'my-database'
    // If connecting via unix domain socket, specify the path
    socketPath: `${dbSocketPath}/${process.env.INSTANCE_CONNECTION_NAME}`,
    // Specify additional properties here.
    ...config
  });
}

Go

Para ver este fragmento en el contexto de una aplicación web, consulta el archivo README en GitHub.

var (
	dbUser                 = mustGetenv("DB_USER")
	dbPwd                  = mustGetenv("DB_PASS")
	instanceConnectionName = mustGetenv("INSTANCE_CONNECTION_NAME")
	dbName                 = mustGetenv("DB_NAME")
)

socketDir, isSet := os.LookupEnv("DB_SOCKET_DIR")
if !isSet {
	socketDir = "/cloudsql"
}

var dbURI string
dbURI = fmt.Sprintf("%s:%s@unix(/%s/%s)/%s?parseTime=true", dbUser, dbPwd, socketDir, instanceConnectionName, dbName)

// dbPool is the pool of database connections.
dbPool, err := sql.Open("mysql", dbURI)
if err != nil {
	return nil, fmt.Errorf("sql.Open: %v", err)
}

// ...

return dbPool, nil

IP privada

Conéctate con TCP

Conéctate directamente con la dirección IP privada y el puerto 3306 de tu instancia.

Prácticas recomendadas y más información

Puedes usar el proxy de Cloud SQL cuando pruebes tu aplicación de forma local. Consulta Inicio rápido para usar el proxy para pruebas locales si quieres obtener instrucciones detalladas.

Grupos de conexiones

Las conexiones a bases de datos subyacentes pueden caerse debido al propio servidor de la base de datos o a la infraestructura subyacente a Cloud Functions. Te recomendamos usar una biblioteca cliente que admita grupos de conexiones que vuelvan a establecer de forma automática las conexiones de clientes que no funcionan. Además, te recomendamos que uses un grupo de conexiones de alcance global, ya que esto aumenta la probabilidad de que la función vuelva a usar la misma conexión para las invocaciones posteriores y cierra la conexión de forma natural cuando se expulsa la instancia (reducción del ajuste de escala automático). Para obtener ejemplos más detallados sobre cómo usar los grupos de conexiones, consulta Administra conexiones de bases de datos.

Límites de conexión

Cloud SQL impone un límite máximo en las conexiones simultáneas. Estos límites pueden variar según el motor de base de datos elegido (consulta Cuotas y límites de Cloud SQL). Cuando se usa un grupo de conexiones, es importante configurar la cantidad máxima de conexiones en 1.
  1. Cloud Functions limita las ejecuciones simultáneas a 1 por instancia. Esto significa que una instancia de una función jamás procesará dos solicitudes al mismo tiempo. En la mayoría de los casos, solo se necesita una conexión de base de datos.
Siempre que sea posible, asegúrate de inicializar un grupo de conexiones solo para las funciones que necesiten usarlo. Si una función implementada inicializa un grupo de conexiones que no necesita, podría crear conexiones que no se usan y que generan costos. Para obtener más detalles sobre cómo funcionan las variables globales en Cloud Functions, consulta Sugerencias. Si deseas obtener ejemplos más detallados sobre cómo limitar la cantidad de conexiones, consulta Administra las conexiones de bases de datos.

Límites de cuota de la API

Cloud Functions proporciona un mecanismo que se conecta mediante el proxy de Cloud SQL, que usa la API de Administrador de Cloud SQL. Los límites de cuota de la API se aplican al proxy de Cloud SQL.