Connect using the AlloyDB Language Connectors

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

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

They can't provide a network path to a AlloyDB cluster if one is not 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:

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>

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'

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, run the following command:

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

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, run the following command:

For asyncpg, use:

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

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, run the following command:

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, 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 (Preview)

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

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

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 it 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,
) -> 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_name (str):
            The name of the database, e.g., mydb
    """
    connector = Connector()

    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 (Preview)

If you're using public IP to connect to your AlloyDB cluster, 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

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 it 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,
) -> 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_name (str):
            The name of the database, e.g., mydb
    """
    connector = AsyncConnector()

    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 (Preview)

If you're using public IP to connect to your AlloyDB cluster, 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

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 it 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,
) (*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)
	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 (Preview)

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

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

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 it 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 (Preview)

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

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

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()
)