1<p align="center">
2 <a href="https://pkg.go.dev/cloud.google.com/go/cloudsqlconn">
3 <img src="docs/images/cloud-sql-go-connector.png" alt="cloud-sql-go-connector image">
4 </a>
5</p>
6
7<h1 align="center">Cloud SQL Go Connector</h1>
8
9[![Open In Codelab][codelab-badge]][codelab]
10[![CI][ci-badge]][ci-build]
11[![Go Reference][pkg-badge]][pkg-docs]
12
13[ci-badge]: https://github.com/GoogleCloudPlatform/cloud-sql-go-connector/actions/workflows/tests.yaml/badge.svg?event=push
14[ci-build]: https://github.com/GoogleCloudPlatform/cloud-sql-go-connector/actions/workflows/tests.yaml?query=event%3Apush+branch%3Amain
15[pkg-badge]: https://pkg.go.dev/badge/cloud.google.com/go/cloudsqlconn.svg
16[pkg-docs]: https://pkg.go.dev/cloud.google.com/go/cloudsqlconn
17[codelab-badge]: https://img.shields.io/badge/Open%20In%20Codelab-blue?labelColor=grey&style=flat&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAyVBMVEX////////////////////////+8/L0oZrrTkHqQzXzlY13yKEPnVgdo2KHzqvw+fX4xMDtWk604MssqWz73NnvcWdKtYHS7eD85+ZowpayncOWapvVS0360MzD5tWW1LZxo/dChfSLaKHfR0FMhe2rY4TyiYBlm/bQ4Pz+7sD7xCPPthRJpkegwvl9q/fn8P7+9+D80VL7vASisCQsoU4spV393YHPwDm40ftNjPX7wBP95qHz9/7/++/b6P3+8tD8zUKIsvj81WJbutStAAAABnRSTlMAIKDw/zDiNY+eAAAA+klEQVR4AbzRRYICMRRF0VB5QLlrO+7uDvvfVKfSv91mnGlunDFWUDh+xJUCE4ocv+JFMZ/jD7zAFPxJYRx/4gz/uGpQKquaDsEwLdv5HrieJriAbwqB/yUII00qA7YpxcmHoKRrJAUSk2QOKLi5vdMk7x7CQ0CF9fgSPFUqlWpN09QyiG1REsugkqs3miW8cTIqHApyrTbedLq9vgzkCoMKGY4gjSdTYTY3F74M0G5VyADCckpWnbd3WG+oaAMdGt7uPj7UfvC2BC2wPIACMspvuzkCp60YPo9/+M328LKHcHiek6EmnRMMAUAw2RPMOASzHsHMSzD7AwCdmyeTDUqFKQAAAABJRU5ErkJggg==
18[codelab]: https://codelabs.developers.google.com/codelabs/cloud-sql-go-connector
19
20The _Cloud SQL Go Connector_ is a Cloud SQL connector designed for use with the
21Go language. Using a Cloud SQL connector provides a native alternative to the
22[Cloud SQL Auth Proxy][] while providing the following benefits:
23
24* **IAM Authorization:** uses IAM permissions to control who/what can connect to
25 your Cloud SQL instances
26* **Improved Security:** uses robust, updated TLS 1.3 encryption and
27 identity verification between the client connector and the server-side proxy,
28 independent of the database protocol.
29* **Convenience:** removes the requirement to use and distribute SSL
30 certificates, as well as manage firewalls or source/destination IP addresses.
31* (optionally) **IAM DB Authentication:** provides support for
32 [Cloud SQL’s automatic IAM DB AuthN][iam-db-authn] feature.
33
34[iam-db-authn]: https://cloud.google.com/sql/docs/postgres/authentication
35[Cloud SQL Auth Proxy]: https://cloud.google.com/sql/docs/postgres/sql-proxy
36
37For users migrating from the Cloud SQL Proxy drivers, see the [migration
38guide](./migration-guide.md).
39
40For a quick example, try out the Go Connector in a [Codelab][codelab].
41
42## Installation
43
44You can install this repo with `go get`:
45```sh
46go get cloud.google.com/go/cloudsqlconn
47```
48
49## Usage
50
51This package provides several functions for authorizing and encrypting
52connections. These functions can be used with your database driver to connect to
53your Cloud SQL instance.
54
55The instance connection name for your Cloud SQL instance is always in the
56format `project:region:instance`.
57
58### APIs and Services
59
60This package requires the following to successfully make Cloud SQL Connections:
61
62- IAM principal (user, service account, etc.) with the
63[Cloud SQL Client][client-role] role or equivalent. This IAM principal will
64 be used for [credentials](#credentials).
65- The [Cloud SQL Admin API][admin-api] to be enabled within your Google Cloud
66Project. By default, the API will be called in the project associated with
67the IAM principal.
68
69[admin-api]: https://console.cloud.google.com/apis/api/sqladmin.googleapis.com
70[client-role]: https://cloud.google.com/sql/docs/mysql/roles-and-permissions
71
72### Credentials
73
74This project uses the [Application Default Credentials (ADC)][adc] strategy for
75resolving credentials. Please see [these instructions for how to set your ADC][set-adc]
76(Google Cloud Application vs Local Development, IAM user vs service account credentials),
77or consult the [golang.org/x/oauth2/google][google-auth] documentation.
78
79To explicitly set a specific source for the Credentials, see [Using
80Options](#using-options) below.
81
82[adc]: https://cloud.google.com/docs/authentication#adc
83[set-adc]: https://cloud.google.com/docs/authentication/provide-credentials-adc
84[google-auth]: https://pkg.go.dev/golang.org/x/oauth2/google#hdr-Credentials
85
86### Connecting to a database
87
88#### Postgres
89
90Postgres users have the option of using the `database/sql` interface or
91using [pgx][] directly. See [pgx's advice on which to choose][pgx-advice].
92
93[pgx]: https://github.com/jackc/pgx
94[pgx-advice]: https://github.com/jackc/pgx#choosing-between-the-pgx-and-databasesql-interfaces
95
96##### Using the dialer with pgx
97
98To use the dialer with [pgx][], we recommend using connection pooling with
99[pgxpool](https://pkg.go.dev/github.com/jackc/pgx/v5/pgxpool) by configuring
100a [Config.DialFunc][dial-func] like so:
101
102``` go
103import (
104 "context"
105 "net"
106
107 "cloud.google.com/go/cloudsqlconn"
108 "github.com/jackc/pgx/v5/pgxpool"
109)
110
111func connect() {
112 // Configure the driver to connect to the database
113 dsn := "user=myuser password=mypass dbname=mydb sslmode=disable"
114 config, err := pgxpool.ParseConfig(dsn)
115 if err != nil {
116 /* handle error */
117 }
118
119 // Create a new dialer with any options
120 d, err := cloudsqlconn.NewDialer(context.Background())
121 if err != nil {
122 /* handle error */
123 }
124
125 // Tell the driver to use the Cloud SQL Go Connector to create connections
126 config.ConnConfig.DialFunc = func(ctx context.Context, _ string, instance string) (net.Conn, error) {
127 return d.Dial(ctx, "project:region:instance")
128 }
129
130 // Interact with the driver directly as you normally would
131 pool, err := pgxpool.NewWithConfig(context.Background(), config)
132 if err != nil {
133 /* handle error */
134 }
135
136 // call cleanup when you're done with the database connection
137 cleanup := func() error { return d.Close() }
138 // ... etc
139}
140```
141
142[dial-func]: https://pkg.go.dev/github.com/jackc/pgconn#Config
143
144##### Using the dialer with `database/sql`
145
146To use `database/sql`, call `pgxv5.RegisterDriver` with any necessary Dialer
147configuration. Note: the connection string must use the keyword/value format
148with host set to the instance connection name. The returned `cleanup` func
149will stop the dialer's background refresh goroutine and so should only be called
150when you're done with the `Dialer`.
151
152``` go
153import (
154 "database/sql"
155
156 "cloud.google.com/go/cloudsqlconn"
157 "cloud.google.com/go/cloudsqlconn/postgres/pgxv5"
158)
159
160func connect() {
161 cleanup, err := pgxv5.RegisterDriver("cloudsql-postgres", cloudsqlconn.WithIAMAuthN())
162 if err != nil {
163 // ... handle error
164 }
165 // call cleanup when you're done with the database connection
166 defer cleanup()
167
168 db, err := sql.Open(
169 "cloudsql-postgres",
170 "host=project:region:instance user=myuser password=mypass dbname=mydb sslmode=disable",
171 )
172 // ... etc
173}
174```
175
176#### MySQL
177
178To use `database/sql`, use `mysql.RegisterDriver` with any necessary Dialer
179configuration. The returned `cleanup` func
180will stop the dialer's background refresh goroutine and so should only be called
181when you're done with the `Dialer`.
182
183```go
184import (
185 "database/sql"
186
187 "cloud.google.com/go/cloudsqlconn"
188 "cloud.google.com/go/cloudsqlconn/mysql/mysql"
189)
190
191func connect() {
192 cleanup, err := mysql.RegisterDriver("cloudsql-mysql", cloudsqlconn.WithCredentialsFile("key.json"))
193 if err != nil {
194 // ... handle error
195 }
196 // call cleanup when you're done with the database connection
197 defer cleanup()
198
199 db, err := sql.Open(
200 "cloudsql-mysql",
201 "myuser:mypass@cloudsql-mysql(project:region:instance)/mydb",
202 )
203 // ... etc
204}
205```
206
207#### SQL Server
208
209To use `database/sql`, use `mssql.RegisterDriver` with any necessary Dialer
210configuration. The returned `cleanup` func
211will stop the dialer's background refresh goroutine and so should only be called
212when you're done with the `Dialer`.
213
214``` go
215import (
216 "database/sql"
217
218 "cloud.google.com/go/cloudsqlconn"
219 "cloud.google.com/go/cloudsqlconn/sqlserver/mssql"
220)
221
222func connect() {
223 cleanup, err := mssql.RegisterDriver("cloudsql-sqlserver", cloudsqlconn.WithCredentialsFile("key.json"))
224 if err != nil {
225 // ... handle error
226 }
227 // call cleanup when you're done with the database connection
228 defer cleanup()
229
230 db, err := sql.Open(
231 "cloudsql-sqlserver",
232 "sqlserver://user:password@localhost?database=mydb&cloudsql=project:region:instance",
233 )
234 // ... etc
235}
236```
237
238### Using Options
239
240If you need to customize something about the `Dialer`, you can initialize
241directly with `NewDialer`:
242
243```go
244d, err := cloudsqlconn.NewDialer(
245 ctx,
246 cloudsqlconn.WithCredentialsFile("key.json"),
247)
248if err != nil {
249 log.Fatalf("unable to initialize dialer: %s", err)
250}
251
252conn, err := d.Dial(ctx, "project:region:instance")
253```
254
255For a full list of customizable behavior, see Option.
256
257### Using DialOptions
258
259If you want to customize things about how the connection is created, use
260`Option`:
261
262```go
263conn, err := d.Dial(
264 ctx,
265 "project:region:instance",
266 cloudsqlconn.WithPrivateIP(),
267)
268```
269
270You can also use the `WithDefaultDialOptions` Option to specify
271DialOptions to be used by default:
272
273```go
274d, err := cloudsqlconn.NewDialer(
275 ctx,
276 cloudsqlconn.WithDefaultDialOptions(
277 cloudsqlconn.WithPrivateIP(),
278 ),
279)
280```
281
282### Automatic IAM Database Authentication
283
284Connections using [Automatic IAM database authentication][] are supported when
285using Postgres or MySQL drivers.
286
287Make sure to [configure your Cloud SQL Instance to allow IAM authentication][configure-iam-authn]
288and [add an IAM database user][add-iam-user].
289
290A `Dialer` can be configured to connect to a Cloud SQL instance using
291automatic IAM database authentication with the `WithIAMAuthN` Option
292(recommended) or the `WithDialIAMAuthN` DialOption.
293
294```go
295d, err := cloudsqlconn.NewDialer(ctx, cloudsqlconn.WithIAMAuthN())
296```
297
298When configuring the DSN for IAM authentication, the `password` field can be
299omitted and the `user` field should be formatted as follows:
300> Postgres: For an IAM user account, this is the user's email address.
301> For a service account, it is the service account's email without the
302> `.gserviceaccount.com` domain suffix.
303>
304> MySQL: For an IAM user account, this is the user's email address, without
305> the `@` or domain name. For example, for `test-user@gmail.com`, set the
306> `user` field to `test-user`. For a service account, this is the service
307> account's email address without the `@project-id.iam.gserviceaccount.com`
308> suffix.
309
310Example DSNs using the `test-sa@test-project.iam.gserviceaccount.com`
311service account to connect can be found below.
312
313**Postgres**:
314
315```go
316dsn := "user=test-sa@test-project.iam dbname=mydb sslmode=disable"
317```
318
319**MySQL**:
320
321```go
322dsn := "user=test-sa dbname=mydb sslmode=disable"
323```
324
325[Automatic IAM database authentication]: https://cloud.google.com/sql/docs/postgres/authentication#automatic
326[configure-iam-authn]: https://cloud.google.com/sql/docs/postgres/create-edit-iam-instances#configure-iam-db-instance
327[add-iam-user]: https://cloud.google.com/sql/docs/postgres/create-manage-iam-users#creating-a-database-user
328
329### Enabling Metrics and Tracing
330
331This library includes support for metrics and tracing using [OpenCensus][].
332To enable metrics or tracing, you need to configure an [exporter][].
333OpenCensus supports many backends for exporters.
334
335Supported metrics include:
336
337- `cloudsqlconn/dial_latency`: The distribution of dialer latencies (ms)
338- `cloudsqlconn/open_connections`: The current number of open Cloud SQL
339 connections
340- `cloudsqlconn/dial_failure_count`: The number of failed dial attempts
341- `cloudsqlconn/refresh_success_count`: The number of successful certificate
342 refresh operations
343- `cloudsqlconn/refresh_failure_count`: The number of failed refresh
344 operations.
345
346Supported traces include:
347
348- `cloud.google.com/go/cloudsqlconn.Dial`: The dial operation including
349 refreshing an ephemeral certificate and connecting the instance
350- `cloud.google.com/go/cloudsqlconn/internal.InstanceInfo`: The call to retrieve
351 instance metadata (e.g., database engine type, IP address, etc)
352- `cloud.google.com/go/cloudsqlconn/internal.Connect`: The connection attempt
353 using the ephemeral certificate
354- SQL Admin API client operations
355
356For example, to use [Cloud Monitoring][] and [Cloud Trace][], you would
357configure an exporter like so:
358
359```golang
360import (
361 "contrib.go.opencensus.io/exporter/stackdriver"
362 "go.opencensus.io/trace"
363)
364
365func main() {
366 sd, err := stackdriver.NewExporter(stackdriver.Options{
367 ProjectID: "mycoolproject",
368 })
369 if err != nil {
370 // handle error
371 }
372 defer sd.Flush()
373 trace.RegisterExporter(sd)
374
375 sd.StartMetricsExporter()
376 defer sd.StopMetricsExporter()
377
378 // Use cloudsqlconn as usual.
379 // ...
380}
381```
382
383As OpenTelemetry has now reached feature parity with OpenCensus, the migration
384from OpenCensus to OpenTelemetry is strongly encouraged.
385[OpenTelemetry bridge](https://github.com/open-telemetry/opentelemetry-go/tree/main/bridge/opencensus)
386can be leveraged to migrate to OpenTelemetry without the need of replacing the
387OpenCensus APIs in this library. Example code is shown below for migrating an
388application using the OpenTelemetry bridge for traces.
389
390```golang
391import (
392 texporter "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace"
393 "go.opencensus.io/trace"
394 "go.opentelemetry.io/otel"
395 "go.opentelemetry.io/otel/bridge/opencensus"
396 sdktrace "go.opentelemetry.io/otel/sdk/trace"
397 "google.golang.org/api/option"
398)
399
400func main() {
401 // trace.AlwaysSample() is expensive. Replacing it with your own
402 // sampler for production environments is recommended.
403 trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})
404
405 exporter, err := texporter.New(
406 texporter.WithTraceClientOptions([]option.ClientOption{option.WithTelemetryDisabled()}),
407 texporter.WithProjectID("mycoolproject"),
408 )
409 if err != nil {
410 // Handle error
411 }
412
413 tp := sdktrace.NewTracerProvider(sdktrace.WithSyncer(exporter))
414 otel.SetTracerProvider(tp)
415 tracer := tp.Tracer("Cloud SQL Go Connector Trace")
416 trace.DefaultTracer = opencensus.NewTracer(tracer)
417
418 // Use cloudsqlconn as usual.
419 // ...
420}
421```
422
423A known OpenTelemetry issue has been reported [here](https://github.com/googleapis/google-cloud-go/issues/7100).
424It shouldn't impact database operations.
425
426[OpenCensus]: https://opencensus.io/
427[exporter]: https://opencensus.io/exporters/
428[Cloud Monitoring]: https://cloud.google.com/monitoring
429[Cloud Trace]: https://cloud.google.com/trace
430
431### Debug Logging
432
433The Go Connector supports optional debug logging to help diagnose problems with
434the background certificate refresh. To enable it, provide a logger that
435implements the `debug.ContextLogger` interface when initializing the Dialer.
436
437For example:
438
439``` go
440import (
441 "context"
442 "net"
443
444 "cloud.google.com/go/cloudsqlconn"
445)
446
447type myLogger struct{}
448
449func (l *myLogger) Debugf(ctx context.Context, format string, args ...interface{}) {
450 // Log as you like here
451}
452
453func connect() {
454 l := &myLogger{}
455
456 d, err := NewDialer(
457 context.Background(),
458 cloudsqlconn.WithContextDebugLogger(l),
459 )
460 // use dialer as usual...
461}
462```
463
464## Support policy
465
466### Major version lifecycle
467
468This project uses [semantic versioning](https://semver.org/), and uses the
469following lifecycle regarding support for a major version:
470
471**Active** - Active versions get all new features and security fixes (that
472wouldn’t otherwise introduce a breaking change). New major versions are
473guaranteed to be "active" for a minimum of 1 year.
474
475**Deprecated** - Deprecated versions continue to receive security and critical
476bug fixes, but do not receive new features. Deprecated versions will be
477supported for 1 year.
478
479**Unsupported** - Any major version that has been deprecated for >=1 year is
480considered unsupported.
481
482### Supported Go Versions
483
484We follow the [Go Version Support Policy][go-policy] used by Google Cloud
485Libraries for Go.
486
487[go-policy]: https://github.com/googleapis/google-cloud-go#go-versions-supported
488
489### Release cadence
490
491This project aims for a release on at least a monthly basis. If no new features
492or fixes have been added, a new PATCH version with the latest dependencies is
493released.
View as plain text