バージョン管理から Cloud Run に生成 AI Go ウェブアプリを自動的にデプロイする

1. 概要

初めてウェブ アプリケーションをデプロイするのは、気が重いかもしれません。最初のデプロイ後も、プロセスが複雑すぎると、アプリケーションの新しいバージョンのデプロイを避ける可能性があります。継続的デプロイを使用すると、アプリケーションの変更を簡単に自動的にデプロイできます。

このラボでは、ウェブ アプリケーションを作成し、アプリケーションのソースコードが変更されたときにアプリケーションを自動的にデプロイするように Cloud Run を構成します。その後、アプリケーションを変更して再度デプロイします。

学習内容

  • Cloud Shell エディタでウェブ アプリケーションを作成する
  • GitHub にアプリケーション コードを保存する
  • アプリケーションを Cloud Run に自動的にデプロイする
  • Vertex AI を使用してアプリケーションに生成 AI を追加する

2. 前提条件

  1. Google アカウントをまだお持ちでない場合は、Google アカウントを作成する必要があります。
    • 仕事用または学校用アカウントではなく、個人アカウントを使用します。職場用アカウントと学校用アカウントには、このラボに必要な API を有効にできないようにする制限が設定されている場合があります。
  2. GitHub アカウントをお持ちでない場合は、GitHub アカウントを作成する必要があります。
    • GitHub アカウントをお持ちの場合は、そのアカウントを使用してください。GitHub では、新しいアカウントが迷惑メールとしてブロックされることがよくあります。
    • GitHub アカウントで 2 要素認証を構成して、アカウントがスパムとしてマークされる可能性を減らしてください。

3. プロジェクトの設定

  1. Google Cloud コンソールにログインします。
  2. Cloud コンソールで課金を有効にします
    • このラボを完了するのにかかる Cloud リソースの費用は 1 米ドル未満です。
    • このラボの最後の手順に沿ってリソースを削除すると、それ以上の料金は発生しません。
    • 新規ユーザーは、300 米ドル分の無料トライアルをご利用いただけます。
    • Gen AI for Devs イベントに参加しますか?1 米ドル相当のクレジットを利用できる場合があります。
  3. 新しいプロジェクトを作成するか、既存のプロジェクトを再利用します。
  4. Cloud Billing の [マイ プロジェクト] で課金が有効になっていることを確認します。
    • 新しいプロジェクトの Billing account 列に Billing is disabled と表示されている場合:
      1. Actions 列のその他アイコンをクリックします。
      2. [お支払い情報を変更] をクリックします。
      3. 使用する請求先アカウントを選択します
    • Gen AI for Devs イベントに参加している場合は、アカウントの名前が Google Cloud Platform Trial Billing Account になっている可能性があります。

4. Cloud Shell エディタを開く

  1. Cloud Shell エディタに移動します。
  2. ターミナルが画面の下部に表示されない場合は、開きます。
    • ハンバーガー メニュー ハンバーガー メニュー アイコン をクリックします。
    • [Terminal] をクリックします。
    • [New Terminal] をクリックします。Cloud Shell エディタで新しいターミナルを開く
  3. ターミナルで、次のコマンドを使用してプロジェクトを設定します。
    • 形式:
      gcloud config set project [PROJECT_ID]
      
    • 例:
      gcloud config set project lab-project-id-example
      
    • プロジェクト ID を忘れた場合:
      • 次のコマンドを使用すると、すべてのプロジェクト ID を一覧表示できます。
        gcloud projects list | awk '/PROJECT_ID/{print $2}'
        
      Cloud Shell エディタのターミナルでプロジェクト ID を設定する
  4. 承認を求められたら、[承認] をクリックして続行します。Cloud Shell を承認する
  5. 次のようなメッセージが表示されます。
    Updated property [core/project].
    
    WARNING が表示され、Do you want to continue (Y/N)? と表示された場合は、プロジェクト ID が正しく入力されていない可能性があります。N を押して Enter を押し、gcloud config set project コマンドを再実行します。

5. API を有効にする

ターミナルで API を有効にします。

gcloud services enable \
  run.googleapis.com \
  cloudbuild.googleapis.com \
  aiplatform.googleapis.com

このコマンドが完了するまで数分かかる場合がありますが、最終的には次のような成功メッセージが表示されます。

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

6. Git を構成する

  1. グローバル Git ユーザーのメールを設定します。
    git config --global user.email "you@example.com"
    
  2. グローバル Git ユーザー名を設定します。
    git config --global user.name "Your Name"
    
  3. グローバル Git のデフォルト ブランチを main に設定します。
    git config --global init.defaultBranch main
    

7. コードを記述する

Go でアプリケーションを作成するには:

  1. ホーム ディレクトリに移動します。
    cd ~
    
  2. codelab-genai ディレクトリを作成します。
    mkdir codelab-genai
    
  3. codelab-genai ディレクトリに移動します。
    cd codelab-genai
    
  4. go.mod ファイルを初期化してモジュールを宣言します。
    go mod init codelab-genai
    
  5. main.go ファイルを作成します。
    touch main.go
    
  6. Cloud Shell エディタで main.go ファイルを開きます。
    cloudshell edit main.go
    
    画面の上部に空のファイルが表示されます。この main.go ファイルを編集できます。コードが画面の上部に表示されることを示す
  7. main.go を編集して、次のコードを貼り付けます。
    package main
    
    import (
        "fmt"
        "log"
        "net/http"
        "os"
    )
    
    func main() {
        http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
            fmt.Fprintln(w, "Hello, world!")
        })
    
        port := os.Getenv("PORT")
    
        if port == "" {
            port = "8080"
        }
        if err := http.ListenAndServe(":"+port, nil); err != nil {
            log.Fatal(err)
        }
    }
    
    数秒後に、Cloud Shell エディタがコードを自動的に保存します。このコードは、「Hello world!」という応答メッセージで HTTP リクエストに応答します。

アプリケーションの初期コードが完成し、バージョン管理に保存できるようになりました。

8. リポジトリを作成する

  1. 画面下部の Cloud Shell ターミナルに戻ります。
  2. 正しいディレクトリにいることを確認します。
    cd ~/codelab-genai
    
  3. Git リポジトリを初期化する
    git init -b main
    
  4. GitHub CLI にログインします
    gh auth login
    
    Enter を押してデフォルトのオプションを承認し、GitHub CLI ツールに表示される手順に沿って操作します。手順には次のものがあります。
    1. ログインするアカウントを選択してください。 GitHub.com
    2. このホストでの Git オペレーションに使用するプロトコルは何ですか? HTTPS
    3. GitHub 認証情報を使用して Git を認証しますか?Y(表示されない場合はスキップします)。
    4. GitHub CLI の認証方法を選択してください。 Login with a web browser
    5. ワンタイム コードをコピーする
    6. https://github.com/login/device を開きます。
    7. ワンタイム コードを貼り付ける
    8. [Authorize github] をクリックします。
    9. ログインを完了する
  5. ログインしていることを確認します。
    gh api user -q ".login"
    
    正常にログインできていると、GitHub ユーザー名が表示されます。
  6. GITHUB_USERNAME 変数を作成する
    GITHUB_USERNAME=$(gh api user -q ".login")
    
  7. 環境変数が作成されたことを確認します。
    echo ${GITHUB_USERNAME}
    
    変数が正常に作成されていると、GitHub ユーザー名が表示されます。
  8. codelab-genai という名前の空の GitHub リポジトリを作成します。
    gh repo create codelab-genai --private
    
    次のエラーが表示された場合:
    GraphQL: Name already exists on this account (createRepository)
    
    この場合、codelab-genai という名前のリポジトリはすでに存在します。このチュートリアルを続行するには、次の 2 つの方法があります。
  9. codelab-genai リポジトリをリモート origin として追加します。
    git remote add origin https://github.com/${GITHUB_USERNAME}/codelab-genai
    

9. コードを共有する

  1. 正しいディレクトリにいることを確認します。
    cd ~/codelab-genai
    
  2. 現在のディレクトリ内のすべてのファイルをこの commit に追加します。
    git add .
    
  3. 最初の commit を作成します。
    git commit -m "add http server"
    
  4. commit を origin リポジトリの main ブランチに push します。
    git push -u origin main
    

次のコマンドを実行し、結果の URL にアクセスすると、GitHub でアプリケーション コードを表示できます。

echo -e "\n\nTo see your code, visit this URL:\n \
    https://github.com/${GITHUB_USERNAME}/codelab-genai/blob/main/main.go \n\n"

10. 自動デプロイを設定する

  1. Cloud Shell エディタのタブは開いたままにします。このタブには後で戻ります。
  2. 新しいタブで、Cloud Run ページにアクセスします。
  3. コンソール Google Cloud Console のプロジェクト プルダウン で正しい Google Cloud プロジェクトを選択します。
  4. [リポジトリを接続] をクリックします。
  5. [Cloud Build の設定] をクリックします。
    1. [リポジトリ プロバイダ] で [GitHub] を選択します。
      • ブラウザで GitHub アカウントにログインしていない場合は、認証情報を使用してログインします。
    2. [認証]、[続行] の順にクリックします。
    3. ログインすると、Cloud Run ページに「GitHub アプリは、どのリポジトリにもインストールされていません。」というメッセージが表示されます。
    4. [Google Cloud Build をインストール] ボタンをクリックします。
      • [Installation Setup] ページで、[Only select repositories] を選択し、CLI で作成した codelab-genai リポジトリを選択します。
      • [インストール] をクリックします。
      • 注: GitHub リポジトリが多い場合、読み込みに数分かかることがあります。
    5. [リポジトリ] として your-user-name/codelab-genai を選択します。
      • リポジトリが表示されない場合は、[接続されたリポジトリを管理します] リンクをクリックします。
    6. [ブランチ] は ^main$ のままにします。
    7. [Go、Node.js、Python、Java、.NET Core、Ruby、PHP(Google Cloud の Buildpacks を使用)] をクリックします。
      • 他のフィールド(Build context directoryEntrypointFunction target)はそのままにします。
    8. [保存] をクリックします。
  6. [認証] まで下にスクロールします。
  7. [未認証の呼び出しを許可する] をクリックします。
  8. [作成] をクリックします。

ビルドが完了したら(数分かかります)、次のコマンドを実行し、結果の URL にアクセスして実行中のアプリケーションを表示します。

echo -e "\n\nOnce the build finishes, visit your live application:\n \
    "$( \
        gcloud run services list | \
        grep codelab-genai | \
        awk '/URL/{print $2}' | \
        head -1 \
    )" \n\n"

11. コードを変更する

  1. 画面下部の Cloud Shell ターミナルに戻ります。
  2. 正しいディレクトリにいることを確認します。
    cd ~/codelab-genai
    
  3. Cloud Shell エディタで main.go を再度開く
    cloudshell edit main.go
    
  4. Vertex AI SDK for Go をインストールします。
    go get cloud.google.com/go/vertexai/genai
    
  5. Go 用の Metadata ライブラリをインストールして、現在のプロジェクト ID を取得します。
    go get cloud.google.com/go/compute/metadata
    
  6. main.go ファイルのコードを次のコードに置き換えます。
    package main
    
    import (
        "context"
        "fmt"
        "log"
        "net/http"
        "os"
    
        "cloud.google.com/go/compute/metadata"
        "cloud.google.com/go/vertexai/genai"
    )
    
    func main() {
        ctx := context.Background()
        var projectId string
        var err error
        projectId = os.Getenv("GOOGLE_CLOUD_PROJECT")
        if projectId == "" {
            projectId, err = metadata.ProjectIDWithContext(ctx)
            if err != nil {
                return
            }
        }
        var client *genai.Client
        client, err = genai.NewClient(ctx, projectId, "us-central1")
        if err != nil {
            return
        }
        defer client.Close()
    
        model := client.GenerativeModel("gemini-1.5-flash-001")
    
        http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
            animal := r.URL.Query().Get("animal")
            if animal == "" {
                animal = "dog"
            }
    
            resp, err := model.GenerateContent(
                ctx,
                genai.Text(
                    fmt.Sprintf("Give me 10 fun facts about %s. Return the results as HTML without markdown backticks.", animal)),
            )
    
            if err != nil {
                w.WriteHeader(http.StatusServiceUnavailable)
                return
            }
    
            if len(resp.Candidates) > 0 && len(resp.Candidates[0].Content.Parts) > 0 {
                htmlContent := resp.Candidates[0].Content.Parts[0]
                w.Header().Set("Content-Type", "text/html; charset=utf-8")
                fmt.Fprint(w, htmlContent)
            }
        })
    
        port := os.Getenv("PORT")
    
        if port == "" {
            port = "8080"
        }
        if err := http.ListenAndServe(":"+port, nil); err != nil {
            log.Fatal(err)
        }
    }
    

12. 再デプロイ

  1. Cloud Shell で正しいディレクトリにいることを確認します。
    cd ~/codelab-genai
    
  2. 次のコマンドを実行して、アプリケーションの新しいバージョンをローカルの git リポジトリに commit します。
    git add .
    git commit -m "add latest changes"
    
  3. 変更を GitHub に push します。
    git push
    
  4. ビルドが完了したら、次のコマンドを実行して、デプロイされたアプリケーションにアクセスします。
    echo -e "\n\nOnce the build finishes, visit your live application:\n \
        "$( \
            gcloud run services list | \
            grep codelab-genai | \
            awk '/URL/{print $2}' | \
            head -1 \
        )" \n\n"
    

変更が反映されるまでに数分かかることがあります。

すべてのリビジョンの履歴は、https://console.cloud.google.com/run/detail/us-central1/codelab-genai/revisions で確認できます。

13. (省略可)Vertex AI の使用状況を監査する

他の Google Cloud サービスと同様に、Vertex AI オペレーションを監査できます。監査ログは、「誰が、いつ、どこで何をしたか」の確認に役立ちます。Vertex AI の管理監査ログはデフォルトで有効になっています。コンテンツを生成するリクエストを監査するには、データアクセス監査ログを有効にする必要があります。

  1. Google Cloud コンソールで、[監査ログ] ページに移動します。

    このページを検索バーで検索する場合は、小見出しが「IAM と管理」の結果を選択します。
  2. 既存の Google Cloud プロジェクトが、Cloud Run アプリケーションを作成するプロジェクトであることを確認します。
  3. [データアクセス監査ログの構成] テーブルで、[サービス] 列から Vertex AI API を選択します。
  4. [ログタイプ] タブで、データアクセス監査ログのタイプ Admin readData read を選択します。
  5. [保存] をクリックします。

有効にすると、アプリケーションの呼び出しごとに監査ログを表示できます。呼び出しの詳細を含む監査ログを表示する手順は次のとおりです。

  1. デプロイしたアプリケーションに戻り、ページを更新してログをトリガーします。
  2. Google Cloud コンソールで、[ログ エクスプローラ] ページに移動します。

  3. クエリ ウィンドウに次のように入力します。
    LOG_ID("cloudaudit.googleapis.com%2Fdata_access")
    protoPayload.serviceName="aiplatform.googleapis.com"
    
  4. [クエリを実行] をクリックします。

監査ログは Vertex AI API の使用状況をキャプチャしますが、プロンプトやレスポンスの詳細などのワークロード関連データをモニタリングすることはできません。

14. (省略可)AI ワークロードのオブザーバビリティを高める

監査ログには、ワークロード関連の情報は記録されません。ワークロードのオブザーバビリティを高めるには、この情報を明示的にロギングする必要があります。これには、お気に入りのロギング フレームワークを使用できます。次の手順では、Go の構造化ロギング ライブラリを使用してこれを行う方法の 1 つを示します。

  1. Cloud Shell エディタで main.go を再度開く
    cloudshell edit ~/codelab-genai/main.go
    
  2. インポート ブロックを変更して、Go の構造化ロギング ライブラリと JSON ライブラリを含めます。
    import (
        "context"
        "encoding/json"
        "fmt"
        "log"
        "log/slog"
        "net/http"
        "os"
    
        "cloud.google.com/go/compute/metadata"
        "cloud.google.com/go/vertexai/genai"
    )
    
  3. Vertex クライアントを初期化したら(33 行目)、次の行を追加して、Google Cloud Logging の適切なフィールドを使用する構造化ロガーを初期化します。
    opts := &slog.HandlerOptions{
    	Level: slog.LevelDebug,
    	ReplaceAttr: func(group []string, a slog.Attr) slog.Attr {
            if a.Key == slog.LevelKey {
                return slog.Attr{Key: "severity", Value: a.Value}
            }
            if a.Key == slog.MessageKey {
                return slog.Attr{Key: "message", Value: a.Value}
            }
            return slog.Attr{Key: a.Key, Value: a.Value}
    	},
    }
    
    jsonHandler := slog.NewJSONHandler(os.Stdout, opts)
    slog.SetDefault(slog.New(jsonHandler))
    
  4. GenerateContent へのレスポンスを確認した後(69 行目)、if ブロック内に次の行を追加します。
    jsonBytes, err := json.Marshal(resp)
    if err != nil {
        slog.Error("Failed to marshal response to JSON", "error", err)
    } else {
        jsonString := string(jsonBytes)
        slog.Debug("Complete response content", "json_response", jsonString)
    }
    
    このコードは、構造化ロギング形式を使用して、生成されたコンテンツに関する情報を stdout に書き込みます。Cloud Run のロギング エージェントは、stdout に出力された内容をキャプチャし、この形式で Cloud Logging に書き込みます
  5. Cloud Shell を再度開き、次のコマンドを入力して、正しいディレクトリにいることを確認します。
    cd ~/codelab-genai
    
  6. 変更を commit します。
    git commit -am "Observe generated content"
    
  7. 変更を GitHub に push して、変更されたバージョンの再デプロイをトリガーします。
    git push
    

新しいバージョンをデプロイすると、Vertex AI への呼び出しに関するデバッグ情報を確認できます。

アプリケーション ログを表示する手順は次のとおりです。

  1. Google Cloud コンソールで、[ログ エクスプローラ] ページに移動します。

  2. クエリ ウィンドウに次のように入力します。
    LOG_ID("run.googleapis.com%2Fstdout")
    severity=DEBUG
    
  3. [クエリを実行] をクリックします。

クエリの結果には、プロンプトと Vertex AI レスポンスを含むログが表示されます。このログには、安全対策のモニタリングに使用できる「安全性評価」が含まれています。

15. (省略可)クリーンアップ

サービスが使用されていない場合、Cloud Run の料金は発生しませんが、コンテナ イメージを Artifact Registry に保存すると課金される場合があります。Cloud プロジェクトを削除して、料金が発生しないようにすることができます。Cloud プロジェクトを削除すると、そのプロジェクト内で使用されているすべてのリソースに対する課金が停止します。

必要に応じて、プロジェクトを削除します。

gcloud projects delete $GOOGLE_CLOUD_PROJECT

cloudshell ディスクから不要なリソースを削除することもできます。次のことが可能です。

  1. Codelab プロジェクト ディレクトリを削除します。
    rm -rf ~/codelab-genai
    
  2. 不要になった Go パッケージをクリーンアップします。
    cd ~
    go clean -modcache
    
  3. 警告: この操作は元に戻せません。Cloud Shell のすべてのデータを削除して空き容量を増やす場合は、ホーム ディレクトリ全体を削除できます。残しておきたいものはすべて別の場所に保存されていることを確認してください。
    sudo rm -rf $HOME
    

16. 完了

このラボでは、ウェブ アプリケーションを作成し、アプリケーションのソースコードが変更されたときにアプリケーションを自動的にデプロイするように Cloud Run を構成しました。その後、アプリケーションを変更して再度デプロイしました。

このラボが気に入った場合は、別のコーディング言語またはフレームワークで再度お試しください。

本日ご利用いただいたサービスを改善するためのユーザー エクスペリエンス(UX)調査にご協力いただける場合は、こちらからご登録ください

学習を継続するためのオプションをいくつかご紹介します。