The AlloyDB Go Connector is the recommended way to connect to AlloyDB from Go applications. It provides:
- Secure connections — TLS 1.3 encryption and identity verification, independent of the database protocol
- IAM-based authorization — controls who can connect to your AlloyDB instances using Google Cloud IAM
- No certificate management — no SSL certificates, firewall rules, or IP allowlisting required
- IAM database authentication — optional support for automatic IAM DB authentication
Install the module:
go get cloud.google.com/go/alloydbconnConnect using the standard database/sql package:
package main
import (
"database/sql"
"fmt"
"log"
"cloud.google.com/go/alloydbconn/driver/pgxv5"
)
func main() {
// Register the AlloyDB driver with the name "alloydb"
// Uses Private IP by default. See Network Options below for details.
cleanup, err := pgxv5.RegisterDriver("alloydb")
if err != nil {
log.Fatal(err)
}
defer cleanup()
// Instance URI format:
// projects/PROJECT/locations/REGION/clusters/CLUSTER/instances/INSTANCE
db, err := sql.Open("alloydb", fmt.Sprintf(
"host=%s user=%s password=%s dbname=%s sslmode=disable",
"projects/my-project/locations/us-central1/clusters/my-cluster/instances/my-instance",
"my-user",
"my-password",
"my-db",
))
if err != nil {
log.Fatal(err)
}
defer db.Close()
var greeting string
if err := db.QueryRow("SELECT 'Hello, AlloyDB!'").Scan(&greeting); err != nil {
log.Fatal(err)
}
fmt.Println(greeting)
}The connector uses Application Default Credentials (ADC) automatically. For local development, run:
gcloud auth application-default login- Prerequisites
- Connecting with database/sql
- Connecting with pgx
- Network Options
- IAM Database Authentication
- Configuring the Dialer
- Observability
- Debug Logging
- Support Policy
The IAM principal (user or service account) making connections needs:
- AlloyDB Client role (
roles/alloydb.client) - Service Usage Consumer role (
roles/serviceusage.serviceUsageConsumer)
Enable the AlloyDB API in your Google Cloud project.
The connector uses Application Default Credentials (ADC) — this is the recommended approach for most applications. ADC automatically finds credentials from the environment:
- Local development: run
gcloud auth application-default loginonce - Google Cloud (Compute Engine, Cloud Run, GKE, etc.): credentials are picked up automatically from the attached service account — no code changes needed
# One-time setup for local development
gcloud auth application-default loginIf you need to supply credentials explicitly (e.g., in non-Google managed environments without Application Default Credentials), see the Configuring the Dialer section for less common alternatives.
The database/sql approach works with any library that accepts a *sql.DB.
import (
"database/sql"
"fmt"
"cloud.google.com/go/alloydbconn"
"cloud.google.com/go/alloydbconn/driver/pgxv5"
)
func connect(instURI, user, pass, dbname string) (*sql.DB, func() error, error) {
// RegisterDriver registers the AlloyDB driver and returns a cleanup
// function that stops background goroutines. Call cleanup when you are
// done with the database connection to avoid a goroutine leak.
cleanup, err := pgxv5.RegisterDriver("alloydb")
if err != nil {
return nil, nil, err
}
db, err := sql.Open("alloydb", fmt.Sprintf(
// sslmode=disable is correct here: the connector handles TLS.
"host=%s user=%s password=%s dbname=%s sslmode=disable",
instURI, user, pass, dbname,
))
if err != nil {
return nil, cleanup, err
}
return db, cleanup, nil
}Instance URI format:
projects/PROJECT/locations/REGION/clusters/CLUSTER/instances/INSTANCE
For direct control over connection pooling, use pgx
with pgxpool:
import (
"context"
"fmt"
"net"
"cloud.google.com/go/alloydbconn"
"github.com/jackc/pgx/v5/pgxpool"
)
func connect(ctx context.Context, instURI, user, pass, dbname string) (*pgxpool.Pool, func() error, error) {
d, err := alloydbconn.NewDialer(ctx)
if err != nil {
return nil, func() error { return nil }, fmt.Errorf("failed to init dialer: %v", err)
}
// cleanup stops the dialer's background goroutines.
cleanup := func() error { return d.Close() }
config, err := pgxpool.ParseConfig(fmt.Sprintf(
"user=%s password=%s dbname=%s sslmode=disable",
user, pass, dbname,
))
if err != nil {
return nil, cleanup, fmt.Errorf("failed to parse config: %v", err)
}
// Tell pgx to use the AlloyDB connector for all connections.
config.ConnConfig.DialFunc = func(ctx context.Context, _, _ string) (net.Conn, error) {
return d.Dial(ctx, instURI)
}
pool, err := pgxpool.NewWithConfig(ctx, config)
if err != nil {
return nil, cleanup, fmt.Errorf("failed to connect: %v", err)
}
return pool, cleanup, nil
}AlloyDB supports three connectivity modes. The connector defaults to private IP.
Private IP requires your application to run within a VPC Network
connected to your AlloyDB instance. No extra configuration is needed — the
default d.Dial(ctx, instURI) call will connect over private IP.
Pass WithPublicIP() to connect over the instance's public IP address.
With database/sql:
cleanup, err := pgxv5.RegisterDriver("alloydb",
alloydbconn.WithDefaultDialOptions(alloydbconn.WithPublicIP()),
)With pgx:
config.ConnConfig.DialFunc = func(ctx context.Context, _, _ string) (net.Conn, error) {
return d.Dial(ctx, instURI, alloydbconn.WithPublicIP())
}Pass WithPSC() to connect via Private Service Connect.
With database/sql:
cleanup, err := pgxv5.RegisterDriver("alloydb",
alloydbconn.WithDefaultDialOptions(alloydbconn.WithPSC()),
)With pgx:
config.ConnConfig.DialFunc = func(ctx context.Context, _, _ string) (net.Conn, error) {
return d.Dial(ctx, instURI, alloydbconn.WithPSC())
}The connector supports Automatic IAM database authentication. With IAM auth, your application's IAM identity is used in place of a static database password.
Before you begin:
Connect with IAM authentication:
// Pass WithIAMAuthN() to enable automatic IAM authentication.
cleanup, err := pgxv5.RegisterDriver("alloydb", alloydbconn.WithIAMAuthN())Set the user field in your DSN based on your IAM identity type:
| Identity type | Username format |
|---|---|
| IAM user account | Full email: user@example.com |
| Service account | Email without .gserviceaccount.com: my-sa@my-project.iam |
db, err := sql.Open("alloydb", fmt.Sprintf(
// Omit the password field when using IAM authentication.
"host=%s user=%s dbname=%s sslmode=disable",
instURI,
"my-sa@my-project.iam",
dbname,
))Both pgxv5.RegisterDriver and alloydbconn.NewDialer accept options to
customize connector behavior.
Most applications should rely on Application Default Credentials and won't need these options. Use them only when ADC isn't available in your environment.
From a service account key file:
cleanup, err := pgxv5.RegisterDriver("alloydb",
alloydbconn.WithCredentialsFile("path/to/service-account-key.json"),
)From a credentials JSON blob:
cleanup, err := pgxv5.RegisterDriver("alloydb",
alloydbconn.WithCredentialsJSON([]byte(`{...}`)),
)Apply options to every connection made by the dialer:
d, err := alloydbconn.NewDialer(ctx,
alloydbconn.WithDefaultDialOptions(
alloydbconn.WithPublicIP(),
),
)For all available options, see the alloydbconn.Option reference.
The connector exports metrics and traces via OpenCensus. Configure an exporter to send telemetry to your monitoring backend.
| Metric | Description |
|---|---|
alloydbconn/dial_latency |
Distribution of dialer latencies (ms) |
alloydbconn/open_connections |
Current number of open AlloyDB connections |
alloydbconn/dial_failure_count |
Number of failed dial attempts |
alloydbconn/refresh_success_count |
Number of successful certificate refresh operations |
alloydbconn/refresh_failure_count |
Number of failed refresh operations |
alloydbconn/bytes_sent |
Bytes sent to an AlloyDB instance |
alloydbconn/bytes_received |
Bytes received from an AlloyDB instance |
cloud.google.com/go/alloydbconn.Dial— the full dial operationcloud.google.com/go/alloydbconn/internal.InstanceInfo— instance metadata retrievalcloud.google.com/go/alloydbconn/internal.Connect— connection attempt using the ephemeral certificate- AlloyDB API client operations
import (
"contrib.go.opencensus.io/exporter/stackdriver"
"go.opencensus.io/trace"
)
func main() {
sd, err := stackdriver.NewExporter(stackdriver.Options{
ProjectID: "my-project",
})
if err != nil {
log.Fatal(err)
}
defer sd.Flush()
trace.RegisterExporter(sd)
sd.StartMetricsExporter()
defer sd.StopMetricsExporter()
// Use alloydbconn as usual.
}Enable debug logging to diagnose issues with the background certificate refresh.
Implement the debug.ContextLogger interface and pass it to the dialer:
import (
"context"
"log"
"cloud.google.com/go/alloydbconn"
)
type myLogger struct{}
func (l *myLogger) Debugf(ctx context.Context, format string, args ...interface{}) {
log.Printf("[DEBUG] "+format, args...)
}
func connect(ctx context.Context) {
d, err := alloydbconn.NewDialer(ctx,
alloydbconn.WithContextDebugLogger(&myLogger{}),
)
// use d as usual...
}This project uses semantic versioning:
| Stage | Description |
|---|---|
| Active | Receives all new features and security fixes. New major versions are guaranteed active for a minimum of 1 year. |
| Deprecated | Receives security and critical bug fixes only. Supported for 1 year after deprecation. |
| Unsupported | Any major version deprecated for ≥ 1 year. |
We follow the Go Version Support Policy used by Google Cloud Libraries for Go.
This project aims for a monthly release cadence. If no new features or fixes are available, a patch release with updated dependencies is published.