Cara menghubungkan aplikasi Go di Cloud Run ke database Cloud SQL untuk PostgreSQL

1. Ringkasan

Konektor Go Cloud SQL adalah cara termudah untuk menghubungkan aplikasi Go Anda ke database Cloud SQL dengan aman. Cloud Run adalah platform serverless terkelola sepenuhnya yang memungkinkan Anda menjalankan container stateless yang dapat dipanggil melalui permintaan HTTP. Codelab ini akan menunjukkan cara menghubungkan aplikasi Go di Cloud Run ke database Cloud SQL untuk PostgreSQL secara aman dengan akun layanan menggunakan Autentikasi IAM.

Yang akan Anda pelajari

Di lab ini, Anda akan mempelajari cara melakukan hal-hal berikut:

  • Membuat database Cloud SQL untuk PostgreSQL
  • Men-deploy aplikasi Go ke Cloud Run
  • Menghubungkan aplikasi Anda ke Cloud SQL menggunakan Konektor Go

Prasyarat

  • Di lab ini, Anda dianggap telah memahami Konsol Cloud dan lingkungan Cloud Shell.

2. Sebelum memulai

Penyiapan Project Cloud

  1. Login ke Google Cloud Console dan buat project baru atau gunakan kembali project yang sudah ada. Jika belum memiliki Akun Google, Anda harus membuatnya.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Project name adalah nama tampilan untuk peserta project ini. String ini adalah string karakter yang tidak digunakan oleh Google API. Anda dapat memperbaruinya kapan saja.
  • Project ID bersifat unik di semua project Google Cloud dan tidak dapat diubah (tidak dapat diubah setelah ditetapkan). Cloud Console otomatis membuat string unik; biasanya Anda tidak mementingkan kata-katanya. Di sebagian besar codelab, Anda harus merujuk Project ID-nya (biasanya diidentifikasi sebagai PROJECT_ID). Jika tidak suka dengan ID yang dibuat, Anda dapat membuat ID acak lainnya. Atau, Anda dapat mencobanya sendiri dan melihat apakah ID tersebut tersedia. ID tidak dapat diubah setelah langkah ini dan akan tetap ada selama durasi project.
  • Sebagai informasi, ada nilai ketiga, Project Number yang digunakan oleh beberapa API. Pelajari lebih lanjut ketiga nilai ini di dokumentasi.
  1. Selanjutnya, Anda harus mengaktifkan penagihan di Konsol Cloud untuk menggunakan resource/API Cloud. Menjalankan operasi dalam codelab ini seharusnya tidak memerlukan banyak biaya, bahkan mungkin tidak sama sekali. Guna mematikan resource agar tidak menimbulkan penagihan di luar tutorial ini, Anda dapat menghapus resource yang dibuat atau menghapus seluruh project. Pengguna baru Google Cloud memenuhi syarat untuk mengikuti program Uji Coba Gratis senilai $300 USD.

Penyiapan Lingkungan

Aktifkan Cloud Shell dengan mengklik ikon di sebelah kanan kotak penelusuran.

ecdc43ada29e91b.png

Aktifkan API dari Cloud Shell:

gcloud services enable compute.googleapis.com sqladmin.googleapis.com \
  run.googleapis.com artifactregistry.googleapis.com \
  cloudbuild.googleapis.com servicenetworking.googleapis.com

Jika diminta untuk memberikan otorisasi, klik "Beri otorisasi" untuk melanjutkan.

6356559df3eccdda.png

Pemrosesan perintah ini mungkin membutuhkan waktu beberapa menit, tetapi pada akhirnya akan menghasilkan pesan keberhasilan yang mirip dengan yang berikut:

Operation "operations/acf.p2-327036483151-73d90d00-47ee-447a-b600-a6badf0eceae" finished successfully.

3. Menyiapkan Akun Layanan

Buat dan konfigurasi akun layanan Google Cloud yang akan digunakan oleh Cloud Run sehingga akun tersebut memiliki izin yang benar untuk terhubung ke Cloud SQL.

  1. Jalankan perintah gcloud iam service-accounts create sebagai berikut untuk membuat akun layanan baru:
    gcloud iam service-accounts create quickstart-service-account \
      --display-name="Quickstart Service Account"
    
  2. Jalankan perintah gcloud projects add-iam-policy-binding sebagai berikut untuk menambahkan peran Cloud SQL Client ke akun layanan Google Cloud yang baru saja Anda buat. Di Cloud Shell, ekspresi ${GOOGLE_CLOUD_PROJECT} akan diganti dengan nama project Anda. Anda juga dapat melakukan penggantian ini secara manual jika Anda merasa lebih nyaman melakukannya.
    gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
      --member="serviceAccount:quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
      --role="roles/cloudsql.client"
    
  3. Jalankan perintah gcloud projects add-iam-policy-binding sebagai berikut untuk menambahkan peran Cloud SQL Instance User ke akun layanan Google Cloud yang baru saja Anda buat.
    gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
      --member="serviceAccount:quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
      --role="roles/cloudsql.instanceUser"
    
  4. Jalankan perintah gcloud projects add-iam-policy-binding sebagai berikut untuk menambahkan peran Log Writer ke akun layanan Google Cloud yang baru saja Anda buat.
    gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
      --member="serviceAccount:quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
      --role="roles/logging.logWriter"
    

4. Menyiapkan Cloud SQL

Jalankan perintah gcloud sql instances create untuk membuat instance Cloud SQL.

  • –database-version: Jenis dan versi mesin database. Jika tidak ditentukan, default API akan digunakan. Lihat dokumentasi versi database gcloud untuk melihat versi yang tersedia saat ini.
  • –cpu: Jumlah inti yang diinginkan dalam mesin.
  • –memory: Nilai bilangan bulat yang menunjukkan jumlah memori yang diinginkan dalam mesin. Unit ukuran harus ditentukan (misalnya, 3072 MB atau 9 GB). Jika tidak ada unit yang ditentukan, GB akan digunakan.
  • –region: Lokasi regional instance (misalnya: us-central1, asia-east1, us-east1).
  • –database-flags: Mengizinkan penetapan tanda. Dalam kasus ini, kita mengaktifkan cloudsql.iam_authentication agar Cloud Run dapat terhubung ke Cloud SQL menggunakan akun layanan yang kita buat sebelumnya.
    gcloud sql instances create quickstart-instance \
      --database-version=POSTGRES_14 \
      --cpu=1 \
      --memory=4GB \
      --region=us-central1 \
      --database-flags=cloudsql.iam_authentication=on
    

Pemrosesan perintah ini dapat membutuhkan waktu beberapa menit.

Jalankan perintah gcloud sql databases create untuk membuat database Cloud SQL dalam quickstart-instance.

gcloud sql databases create quickstart_db \
  --instance=quickstart-instance

Buat pengguna database PostgreSQL untuk akun layanan yang Anda buat sebelumnya guna mengakses database.

gcloud sql users create quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam \
  --instance=quickstart-instance \
  --type=cloud_iam_service_account

5. Menyiapkan Aplikasi

Siapkan aplikasi Go yang merespons permintaan HTTP.

  1. Di Cloud Shell, buat direktori baru bernama helloworld, lalu beralihlah ke direktori tersebut:
    mkdir helloworld
    cd helloworld
    
  2. Jalankan go mod init untuk menginisialisasi aplikasi Go baru.
    go mod init github.com/GoogleCloudPlatform/golang-samples/run/helloworld
    
  3. Instal dependensi Cloud SQL Go Connector.
    go get cloud.google.com/go/cloudsqlconn
    go get cloud.google.com/go/cloudsqlconn/postgres/pgxv4
    
  4. Buat file main.go dengan kode aplikasi. Kode ini dapat:
    • Menerima permintaan HTTP
    • Menghubungkan ke database
    • Menyimpan waktu permintaan HTTP dalam database
    • Menampilkan waktu lima permintaan terakhir
    Jalankan perintah berikut di Cloud Shell:
    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
    

Kode ini menghasilkan server web dasar yang memantau port yang ditentukan oleh variabel lingkungan PORT. Aplikasi kini siap di-deploy.

6. Men-deploy Aplikasi Cloud Run

Jalankan perintah di bawah untuk men-deploy aplikasi Anda:

  • –region: Lokasi regional instance (misalnya: us-central1, asia-east1, us-east1).
  • –source: Kode sumber yang akan di-deploy. Dalam hal ini, . merujuk ke kode sumber di folder saat ini helloworld.
  • –set-env-vars: Menetapkan variabel lingkungan yang digunakan oleh aplikasi untuk mengarahkan aplikasi ke database Cloud SQL.
  • –service-account: Mengaitkan deployment Cloud Run ke akun layanan dengan izin untuk terhubung ke database Cloud SQL yang dibuat di awal Codelab ini.
  • –allow-unauthenticated: Mengizinkan permintaan yang tidak diautentikasi sehingga aplikasi dapat diakses dari internet.
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

Jika diminta, tekan y dan Enter untuk mengonfirmasi bahwa Anda ingin melanjutkan:

Do you want to continue (Y/n)? y

Setelah beberapa menit, aplikasi akan memberikan URL yang dapat Anda kunjungi.

Buka URL untuk melihat cara kerja aplikasi Anda. Setiap kali Anda membuka URL atau memuat ulang halaman, Anda akan melihat lima kunjungan terbaru yang ditampilkan sebagai JSON.

7. Selamat

Anda telah men-deploy aplikasi Go di Cloud Run yang dapat terhubung ke database PostgreSQL yang berjalan di Cloud SQL.

Yang telah kita bahas:

  • Membuat database Cloud SQL untuk PostgreSQL
  • Men-deploy aplikasi Go ke Cloud Run
  • Menghubungkan aplikasi Anda ke Cloud SQL menggunakan Konektor Go

Pembersihan

Agar tidak menimbulkan biaya pada akun Google Cloud Anda untuk resource yang digunakan dalam tutorial ini, hapus project yang berisi resource tersebut, atau simpan project dan hapus setiap resource. Jika ingin menghapus seluruh project, Anda dapat menjalankan:

gcloud projects delete ${GOOGLE_CLOUD_PROJECT}