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}