Se connecter depuis Cloud Run Functions

Cette page contient des informations et des exemples de connexion à une instance Cloud SQL à partir d'un service s'exécutant dans les fonctions Cloud Run.

Pour obtenir des instructions détaillées sur l'exécution d'un exemple d'application Web des fonctions Cloud Run connectée à Cloud SQL, consultez la section Démarrage rapide pour la connexion à partir des fonctions Cloud Run.

Cloud SQL est un service de base de données entièrement géré qui vous aide à configurer, maintenir, gérer et administrer vos bases de données relationnelles dans le cloud.

L'outil fonctions Cloud Run est une solution de calcul légère permettant aux développeurs de créer des fonctions autonomes à usage unique qui répondent aux événements Cloud, sans avoir à gérer de serveur ni d'environnement d'exécution.

Configurer une instance Cloud SQL

  1. Activez l'API Cloud SQL Admin dans le projet Google Cloud à partir duquel vous vous connectez, si ce n'est pas déjà fait :

    Enable the API

  2. Créez une instance Cloud SQL pour PostgreSQL. Nous vous recommandons de choisir un emplacement d'instance Cloud SQL qui soit dans la même région que votre service Cloud Run, afin d'améliorer la latence, d'éviter certains coûts de mise en réseau et de réduire les risques de défaillance interrégionale.

    Par défaut, Cloud SQL attribue une adresse IP publique à une nouvelle instance. Vous avez également la possibilité d'attribuer une adresse IP privée. Pour en savoir plus sur les options de connectivité disponibles pour ces deux types d'adresses IP, consultez la page Présentation du processus de connexion.

Configurer Cloud Run Functions

La procédure à suivre pour configurer la solution fonctions Cloud Run dépend du type d'adresse IP que vous avez attribué à votre instance Cloud SQL.

Pour configurer les fonctions Cloud Run afin d'activer les connexions à une instance Cloud SQL, procédez comme suit :

  • Vérifiez que l'instance créée ci-dessus possède une adresse IP publique. Vous pouvez le vérifier sur la page Présentation de l'instance dans la console Google Cloud. Si vous devez ajouter une adresse IP publique, consultez la section Configurer une adresse IP publique.
  • Obtenez le INSTANCE_CONNECTION_NAME de l'instance. Cette valeur est disponible :
    • Sur la page Présentation de l'instance, dans la console Google Cloud, ou
    • En exécutant la commande suivante : gcloud sql instances describe [INSTANCE_NAME]
  • Configurez le compte de service pour votre fonction. Si le compte de service d'autorisation appartient à un projet différent de l'instance Cloud SQL, activez l'API Cloud SQL Admin et ajoutez les autorisations IAM répertoriées ci-dessous pour les deux projets. Vérifiez que le compte de service dispose des rôles et autorisations Cloud SQL appropriés pour se connecter à Cloud SQL.
    • Pour se connecter à Cloud SQL, le compte de service doit bénéficier de l'un des rôles IAM suivants :
      • Cloud SQL Client (rôle à privilégier)
      • Cloud SQL Editor
      • Cloud SQL Admin
      Vous pouvez également attribuer manuellement les autorisations IAM suivantes :
      • cloudsql.instances.connect
      • cloudsql.instances.get
  • Si vous utilisez des fonctions Cloud Run et non des fonctions Cloud Run (1re génération), les éléments suivants sont obligatoires (voir également la section Configurer Cloud Run) :
    1. Initialisez votre fonction.
      Lorsque vous commencez à créer une fonction Cloud Run dans la console Google Cloud, le service Cloud Run sous-jacent n'a pas encore été créé. Vous ne pouvez pas configurer une connexion Cloud SQL tant que ce service n'est pas créé (en déployant la fonction Cloud Run).
    2. Dans la console Google Cloud, dans l'angle supérieur droit de la page Informations sur la fonction, sous Fourni par Cloud Run, cliquez sur le lien pour accéder au cloud sous-jacent.
    3. Sur la page Détails du service de Cloud Run, sélectionnez l'onglet Modifier et déployer la nouvelle révision.
    4. Suivez les étapes standards (comme pour tout changement de configuration) afin de définir une nouvelle configuration pour une connexion Cloud SQL.
      Cela crée une révision Cloud Run, après quoi les révisions suivantes reçoivent automatiquement cette connexion Cloud SQL, sauf si vous la modifiez explicitement.

Si le compte de service d'autorisation appartient à un projet différent de celui contenant l'instance Cloud SQL, procédez comme suit :

  • Dans les deux projets, activez l'API Cloud SQL Admin.
  • Pour le compte de service du projet contenant l'instance Cloud SQL, ajoutez les autorisations IAM.
Un connecteur d'accès au VPC sans serveur utilise des adresses IP privées pour gérer la communication avec votre réseau VPC. Pour vous connecter directement avec des adresses IP privées, procédez comme suit :
  1. Assurez-vous que l'instance Cloud SQL créée précédemment possède une adresse IP privée. Si vous devez en ajouter une, consultez la page Configurer une adresse IP privée pour savoir comment procéder.
  2. Créez un connecteur d'Accès au VPC sans serveur dans le même réseau VPC que votre instance Cloud SQL. Veuillez noter les conditions suivantes :
    • À moins que vous n'utilisiez le VPC partagé, votre connecteur doit se trouver dans le même projet et la même région que la ressource qui l'utilise, mais il peut envoyer du trafic à des ressources se trouvant dans d'autres régions.
    • L'accès au VPC sans serveur accepte la communication avec les réseaux VPC connectés à l'aide de Cloud VPN et de l'appairage de réseaux VPC.
    • L'accès au VPC sans serveur n'est pas compatible avec les anciens réseaux.
  3. Configurez les fonctions Cloud Run de façon à utiliser le connecteur.
  4. Connectez-vous avec l'adresse IP privée et le port 5432 de votre instance.

Se connecter à Cloud SQL

Une fois que vous avez configuré les fonctions Cloud Run, vous pouvez vous connecter à votre instance Cloud SQL.

Pour les chemins d'accès d'adresses IP publiques, la solutions de fonctions Cloud Run assure le chiffrement et se connecte à l'aide du proxy d'authentification Cloud SQL de deux manières :

Se connecter avec des sockets Unix

Une fois votre service correctement configuré, vous pouvez le connecter au socket de domaine Unix de votre instance Cloud SQL accessible via le système de fichiers de l'environnement au chemin d'accès suivant : /cloudsql/INSTANCE_CONNECTION_NAME.

INSTANCE_CONNECTION_NAME utilise le format project:region:instance-id. Pour le trouver, accédez à la page Présentation de votre instance dans la console Google Cloud ou exécutez la commande suivante :

gcloud sql instances describe [INSTANCE_NAME]

Ces connexions sont automatiquement chiffrées sans configuration supplémentaire.

Les exemples de code présentés ci-dessous sont extraits d'exemples plus complets du site GitHub. Cliquez sur View on GitHub (Afficher sur GitHub) pour plus d'informations.

Pour afficher cet extrait dans le contexte d'une application Web, consultez le fichier README sur GitHub.

import os

import sqlalchemy


def connect_unix_socket() -> sqlalchemy.engine.base.Engine:
    """Initializes a Unix socket connection pool for a Cloud SQL instance of Postgres."""
    # Note: Saving credentials in environment variables is convenient, but not
    # secure - consider a more secure solution such as
    # Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
    # keep secrets safe.
    db_user = os.environ["DB_USER"]  # e.g. 'my-database-user'
    db_pass = os.environ["DB_PASS"]  # e.g. 'my-database-password'
    db_name = os.environ["DB_NAME"]  # e.g. 'my-database'
    unix_socket_path = os.environ[
        "INSTANCE_UNIX_SOCKET"
    ]  # e.g. '/cloudsql/project:region:instance'

    pool = sqlalchemy.create_engine(
        # Equivalent URL:
        # postgresql+pg8000://<db_user>:<db_pass>@/<db_name>
        #                         ?unix_sock=<INSTANCE_UNIX_SOCKET>/.s.PGSQL.5432
        # Note: Some drivers require the `unix_sock` query parameter to use a different key.
        # For example, 'psycopg2' uses the path set to `host` in order to connect successfully.
        sqlalchemy.engine.url.URL.create(
            drivername="postgresql+pg8000",
            username=db_user,
            password=db_pass,
            database=db_name,
            query={"unix_sock": f"{unix_socket_path}/.s.PGSQL.5432"},
        ),
        # ...
    )
    return pool

Pour afficher cet extrait dans le contexte d'une application Web, consultez le fichier README sur GitHub.

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import javax.sql.DataSource;

public class ConnectorConnectionPoolFactory extends ConnectionPoolFactory {

  // Note: Saving credentials in environment variables is convenient, but not
  // secure - consider a more secure solution such as
  // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
  // keep secrets safe.
  private static final String INSTANCE_CONNECTION_NAME =
      System.getenv("INSTANCE_CONNECTION_NAME");
  private static final String INSTANCE_UNIX_SOCKET = System.getenv("INSTANCE_UNIX_SOCKET");
  private static final String DB_USER = System.getenv("DB_USER");
  private static final String DB_PASS = System.getenv("DB_PASS");
  private static final String DB_NAME = System.getenv("DB_NAME");

  public static DataSource createConnectionPool() {
    // The configuration object specifies behaviors for the connection pool.
    HikariConfig config = new HikariConfig();

    // The following URL is equivalent to setting the config options below:
    // jdbc:postgresql:///<DB_NAME>?cloudSqlInstance=<INSTANCE_CONNECTION_NAME>&
    // socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=<DB_USER>&password=<DB_PASS>
    // See the link below for more info on building a JDBC URL for the Cloud SQL JDBC Socket Factory
    // https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory#creating-the-jdbc-url

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

    config.addDataSourceProperty("socketFactory", "com.google.cloud.sql.postgres.SocketFactory");
    config.addDataSourceProperty("cloudSqlInstance", INSTANCE_CONNECTION_NAME);

    // Unix sockets are not natively supported in Java, so it is necessary to use the Cloud SQL
    // Java Connector to connect. When setting INSTANCE_UNIX_SOCKET, the connector will 
    // call an external package that will enable Unix socket connections.
    // Note: For Java users, the Cloud SQL Java Connector can provide authenticated connections
    // which is usually preferable to using the Cloud SQL Proxy with Unix sockets.
    // See https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory for details.
    if (INSTANCE_UNIX_SOCKET != null) {
      config.addDataSourceProperty("unixSocketPath", INSTANCE_UNIX_SOCKET);
    }



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

    // Initialize the connection pool using the configuration object.
    return new HikariDataSource(config);
  }
}

Pour afficher cet extrait dans le contexte d'une application Web, consultez le fichier README sur GitHub.

const Knex = require('knex');

// createUnixSocketPool initializes a Unix socket connection pool for
// a Cloud SQL instance of Postgres.
const createUnixSocketPool = async config => {
  // Note: Saving credentials in environment variables is convenient, but not
  // secure - consider a more secure solution such as
  // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
  // keep secrets safe.
  return Knex({
    client: 'pg',
    connection: {
      user: process.env.DB_USER, // e.g. 'my-user'
      password: process.env.DB_PASS, // e.g. 'my-user-password'
      database: process.env.DB_NAME, // e.g. 'my-database'
      host: process.env.INSTANCE_UNIX_SOCKET, // e.g. '/cloudsql/project:region:instance'
    },
    // ... Specify additional properties here.
    ...config,
  });
};

Pour afficher cet extrait dans le contexte d'une application Web, consultez le fichier README sur GitHub.

package cloudsql

import (
	"database/sql"
	"fmt"
	"log"
	"os"

	// Note: If connecting using the App Engine Flex Go runtime, use
	// "github.com/jackc/pgx/stdlib" instead, since v5 requires
	// Go modules which are not supported by App Engine Flex.
	_ "github.com/jackc/pgx/v5/stdlib"
)

// connectUnixSocket initializes a Unix socket connection pool for
// a Cloud SQL instance of Postgres.
func connectUnixSocket() (*sql.DB, error) {
	mustGetenv := func(k string) string {
		v := os.Getenv(k)
		if v == "" {
			log.Fatalf("Fatal Error in connect_unix.go: %s environment variable not set.\n", k)
		}
		return v
	}
	// Note: Saving credentials in environment variables is convenient, but not
	// secure - consider a more secure solution such as
	// Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
	// keep secrets safe.
	var (
		dbUser         = mustGetenv("DB_USER")              // e.g. 'my-db-user'
		dbPwd          = mustGetenv("DB_PASS")              // e.g. 'my-db-password'
		unixSocketPath = mustGetenv("INSTANCE_UNIX_SOCKET") // e.g. '/cloudsql/project:region:instance'
		dbName         = mustGetenv("DB_NAME")              // e.g. 'my-database'
	)

	dbURI := fmt.Sprintf("user=%s password=%s database=%s host=%s",
		dbUser, dbPwd, dbName, unixSocketPath)

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

	// ...

	return dbPool, nil
}

Pour afficher cet extrait dans le contexte d'une application Web, consultez le fichier README sur GitHub.

namespace Google\Cloud\Samples\CloudSQL\Postgres;

use PDO;
use PDOException;
use RuntimeException;
use TypeError;

class DatabaseUnix
{
    public static function initUnixDatabaseConnection(): PDO
    {
        try {
            // Note: Saving credentials in environment variables is convenient, but not
            // secure - consider a more secure solution such as
            // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
            // keep secrets safe.
            $username = getenv('DB_USER'); // e.g. 'your_db_user'
            $password = getenv('DB_PASS'); // e.g. 'your_db_password'
            $dbName = getenv('DB_NAME'); // e.g. 'your_db_name'
            $instanceUnixSocket = getenv('INSTANCE_UNIX_SOCKET'); // e.g. '/cloudsql/project:region:instance'

            // Connect using UNIX sockets
            $dsn = sprintf(
                'pgsql:dbname=%s;host=%s',
                $dbName,
                $instanceUnixSocket
            );

            // Connect to the database.
            $conn = new PDO(
                $dsn,
                $username,
                $password,
                # ...
            );
        } catch (TypeError $e) {
            throw new RuntimeException(
                sprintf(
                    'Invalid or missing configuration! Make sure you have set ' .
                        '$username, $password, $dbName, ' .
                        'and $instanceUnixSocket (for UNIX socket mode). ' .
                        'The PHP error was %s',
                    $e->getMessage()
                ),
                (int) $e->getCode(),
                $e
            );
        } catch (PDOException $e) {
            throw new RuntimeException(
                sprintf(
                    'Could not connect to the Cloud SQL Database. Check that ' .
                        'your username and password are correct, that the Cloud SQL ' .
                        'proxy is running, and that the database exists and is ready ' .
                        'for use. For more assistance, refer to %s. The PDO error was %s',
                    'https://cloud.google.com/sql/docs/postgres/connect-external-app',
                    $e->getMessage()
                ),
                (int) $e->getCode(),
                $e
            );
        }

        return $conn;
    }
}

Se connecter avec des connecteurs Cloud SQL

Les connecteurs Cloud SQL sont des bibliothèques propres aux langages de programmation qui fournissent le chiffrement et l'autorisation basée sur IAM lors de la connexion à une instance Cloud SQL.

Pour afficher cet extrait dans le contexte d'une application Web, consultez le fichier README sur GitHub.

import os

from google.cloud.sql.connector import Connector, IPTypes
import pg8000

import sqlalchemy


def connect_with_connector() -> sqlalchemy.engine.base.Engine:
    """
    Initializes a connection pool for a Cloud SQL instance of Postgres.

    Uses the Cloud SQL Python Connector package.
    """
    # Note: Saving credentials in environment variables is convenient, but not
    # secure - consider a more secure solution such as
    # Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
    # keep secrets safe.

    instance_connection_name = os.environ[
        "INSTANCE_CONNECTION_NAME"
    ]  # e.g. 'project:region:instance'
    db_user = os.environ["DB_USER"]  # e.g. 'my-db-user'
    db_pass = os.environ["DB_PASS"]  # e.g. 'my-db-password'
    db_name = os.environ["DB_NAME"]  # e.g. 'my-database'

    ip_type = IPTypes.PRIVATE if os.environ.get("PRIVATE_IP") else IPTypes.PUBLIC

    # initialize Cloud SQL Python Connector object
    connector = Connector()

    def getconn() -> pg8000.dbapi.Connection:
        conn: pg8000.dbapi.Connection = connector.connect(
            instance_connection_name,
            "pg8000",
            user=db_user,
            password=db_pass,
            db=db_name,
            ip_type=ip_type,
        )
        return conn

    # The Cloud SQL Python Connector can be used with SQLAlchemy
    # using the 'creator' argument to 'create_engine'
    pool = sqlalchemy.create_engine(
        "postgresql+pg8000://",
        creator=getconn,
        # ...
    )
    return pool

Pour afficher cet extrait dans le contexte d'une application Web, consultez le fichier README sur GitHub.

Remarque :

  • CLOUD_SQL_CONNECTION_NAME doit être représenté sous la forme <MY-PROJECT>:<INSTANCE-REGION>:<INSTANCE-NAME>.
  • Pour en savoir plus sur les exigences de version Socket Factory des sockets JDBC pour le fichier pom.xml, cliquez ici.

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import javax.sql.DataSource;

public class ConnectorConnectionPoolFactory extends ConnectionPoolFactory {

  // Note: Saving credentials in environment variables is convenient, but not
  // secure - consider a more secure solution such as
  // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
  // keep secrets safe.
  private static final String INSTANCE_CONNECTION_NAME =
      System.getenv("INSTANCE_CONNECTION_NAME");
  private static final String INSTANCE_UNIX_SOCKET = System.getenv("INSTANCE_UNIX_SOCKET");
  private static final String DB_USER = System.getenv("DB_USER");
  private static final String DB_PASS = System.getenv("DB_PASS");
  private static final String DB_NAME = System.getenv("DB_NAME");

  public static DataSource createConnectionPool() {
    // The configuration object specifies behaviors for the connection pool.
    HikariConfig config = new HikariConfig();

    // The following URL is equivalent to setting the config options below:
    // jdbc:postgresql:///<DB_NAME>?cloudSqlInstance=<INSTANCE_CONNECTION_NAME>&
    // socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=<DB_USER>&password=<DB_PASS>
    // See the link below for more info on building a JDBC URL for the Cloud SQL JDBC Socket Factory
    // https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory#creating-the-jdbc-url

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

    config.addDataSourceProperty("socketFactory", "com.google.cloud.sql.postgres.SocketFactory");
    config.addDataSourceProperty("cloudSqlInstance", INSTANCE_CONNECTION_NAME);


    // The ipTypes argument can be used to specify a comma delimited list of preferred IP types
    // for connecting to a Cloud SQL instance. The argument ipTypes=PRIVATE will force the
    // SocketFactory to connect with an instance's associated private IP.
    config.addDataSourceProperty("ipTypes", "PUBLIC,PRIVATE");


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

    // Initialize the connection pool using the configuration object.
    return new HikariDataSource(config);
  }
}

Pour afficher cet extrait dans le contexte d'une application Web, consultez le fichier README sur GitHub.

package cloudsql

import (
	"context"
	"database/sql"
	"fmt"
	"log"
	"net"
	"os"

	"cloud.google.com/go/cloudsqlconn"
	"github.com/jackc/pgx/v5"
	"github.com/jackc/pgx/v5/stdlib"
)

func connectWithConnector() (*sql.DB, error) {
	mustGetenv := func(k string) string {
		v := os.Getenv(k)
		if v == "" {
			log.Fatalf("Fatal Error in connect_connector.go: %s environment variable not set.\n", k)
		}
		return v
	}
	// Note: Saving credentials in environment variables is convenient, but not
	// secure - consider a more secure solution such as
	// Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
	// keep passwords and other secrets safe.
	var (
		dbUser                 = mustGetenv("DB_USER")                  // e.g. 'my-db-user'
		dbPwd                  = mustGetenv("DB_PASS")                  // e.g. 'my-db-password'
		dbName                 = mustGetenv("DB_NAME")                  // e.g. 'my-database'
		instanceConnectionName = mustGetenv("INSTANCE_CONNECTION_NAME") // e.g. 'project:region:instance'
		usePrivate             = os.Getenv("PRIVATE_IP")
	)

	dsn := fmt.Sprintf("user=%s password=%s database=%s", dbUser, dbPwd, dbName)
	config, err := pgx.ParseConfig(dsn)
	if err != nil {
		return nil, err
	}
	var opts []cloudsqlconn.Option
	if usePrivate != "" {
		opts = append(opts, cloudsqlconn.WithDefaultDialOptions(cloudsqlconn.WithPrivateIP()))
	}
	d, err := cloudsqlconn.NewDialer(context.Background(), opts...)
	if err != nil {
		return nil, err
	}
	// Use the Cloud SQL connector to handle connecting to the instance.
	// This approach does *NOT* require the Cloud SQL proxy.
	config.DialFunc = func(ctx context.Context, network, instance string) (net.Conn, error) {
		return d.Dial(ctx, instanceConnectionName)
	}
	dbURI := stdlib.RegisterConnConfig(config)
	dbPool, err := sql.Open("pgx", dbURI)
	if err != nil {
		return nil, fmt.Errorf("sql.Open: %w", err)
	}
	return dbPool, nil
}

Pour les chemins d'accès des adresses IP privées, votre application se connecte directement à votre instance via un réseau VPC. Cette méthode utilise TCP pour se connecter directement à l'instance Cloud SQL sans utiliser le proxy d'authentification Cloud SQL.

Se connecter avec TCP

Connectez-vous en utilisant l'adresse IP privée de votre instance Cloud SQL en tant qu'hôte et le port 5432.

Pour afficher cet extrait dans le contexte d'une application Web, consultez le fichier README sur GitHub.

import os
import ssl

import sqlalchemy


def connect_tcp_socket() -> sqlalchemy.engine.base.Engine:
    """Initializes a TCP connection pool for a Cloud SQL instance of Postgres."""
    # Note: Saving credentials in environment variables is convenient, but not
    # secure - consider a more secure solution such as
    # Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
    # keep secrets safe.
    db_host = os.environ[
        "INSTANCE_HOST"
    ]  # e.g. '127.0.0.1' ('172.17.0.1' if deployed to GAE Flex)
    db_user = os.environ["DB_USER"]  # e.g. 'my-db-user'
    db_pass = os.environ["DB_PASS"]  # e.g. 'my-db-password'
    db_name = os.environ["DB_NAME"]  # e.g. 'my-database'
    db_port = os.environ["DB_PORT"]  # e.g. 5432

    pool = sqlalchemy.create_engine(
        # Equivalent URL:
        # postgresql+pg8000://<db_user>:<db_pass>@<db_host>:<db_port>/<db_name>
        sqlalchemy.engine.url.URL.create(
            drivername="postgresql+pg8000",
            username=db_user,
            password=db_pass,
            host=db_host,
            port=db_port,
            database=db_name,
        ),
        # ...
    )
    return pool

Pour afficher cet extrait dans le contexte d'une application Web, consultez le fichier README sur GitHub.

Remarque :

  • CLOUD_SQL_CONNECTION_NAME doit être représenté sous la forme <MY-PROJECT>:<INSTANCE-REGION>:<INSTANCE-NAME>.
  • L'utilisation de l'argument ipTypes=PRIVATE force la connexion de SocketFactory à l'adresse IP privée associée à une instance.
  • Pour en savoir plus sur les exigences de version Socket Factory des sockets JDBC pour le fichier pom.xml, cliquez ici.


import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import javax.sql.DataSource;

public class TcpConnectionPoolFactory extends ConnectionPoolFactory {

  // Note: Saving credentials in environment variables is convenient, but not
  // secure - consider a more secure solution such as
  // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
  // keep secrets safe.
  private static final String DB_USER = System.getenv("DB_USER");
  private static final String DB_PASS = System.getenv("DB_PASS");
  private static final String DB_NAME = System.getenv("DB_NAME");

  private static final String INSTANCE_HOST = System.getenv("INSTANCE_HOST");
  private static final String DB_PORT = System.getenv("DB_PORT");


  public static DataSource createConnectionPool() {
    // The configuration object specifies behaviors for the connection pool.
    HikariConfig config = new HikariConfig();

    // The following URL is equivalent to setting the config options below:
    // jdbc:postgresql://<INSTANCE_HOST>:<DB_PORT>/<DB_NAME>?user=<DB_USER>&password=<DB_PASS>
    // See the link below for more info on building a JDBC URL for the Cloud SQL JDBC Socket Factory
    // https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory#creating-the-jdbc-url

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


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

    // Initialize the connection pool using the configuration object.
    return new HikariDataSource(config);
  }
}

Pour afficher cet extrait dans le contexte d'une application Web, consultez le fichier README sur GitHub.

const Knex = require('knex');
const fs = require('fs');

// createTcpPool initializes a TCP connection pool for a Cloud SQL
// instance of Postgres.
const createTcpPool = async config => {
  // Note: Saving credentials in environment variables is convenient, but not
  // secure - consider a more secure solution such as
  // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
  // keep secrets safe.
  const dbConfig = {
    client: 'pg',
    connection: {
      host: process.env.INSTANCE_HOST, // e.g. '127.0.0.1'
      port: process.env.DB_PORT, // e.g. '5432'
      user: process.env.DB_USER, // e.g. 'my-user'
      password: process.env.DB_PASS, // e.g. 'my-user-password'
      database: process.env.DB_NAME, // e.g. 'my-database'
    },
    // ... Specify additional properties here.
    ...config,
  };
  // Establish a connection to the database.
  return Knex(dbConfig);
};

Pour afficher cet extrait dans le contexte d'une application Web, consultez le fichier README sur GitHub.

package cloudsql

import (
	"database/sql"
	"fmt"
	"log"
	"os"

	// Note: If connecting using the App Engine Flex Go runtime, use
	// "github.com/jackc/pgx/stdlib" instead, since v5 requires
	// Go modules which are not supported by App Engine Flex.
	_ "github.com/jackc/pgx/v5/stdlib"
)

// connectTCPSocket initializes a TCP connection pool for a Cloud SQL
// instance of Postgres.
func connectTCPSocket() (*sql.DB, error) {
	mustGetenv := func(k string) string {
		v := os.Getenv(k)
		if v == "" {
			log.Fatalf("Fatal Error in connect_tcp.go: %s environment variable not set.", k)
		}
		return v
	}
	// Note: Saving credentials in environment variables is convenient, but not
	// secure - consider a more secure solution such as
	// Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
	// keep secrets safe.
	var (
		dbUser    = mustGetenv("DB_USER")       // e.g. 'my-db-user'
		dbPwd     = mustGetenv("DB_PASS")       // e.g. 'my-db-password'
		dbTCPHost = mustGetenv("INSTANCE_HOST") // e.g. '127.0.0.1' ('172.17.0.1' if deployed to GAE Flex)
		dbPort    = mustGetenv("DB_PORT")       // e.g. '5432'
		dbName    = mustGetenv("DB_NAME")       // e.g. 'my-database'
	)

	dbURI := fmt.Sprintf("host=%s user=%s password=%s port=%s database=%s",
		dbTCPHost, dbUser, dbPwd, dbPort, dbName)


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

	// ...

	return dbPool, nil
}

Pour afficher cet extrait dans le contexte d'une application Web, consultez le fichier README sur GitHub.

namespace Google\Cloud\Samples\CloudSQL\Postgres;

use PDO;
use PDOException;
use RuntimeException;
use TypeError;

class DatabaseTcp
{
    public static function initTcpDatabaseConnection(): PDO
    {
        try {
            // Note: Saving credentials in environment variables is convenient, but not
            // secure - consider a more secure solution such as
            // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
            // keep secrets safe.
            $username = getenv('DB_USER'); // e.g. 'your_db_user'
            $password = getenv('DB_PASS'); // e.g. 'your_db_password'
            $dbName = getenv('DB_NAME'); // e.g. 'your_db_name'
            $instanceHost = getenv('INSTANCE_HOST'); // e.g. '127.0.0.1' ('172.17.0.1' for GAE Flex)

            // Connect using TCP
            $dsn = sprintf('pgsql:dbname=%s;host=%s', $dbName, $instanceHost);

            // Connect to the database
            $conn = new PDO(
                $dsn,
                $username,
                $password,
                # ...
            );
        } catch (TypeError $e) {
            throw new RuntimeException(
                sprintf(
                    'Invalid or missing configuration! Make sure you have set ' .
                        '$username, $password, $dbName, and $instanceHost (for TCP mode). ' .
                        'The PHP error was %s',
                    $e->getMessage()
                ),
                $e->getCode(),
                $e
            );
        } catch (PDOException $e) {
            throw new RuntimeException(
                sprintf(
                    'Could not connect to the Cloud SQL Database. Check that ' .
                        'your username and password are correct, that the Cloud SQL ' .
                        'proxy is running, and that the database exists and is ready ' .
                        'for use. For more assistance, refer to %s. The PDO error was %s',
                    'https://cloud.google.com/sql/docs/postgres/connect-external-app',
                    $e->getMessage()
                ),
                $e->getCode(),
                $e
            );
        }

        return $conn;
    }
}

Bonnes pratiques et autres informations

Vous pouvez utiliser le proxy d'authentification Cloud SQL lorsque vous testez votre application en local. Pour obtenir des instructions détaillées, consultez le guide de démarrage rapide pour l'utilisation du proxy d'authentification Cloud SQL.

Pools de connexions

Les connexions aux bases de données sous-jacentes peuvent être supprimées, soit par le serveur de base de données lui-même, soit par l'infrastructure qui sous-tend les fonctions Cloud Run. Nous vous recommandons d'utiliser une bibliothèque cliente compatible avec les pools de connexions qui restaurent automatiquement les connexions client interrompues. De plus, nous recommandons d'utiliser un pool de connexions globalement limité, car cela augmente la probabilité que votre fonction réutilise la même connexion pour les invocations ultérieures de la fonction et qu'elle ferme naturellement la connexion lorsque l'instance est évincée (autoscaling à la baisse). Pour obtenir des exemples plus détaillés d'utilisation des pools de connexions, consultez la page Gérer les connexions à la base de données.

Limites de connexion

Cloud SQL impose une limite maximale de connexions simultanées, laquelle peut varier en fonction du moteur de base de données choisi (consultez la page Quotas et limites de Cloud SQL). Il est recommandé d'utiliser une connexion avec les fonctions Cloud Run, mais il est important de définir le nombre maximal de connexions sur 1.

Lorsque cela est possible, veillez à n'initialiser un pool de connexions que pour les fonctions qui doivent accéder à votre base de données. Certains pools de connexions créent des connexions de manière préemptive, ce qui peut consommer des ressources excédentaires et être comptabilisé dans vos limites de connexion. Pour cette raison, il est recommandé d'utiliser l'initialisation différée pour retarder la création d'un pool de connexions jusqu'à ce que cela soit nécessaire et n'inclure le pool de connexions que dans les fonctions où il est utilisé.

Pour obtenir des exemples plus détaillés de limitation du nombre de connexions, consultez la page Gérer les connexions à la base de données.

Limites de quota d'API

La solution de fonctions Cloud Run fournit un mécanisme permettant de se connecter à l'aide du proxy d'authentification Cloud SQL, qui utilise l'API Cloud SQL Admin. Les limites de quota d'API s'appliquent au proxy d'authentification Cloud SQL. Le quota de l'API Cloud SQL Admin utilisé correspond approximativement au double du nombre d'instances Cloud SQL configurées ou au nombre total de fonctions déployées. Vous pouvez définir le nombre maximal d'appels simultanés pour modifier le quota d'API que vous prévoyez d'utiliser. La solution de fonctions Cloud Run impose également des limitations de débit sur le nombre d'appels d'API autorisés par tranche de 100 secondes.

Étape suivante