The Cloud SQL Go connector is the easiest way to securely connect your Go application to your Cloud SQL database. Cloud Run is a fully managed serverless platform that enables you to run stateless containers that are invocable via HTTP requests. This Codelab will demonstrate how to connect a Go application on Cloud Run to a Cloud SQL for PostgreSQL database securely with a service account using IAM Authentication.
What you will learnIn this lab, you will learn how to do the following:
PROJECT_ID
). If you don't like the generated ID, you may generate another random one. Alternatively, you can try your own and see if it's available. It cannot be changed after this step and will remain for the duration of the project.Activate Cloud Shell by clicking on the icon to the right of the search bar.
From Cloud Shell, enable the APIs:
gcloud services enable compute.googleapis.com sqladmin.googleapis.com \
run.googleapis.com artifactregistry.googleapis.com \
cloudbuild.googleapis.com servicenetworking.googleapis.com
If prompted to authorize, click "Authorize" to continue.
This command may take a few minutes to complete, but it should eventually produce a successful message similar to this one:
Operation "operations/acf.p2-327036483151-73d90d00-47ee-447a-b600-a6badf0eceae" finished successfully.
3. Set up a Service Account
Create and configure a Google Cloud service account to be used by Cloud Run so that it has the correct permissions to connect to Cloud SQL.
gcloud iam service-accounts create
command as follows to create a new service account:
gcloud iam service-accounts create quickstart-service-account \
--display-name="Quickstart Service Account"
${GOOGLE_CLOUD_PROJECT}
will be replaced by the name of your project. You can also do this replacement manually if you feel more comfortable with that.
gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
--member="serviceAccount:quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
--role="roles/cloudsql.client"
gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
--member="serviceAccount:quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
--role="roles/cloudsql.instanceUser"
gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
--member="serviceAccount:quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
--role="roles/logging.logWriter"
Run the gcloud sql instances create
command to create a Cloud SQL instance.
cloudsql.iam_authentication
to enable Cloud Run to connect to Cloud SQL using the service account we created before.
gcloud sql instances create quickstart-instance \
--database-version=POSTGRES_14 \
--cpu=1 \
--memory=4GB \
--region=us-central1 \
--database-flags=cloudsql.iam_authentication=on
This command may take a few minutes to complete.
Run the gcloud sql databases create
command to create a Cloud SQL database within the quickstart-instance
.
gcloud sql databases create quickstart_db \
--instance=quickstart-instance
Create a PostgreSQL database user for the service account you created earlier to access the database.
gcloud sql users create quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam \
--instance=quickstart-instance \
--type=cloud_iam_service_account
5. Prepare Application
Prepare a Go application that responds to HTTP requests.
helloworld
, then change into that directory:
mkdir helloworld
cd helloworld
go mod init
to initialize a new Go application.
go mod init github.com/GoogleCloudPlatform/golang-samples/run/helloworld
go get cloud.google.com/go/cloudsqlconn
go get cloud.google.com/go/cloudsqlconn/postgres/pgxv4
main.go
file with the application code. This code is able to:
cat > main.go << "EOF"
package main
import (
"database/sql"
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"time"
"cloud.google.com/go/cloudsqlconn"
"cloud.google.com/go/cloudsqlconn/postgres/pgxv4"
)
// visitData is used to pass data to the HTML template.
type visitData struct {
RecentVisits []visit
}
// visit contains a single row from the visits table in the database.
// Each visit includes a timestamp.
type visit struct {
VisitTime time.Time
}
// getDB creates a connection to the database
// based on environment variables.
func getDB() (*sql.DB, func() error) {
cleanup, err := pgxv4.RegisterDriver("cloudsql-postgres", cloudsqlconn.WithIAMAuthN())
if err != nil {
log.Fatalf("Error on pgxv4.RegisterDriver: %v", err)
}
dsn := fmt.Sprintf("host=%s user=%s dbname=%s sslmode=disable", os.Getenv("INSTANCE_CONNECTION_NAME"), os.Getenv("DB_USER"), os.Getenv("DB_NAME"))
db, err := sql.Open("cloudsql-postgres", dsn)
if err != nil {
log.Fatalf("Error on sql.Open: %v", err)
}
createVisits := `CREATE TABLE IF NOT EXISTS visits (
id SERIAL NOT NULL,
created_at timestamp NOT NULL,
PRIMARY KEY (id)
);`
_, err = db.Exec(createVisits)
if err != nil {
log.Fatalf("unable to create table: %s", err)
}
return db, cleanup
}
func main() {
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
log.Printf("Listening on port %s", port)
db, cleanup := getDB()
defer cleanup()
http.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) {
// Insert current visit
_, err := db.Exec("INSERT INTO visits(created_at) VALUES(NOW())")
if err != nil {
log.Fatalf("unable to save visit: %v", err)
}
// Get the last 5 visits
rows, err := db.Query("SELECT created_at FROM visits ORDER BY created_at DESC LIMIT 5")
if err != nil {
log.Fatalf("DB.Query: %v", err)
}
defer rows.Close()
var visits []visit
for rows.Next() {
var visitTime time.Time
err := rows.Scan(&visitTime)
if err != nil {
log.Fatalf("Rows.Scan: %v", err)
}
visits = append(visits, visit{VisitTime: visitTime})
}
response, err := json.Marshal(visitData{RecentVisits: visits})
if err != nil {
log.Fatalf("renderIndex: failed to parse totals with json.Marshal: %v", err)
}
w.Write(response)
})
if err := http.ListenAndServe(":"+port, nil); err != nil {
log.Fatal(err)
}
}
EOF
This code creates a basic web server that listens on the port defined by the PORT environment variable. The application is now ready to be deployed.
6. Deploy Cloud Run ApplicationRun the command below to deploy your application:
.
refers to the source code in the current folder helloworld
.gcloud run deploy helloworld \
--region=us-central1 \
--source=. \
--set-env-vars INSTANCE_CONNECTION_NAME="${GOOGLE_CLOUD_PROJECT}:us-central1:quickstart-instance" \
--set-env-vars DB_NAME="quickstart_db" \
--set-env-vars DB_USER="quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam" \
--service-account="quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
--allow-unauthenticated
If prompted, press y
and Enter
to confirm that you would like to continue:
Do you want to continue (Y/n)? y
After a few minutes, the application should provide a URL for you to visit.
Navigate to the URL to see your application in action. Every time you visit the URL or refresh the page, you will see the five most recent visits returned as JSON.
7. CongratulationsYou have deployed a Go application on Cloud Run that is able to connect to a PostgreSQL database running on Cloud SQL.
What we've covered:To avoid incurring charges to your Google Cloud account for the resources used in this tutorial, either delete the project that contains the resources, or keep the project and delete the individual resources. If you would like to delete the entire project, you can run:
gcloud projects delete ${GOOGLE_CLOUD_PROJECT}
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],[],[],[]]
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4