I am using gin framework to develop my go microservice. I am using google cloud as the provider and using google cloud run for deploying the microservice and google cloud postgressql for database. I am using IAM authentication.
Below is the code I am using for creating database object
func connectDatabase() (*gorm.DB, error) {
fmt.Println("Connecting to database")
// Construct the DSN
dsn := fmt.Sprintf("host=%s dbname=%s user=%s sslmode=disable",
os.Getenv("INSTANCE_CONNECTION_NAME"), // Cloud SQL instance connection name
os.Getenv("DB_NAME"), // Database name
os.Getenv("DB_USER"), // Database password
)
// Open a connection to the database
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
return nil, fmt.Errorf("error connecting to database: %w", err)
}
// Auto-migrate your models
db.AutoMigrate(&User{})
fmt.Println("Connected to database successfully")
return db, nil
}
Below is the cmd I am using for deploying the microservice
gcloud run deploy api \
--source=. \
--set-env-vars INSTANCE_CONNECTION_NAME=“env-xxxx:us-west1:uxxx” \
--set-env-vars DB_NAME=“dbxxxxxx” \
--set-env-vars DB_USER="sxxxx-xxxx@sxxxx-xxxx.iam" \
--service-account="sxxxx-xxxx@sxxxx-rxxxx.iam.gserviceaccount.com" \
--allow-unauthenticated
With the above code, Once I deploy the microsevice I am getting error as "[0m[31m[error] [0mfailed to initialize database, got error failed to connect to host=sxxxx-xxxxx:us-west1:uxxx user=sxxxx-xxxx@sxxxx-xxxx.iam database= dbxxxxxx
: hostname resolving error (lookup sxxxx-xxxx:us-west1:uxxxx: no such host)"
I assume you're using public IP.
You have a few options to do this:
package main
import (
"fmt"
"time"
"cloud.google.com/go/cloudsqlconn"
"cloud.google.com/go/cloudsqlconn/postgres/pgxv5"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
func main() {
cleanup, err := pgxv5.RegisterDriver(
"cloudsql-postgres",
cloudsqlconn.WithLazyRefresh(),
cloudsqlconn.WithIAMAuthN(),
)
if err != nil {
panic(err)
}
// cleanup will stop the driver from retrieving ephemeral certificates
// Don't call cleanup until you're done with your database connections
defer cleanup()
dsn := "host=my-project:us-central1:my-instance user=postgres password=postgres dbname=postgres sslmode=disable"
db, err := gorm.Open(postgres.New(postgres.Config{
DriverName: "cloudsql-postgres",
DSN: dsn,
}))
if err != nil {
panic(err)
}
// get the underlying *sql.DB type to verify the connection
sdb, err := db.DB()
if err != nil {
panic(err)
}
var t time.Time
if err := sdb.QueryRow("select now()").Scan(&t); err != nil {
panic(err)
}
fmt.Println(t)
}
From a convenience standpoint, #2 is easier. Note the "lazy refresh" option which ensures the Go Connector doesn't try to run background goroutines outside of a request, since Cloud Run throttles the CPU by default and causes problems with background goroutines.