この Codelab について
1. 概要
Cloud SQL Go コネクタは、Go アプリケーションを Cloud SQL データベースに安全に接続する最も簡単な方法です。Cloud Run はフルマネージドのサーバーレス プラットフォームで、HTTP リクエスト経由で呼び出し可能なステートレス コンテナを実行できます。この Codelab では、IAM 認証を使用して、サービス アカウントを使用して Cloud Run 上の Go アプリケーションを Cloud SQL for PostgreSQL データベースに安全に接続する方法を説明します。
学習内容
このラボでは、次の方法について学びます。
- Cloud SQL for PostgreSQL データベースを作成する
- Go アプリケーションを Cloud Run にデプロイする
- Go Connector を使用してアプリケーションを Cloud SQL に接続する
前提条件
- このラボは、Cloud コンソール環境と Cloud Shell 環境に精通していることを前提としています。
2. 始める前に
Cloud プロジェクトの設定
- Google Cloud Console にログインして、プロジェクトを新規作成するか、既存のプロジェクトを再利用します。Google アカウントをまだお持ちでない場合は、アカウントを作成してください。
- プロジェクト名は、このプロジェクトの参加者に表示される名称です。Google API では使用されない文字列です。この値はいつでも更新できます。
- プロジェクト ID は、すべての Google Cloud プロジェクトにおいて一意でなければならず、不変です(設定後は変更できません)。Cloud コンソールでは一意の文字列が自動生成されます。通常、それが何であるかは関係ありません。ほとんどの Codelab では、プロジェクト ID を参照する必要があります(通常は
PROJECT_ID
として識別されます)。生成された ID が気に入らない場合は、別のランダムな ID を生成できます。または、ご自身でお試しになることもできます。このステップを終えた後は変更できず、プロジェクト期間中は維持されます。 - なお、3 つ目の値は、一部の API で使用される [プロジェクト番号] です。これら 3 つの値について詳しくは、こちらのドキュメントをご覧ください。
- 次に、Cloud のリソースや API を使用するために、Cloud コンソールで課金を有効にする必要があります。この Codelab の操作をすべて行って、費用が生じたとしても、少額です。このチュートリアルの終了後に課金が発生しないようにリソースをシャットダウンするには、作成したリソースを削除するか、プロジェクト全体を削除します。Google Cloud の新規ユーザーは、300 米ドル分の無料トライアル プログラムをご利用いただけます。
環境設定
検索バーの右側にあるアイコンをクリックして Cloud Shell をアクティブにします。
Cloud Shell から API を有効にします。
gcloud services enable compute.googleapis.com sqladmin.googleapis.com \
run.googleapis.com artifactregistry.googleapis.com \
cloudbuild.googleapis.com servicenetworking.googleapis.com
承認するよう求められたら、[承認] をクリックします。] をクリックしてください。
このコマンドが完了するまでに数分かかる場合がありますが、最終的に次のようなメッセージが正常に出力されます。
Operation "operations/acf.p2-327036483151-73d90d00-47ee-447a-b600-a6badf0eceae" finished successfully.
3. サービス アカウントを設定する
Cloud Run で使用する Google Cloud サービス アカウントを作成して構成し、Cloud SQL に接続するための適切な権限を付与する。
- 次のように
gcloud iam service-accounts create
コマンドを実行して、新しいサービス アカウントを作成します。gcloud iam service-accounts create quickstart-service-account \
--display-name="Quickstart Service Account" - 次のように gcloud projects add-iam-policy-binding コマンドを実行して、作成した Google Cloud サービス アカウントに Cloud SQL Client ロールを追加します。Cloud Shell では、式
${GOOGLE_CLOUD_PROJECT}
は実際のプロジェクトの名前に置き換えられます。ご希望であれば、手動で交換することもできます。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 サービス アカウントに Cloud SQL インスタンス ユーザーのロールを追加します。
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 サービス アカウントにログ書き込みロールを追加します。
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. Cloud SQL の設定
gcloud sql instances create
コマンドを実行して、Cloud SQL インスタンスを作成します。
- –database-version: データベース エンジンのタイプとバージョン。指定しない場合は、API のデフォルトが使用されます。現在利用可能なバージョンを確認するには、gcloud database versions ドキュメントをご覧ください。
- –cpu: マシンに必要なコア数。
- –memory: マシンに必要なメモリ量を示す整数値。単位を指定する必要があります(例: 3, 072 MB、9 GB)。単位を指定しない場合、GB が使用されます。
- –region: インスタンスのリージョンのロケーション(例: us-central1、asia-east1、us-east1)。
- –database-flags: フラグの設定を許可します。ここでは
cloudsql.iam_authentication
を有効にし、前に作成したサービス アカウントを使用して Cloud Run が Cloud SQL に接続できるようにします。gcloud sql instances create quickstart-instance \
--database-version=POSTGRES_14 \
--cpu=1 \
--memory=4GB \
--region=us-central1 \
--database-flags=cloudsql.iam_authentication=on
このコマンドが完了するまで数分かかることがあります。
gcloud sql databases create
コマンドを実行して、quickstart-instance
内に Cloud SQL データベースを作成します。
gcloud sql databases create quickstart_db \
--instance=quickstart-instance
前に作成したサービス アカウントに PostgreSQL データベース ユーザーを作成して、データベースにアクセスします。
gcloud sql users create quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam \
--instance=quickstart-instance \
--type=cloud_iam_service_account
5. 申請の準備
HTTP リクエストに応答する Go アプリケーションを準備します。
- Cloud Shell で、
helloworld
という名前の新しいディレクトリを作成し、そのディレクトリに移動します。mkdir helloworld
cd helloworld go mod init
を実行して、新しい Go アプリケーションを初期化します。go mod init github.com/GoogleCloudPlatform/golang-samples/run/helloworld
- Cloud SQL Go Connector の依存関係をインストールします。
go get cloud.google.com/go/cloudsqlconn
go get cloud.google.com/go/cloudsqlconn/postgres/pgxv4 - アプリケーション コードを含む
main.go
ファイルを作成します。このコードを使用して次のことができます。- HTTP リクエストを受け入れる
- データベースに接続する
- HTTP リクエストの時刻をデータベースに保存する
- 直近の 5 つのリクエストの時間を返す
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
このコードは、PORT 環境変数で定義されたポートをリッスンする基本的なウェブサーバーを作成します。これで、アプリケーションをデプロイする準備が整いました。
6. Cloud Run アプリケーションをデプロイする
次のコマンドを実行して、アプリケーションをデプロイします。
- –region: インスタンスのリージョンのロケーション(例: us-central1、asia-east1、us-east1)。
- –source: デプロイされるソースコード。この場合、
.
は現在のフォルダhelloworld
内のソースコードを参照します。 - –set-env-vars: アプリケーションを Cloud SQL データベースに転送するためにアプリケーションが使用する環境変数を設定します。
- –service-account: Cloud Run デプロイメントを、この Codelab の冒頭で作成した Cloud SQL データベースに接続する権限を持つサービス アカウントに結び付けます。
- –allow-unauthenticated: 未認証のリクエストを許可し、インターネットからアプリケーションにアクセスできるようにします。
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
プロンプトが表示されたら、y
と Enter
キーを押して続行します。
Do you want to continue (Y/n)? y
数分後、アプリケーションからアクセスするための URL が表示されます。
この URL に移動して、アプリケーションの動作を確認します。URL にアクセスするかページを更新するたびに、直近 5 件の訪問が JSON として返されます。
7. 完了
Cloud SQL で実行されている PostgreSQL データベースに接続できる Go アプリケーションを Cloud Run にデプロイしました。
学習した内容
- Cloud SQL for PostgreSQL データベースの作成
- Cloud Run に Go アプリケーションをデプロイする
- Go コネクタを使用してアプリケーションを Cloud SQL に接続する
クリーンアップ
このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。プロジェクト全体を削除する場合は、次のコマンドを実行します。
gcloud projects delete ${GOOGLE_CLOUD_PROJECT}