Connect using the AlloyDB Language Connectors

The AlloyDB Language Connectors are libraries that provide a simplified process to establish secure connections to your cluster use the following:

  • Automated mTLS Connections
  • Identity and Access Management (IAM)-based authorization support
  • Automated IAM authentication

AlloyDB Language Connectors can't provide a network path to a AlloyDB cluster, if a network path isn't already present.

For more information about AlloyDB Language Connectors, see AlloyDB Language Connectors overview.

This page discusses the following AlloyDB Language Connectors:

  • The AlloyDB Java Connector
  • The AlloyDB Go Connector
  • The AlloyDB Python Connector

Before you begin

  1. Enable the AlloyDB Admin API.

    Enable the API

  2. Create an AlloyDB instance and configure the default user.

    For more information about creating an instance, see Create a primary instance.

    For more information about user roles, see Predefined AlloyDB IAM roles.

  3. Configure the following roles and permissions required to connect to an AlloyDB instance:

    • roles/alloydb.client
    • roles/serviceusage.serviceUsageConsumer

      For more information about which roles and permissions are required, see Manage IAM authentication.

Install the AlloyDB Language Connectors

Java

The AlloyDB Java Connector is a library that provides IAM-based authorization and encryption when connecting to an AlloyDB instance.

Installation

For Maven, you can install the AlloyDB Java Connector by adding the following to your project's pom.xml:

<!-- Add the connector with the latest version -->
<dependency>
  <groupId>com.google.cloud</groupId>
  <artifactId>alloydb-jdbc-connector</artifactId>
  <version>0.4.0</version>
</dependency>

<!-- Add the driver with the latest version -->
<dependency>
  <groupId>org.postgresql</groupId>
  <artifactId>postgresql</artifactId>
  <version>46.6.0<</version>
</dependency>

<!-- Add HikariCP with the latest version -->
<dependency>
  <groupId>com.zaxxer</groupId>
  <artifactId>HikariCP</artifactId>
  <version>5.1.0</version>
</dependency>

For Gradle, you can install the AlloyDB Java Connector by including the following in your project's gradle.build:

// Add connector with the latest version
implementation group: 'com.google.cloud.alloydb', name: 'alloydb-jdbc-connector', version: '0.4.0'

// Add driver with the latest version
implementation group: 'org.postgresql', name: 'postgresql', version: '46.6.0'

// Add HikariCP with the latest version
implementation group: 'com.zaxxer', name: 'HikariCP', version: '5.1.0'

Python (pg8000)

The AlloyDB Python Connector is a library that can be used alongside a database driver to allow users with sufficient permissions to connect to an AlloyDB database without having to manually allowlist IPs.

Installation

You can install the AlloyDB Python Connector library with pip install.

If you're using pg8000, then run the following command:

pip install "google-cloud-alloydb-connector[pg8000]" sqlalchemy

Python (asyncpg)

The AlloyDB Python Connector is a library that can be used alongside a database driver to allow users with sufficient permissions to connect to an AlloyDB database without having to manually allowlist IPs.

Installation

You can install the AlloyDB Python Connector library with pip install.

If you're using asyncpg, then run the following command:

For asyncpg, use:

pip install "google-cloud-alloydb-connector[asyncpg]" "sqlalchemy[asyncio]"

For more information about async driver usage, see Async Driver Usage.

Go (pgx)

The AlloyDB Go Connector is an AlloyDB connector designed for use with the Go language.

Installation

You can install the AlloyDB Go Connector with go get.

If you're using pgx, then run the following command:

go get github.com/jackc/pgx/v5
go get cloud.google.com/go/alloydbconn

Go (database/sql)

The AlloyDB Go Connector is an AlloyDB connector designed for use with the Go language.

Installation

You can install the AlloyDB Go Connector with go get.

If you're using database/sql, then run the following command:

go get cloud.google.com/go/alloydbconn

Configure the AlloyDB Language Connectors

Java

To use the AlloyDB Java Connector to connect to your AlloyDB cluster, configure it using the following steps.

To use this snippet in the context of a web application, view the README on GitHub.

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

public class AlloyDbJdbcConnectorDataSourceFactory {

  public static final String ALLOYDB_DB = System.getenv("ALLOYDB_DB");
  public static final String ALLOYDB_USER = System.getenv("ALLOYDB_USER");
  public static final String ALLOYDB_PASS = System.getenv("ALLOYDB_PASS");
  public static final String ALLOYDB_INSTANCE_NAME = System.getenv("ALLOYDB_INSTANCE_NAME");

  static HikariDataSource createDataSource() {
    HikariConfig config = new HikariConfig();

    config.setJdbcUrl(String.format("jdbc:postgresql:///%s", ALLOYDB_DB));
    config.setUsername(ALLOYDB_USER); // e.g., "postgres"
    config.setPassword(ALLOYDB_PASS); // e.g., "secret-password"
    config.addDataSourceProperty("socketFactory", "com.google.cloud.alloydb.SocketFactory");
    // e.g., "projects/my-project/locations/us-central1/clusters/my-cluster/instances/my-instance"
    config.addDataSourceProperty("alloydbInstanceName", ALLOYDB_INSTANCE_NAME);

    return new HikariDataSource(config);
  }
}

Use public IP

If you're using public IP to connect to your AlloyDB cluster, then include the following:

config.addDataSourceProperty("alloydbIpType", "PUBLIC");

Use Private Service Connect

If you're using Private Service Connect to connect to your AlloyDB instance, then include the following:

config.addDataSourceProperty("alloydbIpType", "PSC");

Automatic IAM authentication

By default, AlloyDB Language Connectors use built-in authentication. You can use automatic IAM authentication with the AlloyDB Java Connector. To enable, include the following:

config.addDataSourceProperty("alloydbEnableIAMAuth", "true");

Python (pg8000)

To use the AlloyDB Python Connector to connect to your AlloyDB cluster, configure the connector using the following steps, if you're using pg8000.

To use this snippet in the context of a web application, view the README on GitHub.

import pg8000
import sqlalchemy

from google.cloud.alloydb.connector import Connector


def create_sqlalchemy_engine(
    inst_uri: str,
    user: str,
    password: str,
    db: str,
    refresh_strategy: str = "background",
) -> Tuple[sqlalchemy.engine.Engine, Connector]:
    """Creates a connection pool for an AlloyDB instance and returns the pool
    and the connector. Callers are responsible for closing the pool and the
    connector.

    A sample invocation looks like:

        engine, connector = create_sqlalchemy_engine(
            inst_uri,
            user,
            password,
            db,
        )
        with engine.connect() as conn:
            time = conn.execute(sqlalchemy.text("SELECT NOW()")).fetchone()
            conn.commit()
            curr_time = time[0]
            # do something with query result
            connector.close()

    Args:
        instance_uri (str):
            The instance URI specifies the instance relative to the project,
            region, and cluster. For example:
            "projects/my-project/locations/us-central1/clusters/my-cluster/instances/my-instance"
        user (str):
            The database user name, e.g., postgres
        password (str):
            The database user's password, e.g., secret-password
        db (str):
            The name of the database, e.g., mydb
        refresh_strategy (Optional[str]):
            Refresh strategy for the AlloyDB Connector. Can be one of "lazy"
            or "background". For serverless environments use "lazy" to avoid
            errors resulting from CPU being throttled.
    """
    connector = Connector(refresh_strategy=refresh_strategy)

    def getconn() -> pg8000.dbapi.Connection:
        conn: pg8000.dbapi.Connection = connector.connect(
            inst_uri,
            "pg8000",
            user=user,
            password=password,
            db=db,
        )
        return conn

    # create SQLAlchemy connection pool
    engine = sqlalchemy.create_engine(
        "postgresql+pg8000://",
        creator=getconn,
    )
    engine.dialect.description_encoding = None
    return engine, connector

Use public IP

If you're using public IP to connect to your AlloyDB cluster, then replace your connection function the following:

  def getconn() -> pg8000.dbapi.Connection:
      conn: pg8000.dbapi.Connection = connector.connect(
          inst_uri,
          "pg8000",
          user=user,
          password=password,
          db=db,
          # use ip_type to specify public IP
          ip_type=IPTypes.PUBLIC,
      )
      return conn

Use Private Service Connect

If you're using Private Service Connect to connect to your AlloyDB instance, then include the following:

  def getconn() -> pg8000.dbapi.Connection:
      conn: pg8000.dbapi.Connection = connector.connect(
          inst_uri,
          "pg8000",
          user=user,
          password=password,
          db=db,
          # use ip_type to specify PSC
          ip_type=IPTypes.PSC,
        )
      return conn

Automatic IAM authentication

By default, AlloyDB Language Connectors use built-in authentication. You can use automatic IAM authentication with the AlloyDB Python Connector. To enable, replace your connection function with the following:

  def getconn() -> pg8000.dbapi.Connection:
      conn: pg8000.dbapi.Connection = connector.connect(
          inst_uri,
          "pg8000",
          user=user,
          password=password,
          db=db,
          # use enable_iam_auth to enable IAM authentication
          enable_iam_auth=True,
      )
      return conn

Python (asyncpg)

To use the AlloyDB Python Connector to connect to your AlloyDB cluster, configure the connector using the following steps, if you're using async.

To use this snippet in the context of a web application, view the README on GitHub.

import asyncpg
import sqlalchemy
import sqlalchemy.ext.asyncio

from google.cloud.alloydb.connector import AsyncConnector


async def create_sqlalchemy_engine(
    inst_uri: str,
    user: str,
    password: str,
    db: str,
    refresh_strategy: str = "background",
) -> Tuple[sqlalchemy.ext.asyncio.engine.AsyncEngine, AsyncConnector]:
    """Creates a connection pool for an AlloyDB instance and returns the pool
    and the connector. Callers are responsible for closing the pool and the
    connector.

    A sample invocation looks like:

        engine, connector = await create_sqlalchemy_engine(
            inst_uri,
            user,
            password,
            db,
        )
        async with engine.connect() as conn:
            time = await conn.execute(sqlalchemy.text("SELECT NOW()")).fetchone()
            curr_time = time[0]
            # do something with query result
            await connector.close()

    Args:
        instance_uri (str):
            The instance URI specifies the instance relative to the project,
            region, and cluster. For example:
            "projects/my-project/locations/us-central1/clusters/my-cluster/instances/my-instance"
        user (str):
            The database user name, e.g., postgres
        password (str):
            The database user's password, e.g., secret-password
        db (str):
            The name of the database, e.g., mydb
        refresh_strategy (Optional[str]):
            Refresh strategy for the AlloyDB Connector. Can be one of "lazy"
            or "background". For serverless environments use "lazy" to avoid
            errors resulting from CPU being throttled.
    """
    connector = AsyncConnector(refresh_strategy=refresh_strategy)

    async def getconn() -> asyncpg.Connection:
        conn: asyncpg.Connection = await connector.connect(
            inst_uri,
            "asyncpg",
            user=user,
            password=password,
            db=db,
        )
        return conn

    # create SQLAlchemy connection pool
    engine = sqlalchemy.ext.asyncio.create_async_engine(
        "postgresql+asyncpg://",
        async_creator=getconn,
        execution_options={"isolation_level": "AUTOCOMMIT"},
    )
    return engine, connector

Use public IP

If you're using public IP to connect to your AlloyDB cluster, then replace your connection function with the following:

  async def getconn() -> asyncpg.Connection:
    conn: asyncpg.Connection = await connector.connect(
        inst_uri,
        "asyncpg",
        user=user,
        password=password,
        db=db,
        # use ip_type to specify public IP
        ip_type=IPTypes.PUBLIC,
    )
    return conn

Use Private Service Connect

If you're using Private Service Connect to connect to your AlloyDB instance, then include the following:

    async def getconn() -> asyncpg.Connection:
      conn: asyncpg.Connection = await connector.connect(
          inst_uri,
          "asyncpg",
          user=user,
          password=password,
          db=db,
          # use ip_type to specify PSC
          ip_type=IPTypes.PSC,
      )
      return conn

Automatic IAM authentication

By default, AlloyDB Language Connectors use built-in authentication. You can use automatic IAM authentication with the AlloyDB Python Connector. To enable, replace your connection function with the following:

  async def getconn() -> asyncpg.Connection:
    conn: asyncpg.Connection = await connector.connect(
        inst_uri,
        "asyncpg",
        user=user,
        password=password,
        db=db,
        # use enable_iam_auth to enable IAM authentication
        enable_iam_auth=True,
    )
    return conn

Go (pgx)

To use the AlloyDB Go Connector to connect to your AlloyDB cluster, configure the connetor using the following steps, if you're using pgx.

To use this snippet in the context of a web application, view the README on GitHub.

import (
	"context"
	"fmt"
	"net"

	"cloud.google.com/go/alloydbconn"
	"github.com/jackc/pgx/v5/pgxpool"
)

// connectPgx establishes a connection to your database using pgxpool and the
// AlloyDB Go Connector (aka alloydbconn.Dialer)
//
// The function takes an instance URI, a username, a password, and a database
// name. Usage looks like this:
//
//	pool, cleanup, err := connectPgx(
//	  context.Background(),
//	  "projects/myproject/locations/us-central1/clusters/mycluster/instances/myinstance",
//	  "postgres",
//	  "secretpassword",
//	  "mydb",
//	)
//
// In addition to a *pgxpool.Pool type, the function returns a cleanup function
// that should be called when you're done with the database connection.
func connectPgx(
	ctx context.Context, instURI, user, pass, dbname string,
	opts ...alloydbconn.Option,
) (*pgxpool.Pool, func() error, error) {
	// First initialize the dialer. alloydbconn.NewDialer accepts additional
	// options to configure credentials, timeouts, etc.
	//
	// For details, see:
	// https://pkg.go.dev/cloud.google.com/go/alloydbconn#Option
	d, err := alloydbconn.NewDialer(ctx, opts...)
	if err != nil {
		noop := func() error { return nil }
		return nil, noop, fmt.Errorf("failed to init Dialer: %v", err)
	}
	// The cleanup function will stop the dialer's background refresh
	// goroutines. Call it when you're done with your database connection to
	// avoid a goroutine leak.
	cleanup := func() error { return d.Close() }

	dsn := fmt.Sprintf(
		// sslmode is disabled, because the Dialer will handle the SSL
		// connection instead.
		"user=%s password=%s dbname=%s sslmode=disable",
		user, pass, dbname,
	)

	// Prefer pgxpool for applications.
	// For more information, see:
	// https://github.com/jackc/pgx/wiki/Getting-started-with-pgx#using-a-connection-pool
	config, err := pgxpool.ParseConfig(dsn)
	if err != nil {
		return nil, cleanup, fmt.Errorf("failed to parse pgx config: %v", err)
	}

	// Tell pgx to use alloydbconn.Dialer to connect to the instance.
	config.ConnConfig.DialFunc = func(ctx context.Context, _ string, _ string) (net.Conn, error) {
		return d.Dial(ctx, instURI)
	}

	// Establish the connection.
	pool, connErr := pgxpool.NewWithConfig(ctx, config)
	if connErr != nil {
		return nil, cleanup, fmt.Errorf("failed to connect: %s", connErr)
	}

	return pool, cleanup, nil
}

Use public IP

If you're using public IP to connect to your AlloyDB cluster, then replace your d.Dial function with the following:

d.Dial(ctx, instURI, alloydbconn.WithPublicIP())

Use Private Service Connect

If you're using Private Service Connect to connect to your AlloyDB instance, then include the following:

  d.Dial(ctx, instURI, alloydbconn.WithPSC())

Automatic IAM authentication

By default, AlloyDB Language Connectors use built-in authentication. You can use automatic IAM authentication with the AlloyDB Go Connector. To enable, replace the alloydbconn.NewDialer function with the following:

d, err := alloydbconn.NewDialer(ctx, alloydbconn.WithIAMAuthN())

Go (database/sql)

To use the AlloyDB Go Connector to connect to your AlloyDB cluster, configure the connector using the following steps, if you're using database/sql.

To use this snippet in the context of a web application, view the README on GitHub.

import (
	"database/sql"
	"fmt"

	"cloud.google.com/go/alloydbconn/driver/pgxv5"
)

// connectDatabaseSQL establishes a connection to your database using the Go
// standard library's database/sql package and using the AlloyDB Go Connector
// (aka alloydbconn.Dialer)
//
// The function takes an instance URI, a username, a password, and a database
// name. Usage looks like this:
//
//	db, cleanup, err := connectDatabaseSQL(
//	  "projects/myproject/locations/us-central1/clusters/mycluster/instances/myinstance",
//	  "postgres",
//	  "secretpassword",
//	  "mydb",
//	)
//
// In addition to a *db.SQL type, the function returns a cleanup function that
// should be called when you're done with the database connection.
func connectDatabaseSQL(
	instURI, user, pass, dbname string,
) (*sql.DB, func() error, error) {
	// First, register the AlloyDB driver. Note, the driver's name is arbitrary
	// and must only match what you use below in sql.Open. Also,
	// pgxv5.RegisterDriver accepts options to configure credentials, timeouts,
	// etc.
	//
	// For details, see:
	// https://pkg.go.dev/cloud.google.com/go/alloydbconn#Option
	//
	// The cleanup function will stop the dialer's background refresh
	// goroutines. Call it when you're done with your database connection to
	// avoid a goroutine leak.
	cleanup, err := pgxv5.RegisterDriver("alloydb")
	if err != nil {
		return nil, cleanup, err
	}

	db, err := sql.Open(
		"alloydb",
		fmt.Sprintf(
			// sslmode is disabled, because the Dialer will handle the SSL
			// connection instead.
			"host=%s user=%s password=%s dbname=%s sslmode=disable",
			instURI, user, pass, dbname,
		),
	)
	return db, cleanup, err
}

Use public IP

If you're using public IP to connect to your AlloyDB cluster, then replace your RegisterDriver function with the following:

cleanup, err := pgxv5.RegisterDriver(
  "alloydb",
  alloydbconn.WithDefaultDialOptions(alloydbconn.WithPublicIP())
)

Use Private Service Connect

If you're using Private Service Connect to connect to your AlloyDB instance, then include the following:

  cleanup, err := pgxv5.RegisterDriver(
    "alloydb",
    alloydbconn.WithDefaultDialOptions(alloydbconn.WithPSC())
)

Automatic IAM authentication

By default, AlloyDB Language Connectors use built-in authentication. You can use automatic IAM authentication with the AlloyDB Go Connector. To enable, replace your RegisterDriver function with the following:

cleanup, err := pgxv4.RegisterDriver(
  "alloydb",
  alloydbconn.WithIAMAuthN()
)