読み込んでいます...
一致する結果は見つかりませんでした。

Google Cloud コンソールでスキルを試す

700 以上のラボとコースにアクセス

Go と Cloud Run を使用した REST API の開発

ラボ 1時間 universal_currency_alt クレジット: 5 show_chart 中級
info このラボでは、学習をサポートする AI ツールが組み込まれている場合があります。
700 以上のラボとコースにアクセス

GSP761

Google Cloud セルフペース ラボのロゴ

Pet Theory のロゴ

概要

サーバーレス Cloud Run 開発」コースのラボでは、架空のビジネス シナリオの登場人物を支援してサーバーレスへの移行計画を進めていきます。

Lily さんは 12 年前、獣医クリニック チェーン「Pet Theory」を開業しました。チェーンが拡大するに伴い、Lily さんはペットの治療よりも、保険会社との電話のやり取りに時間を取られるようになっています。Lily さんは、保険会社が治療の総費用だけをオンラインで確認できるようになればいいのに、と考えています。

このシリーズのラボでは、以前、コンピュータ コンサルタントの Ruby さんと DevOps エンジニアの Patrick さんが Pet Theory の顧客データベースをクラウドでのサーバーレス Firestore データベースに移行し、顧客がデータベースにアクセスしてオンラインで予約を取れるようにしました。しかし Pet Theory の運用チームは 1 人だけなので、継続的なメンテナンスをあまり必要としないサーバーレス ソリューションが求められます。

このラボでは、Ruby さんと Patrick さんの作業をサポートして、顧客の個人情報(PII)を公開せずに、保険会社が顧客データにアクセスできるようにします。サーバーレスの Cloud Run を使用して、安全な Representational State Transfer(REST)API ゲートウェイをビルドします。これにより、顧客の PII を非開示にしたまま、保険会社に治療の総費用を開示できるようになります。

目標

このラボでは、次の作業を行います。

  • Go を使用して REST API を開発する
  • テスト用の顧客データを Firestore に読み込む
  • REST API を Firestore データベースに接続する
  • REST API を Cloud Run にデプロイする

前提条件

これは中級レベルのラボです。Cloud コンソール環境と Cloud Shell 環境に精通していることを前提としています。このラボは、シリーズの一部です。次のような先行のラボを受講していれば役立ちますが、必須ではありません。

  • サーバーレス データベースへデータを読み込む
  • サーバーレス ウェブアプリを Firebase と Firestore でビルドする
  • PDF ファイルを作成するサーバーレス アプリをビルドする

設定と要件

[ラボを開始] ボタンをクリックする前に

こちらの説明をお読みください。ラボには時間制限があり、一時停止することはできません。タイマーは、Google Cloud のリソースを利用できる時間を示しており、[ラボを開始] をクリックするとスタートします。

このハンズオンラボでは、シミュレーションやデモ環境ではなく実際のクラウド環境を使って、ラボのアクティビティを行います。そのため、ラボの受講中に Google Cloud にログインおよびアクセスするための、新しい一時的な認証情報が提供されます。

このラボを完了するためには、下記が必要です。

  • 標準的なインターネット ブラウザ(Chrome を推奨)
注: このラボの実行には、シークレット モード(推奨)またはシークレット ブラウジング ウィンドウを使用してください。これにより、個人アカウントと受講者アカウント間の競合を防ぎ、個人アカウントに追加料金が発生しないようにすることができます。
  • ラボを完了するための時間(開始後は一時停止できません)
注: このラボでは、受講者アカウントのみを使用してください。別の Google Cloud アカウントを使用すると、そのアカウントに料金が発生する可能性があります。

ラボを開始して Google Cloud コンソールにログインする方法

  1. [ラボを開始] ボタンをクリックします。ラボの料金をお支払いいただく必要がある場合は、表示されるダイアログでお支払い方法を選択してください。 左側の [ラボの詳細] ペインには、以下が表示されます。

    • [Google Cloud コンソールを開く] ボタン
    • 残り時間
    • このラボで使用する必要がある一時的な認証情報
    • このラボを行うために必要なその他の情報(ある場合)
  2. [Google Cloud コンソールを開く] をクリックします(Chrome ブラウザを使用している場合は、右クリックして [シークレット ウィンドウで開く] を選択します)。

    ラボでリソースがスピンアップし、別のタブで [ログイン] ページが表示されます。

    ヒント: タブをそれぞれ別のウィンドウで開き、並べて表示しておきましょう。

    注: [アカウントの選択] ダイアログが表示されたら、[別のアカウントを使用] をクリックします。
  3. 必要に応じて、下のユーザー名をコピーして、[ログイン] ダイアログに貼り付けます。

    {{{user_0.username | "Username"}}}

    [ラボの詳細] ペインでもユーザー名を確認できます。

  4. [次へ] をクリックします。

  5. 以下のパスワードをコピーして、[ようこそ] ダイアログに貼り付けます。

    {{{user_0.password | "Password"}}}

    [ラボの詳細] ペインでもパスワードを確認できます。

  6. [次へ] をクリックします。

    重要: ラボで提供された認証情報を使用する必要があります。Google Cloud アカウントの認証情報は使用しないでください。 注: このラボでご自身の Google Cloud アカウントを使用すると、追加料金が発生する場合があります。
  7. その後次のように進みます。

    • 利用規約に同意してください。
    • 一時的なアカウントなので、復元オプションや 2 要素認証プロセスは設定しないでください。
    • 無料トライアルには登録しないでください。

その後、このタブで Google Cloud コンソールが開きます。

注: Google Cloud のプロダクトやサービスにアクセスするには、ナビゲーション メニューをクリックするか、[検索] フィールドにサービス名またはプロダクト名を入力します。 ナビゲーション メニュー アイコンと検索フィールド

Cloud Shell をアクティブにする

Cloud Shell は、開発ツールと一緒に読み込まれる仮想マシンです。5 GB の永続ホーム ディレクトリが用意されており、Google Cloud で稼働します。Cloud Shell を使用すると、コマンドラインで Google Cloud リソースにアクセスできます。

  1. Google Cloud コンソールの上部にある「Cloud Shell をアクティブにする」アイコン 「Cloud Shell をアクティブにする」アイコン をクリックします。

  2. ウィンドウで次の操作を行います。

    • Cloud Shell 情報ウィンドウで操作を進めます。
    • Cloud Shell が認証情報を使用して Google Cloud API を呼び出すことを承認します。

接続した時点で認証が完了しており、プロジェクトに各自の Project_ID が設定されます。出力には、このセッションの PROJECT_ID を宣言する次の行が含まれています。

Your Cloud Platform project in this session is set to {{{project_0.project_id | "PROJECT_ID"}}}

gcloud は Google Cloud のコマンドライン ツールです。このツールは、Cloud Shell にプリインストールされており、タブ補完がサポートされています。

  1. (省略可)次のコマンドを使用すると、有効なアカウント名を一覧表示できます。
gcloud auth list
  1. [承認] をクリックします。

出力:

ACTIVE: * ACCOUNT: {{{user_0.username | "ACCOUNT"}}} To set the active account, run: $ gcloud config set account `ACCOUNT`
  1. (省略可)次のコマンドを使用すると、プロジェクト ID を一覧表示できます。
gcloud config list project

出力:

[core] project = {{{project_0.project_id | "PROJECT_ID"}}} 注: Google Cloud における gcloud ドキュメントの全文については、gcloud CLI の概要ガイドをご覧ください。

Lily

Lily さん(Pet Theory の創業者)

Ruby さん、こんにちは。

先週、保険会社に関する事務処理や電話でのやり取りに追われていることについて、お話ししました。保険会社の担当者が、安全かつ効率的な方法で、顧客レコードにアクセスできる方法があればいいのに、と思っています。

現状の作業負荷ではこの先、無理が生じてしまいます。アドバイスをいただけませんか?

Lily

Ruby

Ruby さん(ソフトウェア コンサルタント)

Lily さん、こんにちは。

先日 Patrick さんとのランチ ミーティングで、承認された第三者が貴社のデジタル レコードに安全かつ簡単にアクセスできる方法について計画を作成しました。

この計画は次の 4 ステップで進めます。

  1. シンプルな REST API をビルドする。
  2. 顧客テストデータを読み込む。
  3. REST API を顧客データベースに接続する。
  4. 認証を REST API に追加する。

ステップ 1 と 2 についてはすでに見通しが立っていて、順調なスタートといって良いと思います。今週中には実用的なプロトタイプが完成する予定です。

Ruby

Ruby さんが Pet Theory 用の REST API のビルドに必要なアクティビティを管理する作業をサポートしていきましょう。

タスク 1. Google API を有効にする

このラボでは、2 つの API があらかじめ有効になっています。

名前 API
Cloud Build cloudbuild.googleapis.com
Cloud Run 管理者 run.googleapis.com

タスク 2. REST API を開発する

  1. プロジェクトを有効にします。
gcloud config set project $(gcloud projects list --format='value(PROJECT_ID)' --filter='qwiklabs-gcp')
  1. pet-theory リポジトリのクローンを作成し、ソースコードにアクセスします。
git clone https://github.com/rosera/pet-theory.git && cd pet-theory/lab08
  1. 使い慣れたテキスト エディタを使うか、Cloud Shell リボンのコードエディタ ボタンを押して、go.mod ファイルと go.sum ファイルを表示します。

  2. ファイル main.go を作成し、次のコードをファイルに追加します。

package main import ( "fmt" "log" "net/http" "os" ) func main() { port := os.Getenv("PORT") if port == "" { port = "8080" } http.HandleFunc("/v1/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "{status: 'running'}") }) log.Println("Pets REST API listening on port", port) if err := http.ListenAndServe(":"+port, nil); err != nil { log.Fatalf("Error launching Pets REST API server: %v", err) } } 注: サービスが想定どおりに稼働するかをテストするために、上記のコードでエンドポイントを作成します。サービス URL に「/v1/」を追加することで、アプリケーションが想定どおりに機能することを検証することができます。Cloud Run ではコンテナがデプロイされるので、コンテナ定義を設定する必要があります。「Dockerfile」というファイルは、使用する Go のバージョン、アプリに含めるファイル、コードの開始方法を Cloud Run に指示します。
  1. Dockerfile という名前のファイルを作成し、次のコードをファイルに追加します。
FROM gcr.io/distroless/base-debian12 WORKDIR /usr/src/app COPY server . CMD [ "/usr/src/app/server" ]

ファイル server は、main.go からビルドされた実行バイナリです。

  1. バイナリをビルドするため次のコマンドを実行します。
go build -o server
  1. ビルドコマンドを実行したら、必要な Dockerfile とサーバーが同じディレクトリ内にあることを確認します。
ls -la . ├── Dockerfile ├── go.mod ├── go.sum ├── main.go └── server

Cloud Run の Go ベースのアプリの多くでは、通常、上記のようなテンプレート Dockerfile を変更せずに使用できます。

  1. 次のコードを実行して、シンプルな REST API をデプロイします。
gcloud builds submit \ --tag gcr.io/$GOOGLE_CLOUD_PROJECT/rest-api:0.1

このコマンドは、コードでコンテナをビルドし、プロジェクトの Artifact Registry にそのコンテナを配置します。ナビゲーション メニューナビゲーション メニュー アイコン)で、[すべてのプロダクトを表示] > [CI / CD] > [Artifact Registry] をクリックし、gcr.io リポジトリをクリックすると、コンテナを表示できます。rest-api が表示されない場合は、[更新] をクリックします。

Artifact Registry

[進行状況を確認] をクリックして、上記のタスクを実行したことを確認します。

Cloud Build でイメージをビルドする
  1. コンテナがビルドされたら、デプロイします。
gcloud run deploy rest-api \ --image gcr.io/$GOOGLE_CLOUD_PROJECT/rest-api:0.1 \ --platform managed \ --region {{{ project_0.default_region | "Filled in at lab startup." }}} \ --allow-unauthenticated \ --max-instances=2
  1. デプロイが完了すると、次のようなメッセージが表示されます。
Service [rest-api] revision [rest-api-00001] has been deployed and is serving traffic at https://rest-api-[hash].a.run.app

[進行状況を確認] をクリックして、上記のタスクを実行したことを確認します。

REST API サービスをデプロイする
  1. サービス URL を新しいブラウザタブで開くには、メッセージの最後でサービス URL をクリックします。URL の末尾に「/v1/」を追加し、Enter キーを押します。

次のようなメッセージが表示されます。

{"status" : "running"}

REST API が稼働するようになりました。プロトタイプ サービスの準備ができたので、次のセクションでは API を使って、Firestore データベースから「顧客」情報を取得します。

タスク 3. 顧客のテストデータを読み込む

Ruby

Ruby さん(ソフトウェア コンサルタント)

Patrick さん、こんにちは。

しばらく前に疑似顧客データを作成しましたが、今もお持ちですか?そのデータをテストに利用したいと考えています。

また、Firestore データベースを設定してデータを読み込む方法について、確認しておいてください。

Ruby

Patrick

Patrick さん(IT 管理者)

Ruby さん、こんにちは。

はい、テストデータは今も手元にあります。テストに使えるように、本日中に Firestore に移行しておきます。

Patrick

Ruby さんと Patrick さんは以前に、顧客 10 人のテスト データベースを作成しました。そこには、ある顧客の猫に対して提案された治療データが入っています。

Patrick さんが Firestore データベースを設定して顧客のテストデータを読み込む作業をサポートしましょう。まず、プロジェクトで Firestore を有効にします。

  1. Cloud コンソールに戻り、ナビゲーション メニューナビゲーション メニュー アイコン)> [すべてのプロダクトを表示] > [データベース] > [Firestore] をクリックします。

  2. [Firestore データベースを作成] ボタンをクリックします。

  3. [Standard Edition] を選択します。

  4. [構成オプション] で [Firestore ネイティブ] を選択します。

  5. [セキュリティ ルール] には [開く] を選択します。

  6. [ロケーション タイプ] で、[リージョン] を選択します。

  7. 利用可能なリージョンのリストから を選択し、[データベースを作成] をクリックします。

データベースが作成されるまで待ってから次に進みます。

[進行状況を確認] をクリックして、上記のタスクを実行したことを確認します。

Firestore データベースを作成する
  1. あらかじめ用意された Cloud Storage バケットにインポート ファイルを移行します。
gsutil mb -c standard -l {{{ project_0.default_region | Region }}} gs://$GOOGLE_CLOUD_PROJECT-customer gsutil cp -r gs://spls/gsp645/2019-10-06T20:10:37_43617 gs://$GOOGLE_CLOUD_PROJECT-customer
  1. このデータを Firebase に読み込みます。
gcloud beta firestore import gs://$GOOGLE_CLOUD_PROJECT-customer/2019-10-06T20:10:37_43617/

Cloud コンソール ブラウザを再読み込みして Firestore の結果を確認します。

  1. Firestore で、「Default」の下にある [顧客] をクリックします。読み込まれたペットデータが表示されるので確認します。データが表示されない場合は、ページを更新してみてください。

Firestore データベースが正常に作成され、テストデータが入力されました。

タスク 4. REST API を Firestore データベースに接続する

Ruby

Ruby さん(ソフトウェア コンサルタント)

Lily さん、こんにちは。

取り急ぎ、進捗状況をお知らせします。先日お知らせしたリストのうち、最初の 2 つのタスクを Patrick さんにご協力いただいて完了しました。

次は REST API を構造化して、Firestore の顧客データにアクセスできるようにします。

Ruby

Lily

Lily さん(Pet Theory の創業者)

Ruby さん、こんにちは。

ご連絡ありがとうございます。次の作業についても、進捗のご報告をお待ちしています。

Lily

このセクションでは、次のエンドポイントを REST API で作成する Ruby さんの作業をサポートします。

https://rest-api-[hash].a.run.app/v1/customer/22530

たとえば、この URL では ID 22530 の顧客に関して提案、承認、拒否された治療すべてについて、それぞれの合計金額が(Firestore データベースに存在する場合に)返されます。

{ "status": "success", "data": { "proposed": 1602, "approved": 585, "rejected": 489 } } 注: 顧客がデータベースに存在しない場合は、ステータス コード 404(未検出)とエラー メッセージが代わりに返されます。

この新機能には、Firestore データベースにアクセスするパッケージと、クロスオリジン リソース シェアリング(CORS)を処理するパッケージが必要です。

  1. $GOOGLE_CLOUD_PROJECT 環境変数の値を取得します。
echo $GOOGLE_CLOUD_PROJECT
  1. pet-theory/lab08 ディレクトリにある main.go ファイルを開きます。
注: $GOOGLE_CLOUD_PROJECT に表示された値を使って main.go の内容を更新します。
  1. ファイルの内容を以下のコードに置き換えます。PROJECT_ID に設定されていることを確認してください。
package main import ( "context" "encoding/json" "fmt" "log" "net/http" "os" "cloud.google.com/go/firestore" "github.com/gorilla/handlers" "github.com/gorilla/mux" "google.golang.org/api/iterator" ) var client *firestore.Client func main() { var err error ctx := context.Background() client, err = firestore.NewClient(ctx, "{{{ project_0.project_id | \"Filled in at lab startup\"}}}") if err != nil { log.Fatalf("Error initializing Cloud Firestore client: %v", err) } port := os.Getenv("PORT") if port == "" { port = "8080" } r := mux.NewRouter() r.HandleFunc("/v1/", rootHandler) r.HandleFunc("/v1/customer/{id}", customerHandler) log.Println("Pets REST API listening on port", port) cors := handlers.CORS( handlers.AllowedHeaders([]string{"X-Requested-With", "Authorization", "Origin"}), handlers.AllowedOrigins([]string{"https://storage.googleapis.com"}), handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "OPTIONS", "PATCH", "CONNECT"}), ) if err := http.ListenAndServe(":"+port, cors(r)); err != nil { log.Fatalf("Error launching Pets REST API server: %v", err) } }
  1. ファイルの末尾に、ハンドラ サポートを追加します。
func rootHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "{status: 'running'}") } func customerHandler(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] ctx := context.Background() customer, err := getCustomer(ctx, id) if err != nil { w.WriteHeader(http.StatusInternalServerError) fmt.Fprintf(w, `{"status": "fail", "data": '%s'}`, err) return } if customer == nil { w.WriteHeader(http.StatusNotFound) msg := fmt.Sprintf("`Customer \"%s\" not found`", id) fmt.Fprintf(w, fmt.Sprintf(`{"status": "fail", "data": {"title": %s}}`, msg)) return } amount, err := getAmounts(ctx, customer) if err != nil { w.WriteHeader(http.StatusInternalServerError) fmt.Fprintf(w, `{"status": "fail", "data": "Unable to fetch amounts: %s"}`, err) return } data, err := json.Marshal(amount) if err != nil { w.WriteHeader(http.StatusInternalServerError) fmt.Fprintf(w, `{"status": "fail", "data": "Unable to fetch amounts: %s"}`, err) return } fmt.Fprintf(w, fmt.Sprintf(`{"status": "success", "data": %s}`, data)) }
  1. ファイルの末尾に、カスタマー サポートを追加します。
type Customer struct { Email string `firestore:"email"` ID string `firestore:"id"` Name string `firestore:"name"` Phone string `firestore:"phone"` } func getCustomer(ctx context.Context, id string) (*Customer, error) { query := client.Collection("customers").Where("id", "==", id) iter := query.Documents(ctx) var c Customer for { doc, err := iter.Next() if err == iterator.Done { break } if err != nil { return nil, err } err = doc.DataTo(&c) if err != nil { return nil, err } } return &c, nil } func getAmounts(ctx context.Context, c *Customer) (map[string]int64, error) { if c == nil { return map[string]int64{}, fmt.Errorf("Customer should be non-nil: %v", c) } result := map[string]int64{ "proposed": 0, "approved": 0, "rejected": 0, } query := client.Collection(fmt.Sprintf("customers/%s/treatments", c.Email)) if query == nil { return map[string]int64{}, fmt.Errorf("Query is nil: %v", c) } iter := query.Documents(ctx) for { doc, err := iter.Next() if err == iterator.Done { break } if err != nil { return nil, err } treatment := doc.Data() result[treatment["status"].(string)] += treatment["cost"].(int64) } return result, nil }
  1. ファイルを保存します。

タスク 6. 理解度テスト

パターン「/v1/customer/」の URL に対応する関数はどれですか。 getAmounts customerHandler 該当する顧客に対して成功を返すステートメントはどれですか。 fmt.Fprintf(w, `{"status": "fail", "data": "Unable to fetch amounts: %s"} fmt.Fprintf(w, fmt.Sprintf(`{"status": "success", "data": %s} Firestore データベースから読み込まれる関数はどれですか。 customerHandler と getCustomer getCustomer と getAmounts

タスク 7. 新しいリビジョンをデプロイする

  1. ソースコードを再ビルドします。
go build -o server
  1. REST API の新しいイメージをビルドします。
gcloud builds submit \ --tag gcr.io/$GOOGLE_CLOUD_PROJECT/rest-api:0.2

[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。 イメージ リビジョン 0.2 をビルドする

  1. 更新したイメージをデプロイします。
gcloud run deploy rest-api \ --image gcr.io/$GOOGLE_CLOUD_PROJECT/rest-api:0.2 \ --platform managed \ --region {{{ project_0.default_region | "Filled in at lab startup." }}} \ --allow-unauthenticated \ --max-instances=2
  1. デプロイが完了すると、以前と同様のメッセージが表示されます。新しいバージョンのデプロイ時には、REST API の URL は変わりませんでした。
Service [rest-api] revision [rest-api-00002] has been deployed and is serving traffic at https://rest-api-[hash].a.run.app
  1. すでにその URL で開いてあるブラウザタブに戻ります(末尾に「/v1」が付いています)。更新して、API ステータスがまだ実行中であることを示す、以前と同じメッセージが表示されることを確認します。

{status" : "running"}

  1. ブラウザのアドレスバーに表示されたアプリケーション URL に「/customer/22530」を追加します。次の JSON レスポンスを受け取ります。顧客に関して提案、承認、拒否された治療の合計額がそれぞれ表示されるはずです。

{"status" : "success", "data" :{"proposed" :1602, "approved" :585, "rejected" :489}}

  1. 22530 の代わりに次のような別の顧客 ID を URL に入力してみましょう。
  • 34216
  • 70156(金額はすべてゼロになります)
  • 12345(顧客やペットは存在しないため、Query is nil のようなエラーが返されます)

データベースからの読み取りを行う、スケーラブルでメンテナンスをあまり必要としないサーバーレス REST API をビルドしました。

お疲れさまでした

お疲れさまでした。このラボでは、Ruby さんと Patrick さんが Pet Theory 用のプロトタイプ REST API を正常にビルドできるようにサポートしました。Firestore データベースに接続する REST API を作成し、それを Cloud Run にデプロイしました。また、API をテストして、想定どおりに動作することを確認しました。

Google Cloud トレーニングと認定資格

Google Cloud トレーニングと認定資格を通して、Google Cloud 技術を最大限に活用できるようになります。必要な技術スキルとベスト プラクティスについて取り扱うクラスでは、学習を継続的に進めることができます。トレーニングは基礎レベルから上級レベルまであり、オンデマンド、ライブ、バーチャル参加など、多忙なスケジュールにも対応できるオプションが用意されています。認定資格を取得することで、Google Cloud テクノロジーに関するスキルと知識を証明できます。

マニュアルの最終更新日: 2025 年 5 月 6 日

ラボの最終テスト日: 2025 年 5 月 6 日

Copyright 2025 Google LLC. All rights reserved. Google および Google のロゴは Google LLC の商標です。その他すべての企業名および商品名はそれぞれ各社の商標または登録商標です。

始める前に

  1. ラボでは、Google Cloud プロジェクトとリソースを一定の時間利用します
  2. ラボには時間制限があり、一時停止機能はありません。ラボを終了した場合は、最初からやり直す必要があります。
  3. 画面左上の [ラボを開始] をクリックして開始します

シークレット ブラウジングを使用する

  1. ラボで使用するユーザー名パスワードをコピーします
  2. プライベート モードで [コンソールを開く] をクリックします

コンソールにログインする

    ラボの認証情報を使用して
  1. ログインします。他の認証情報を使用すると、エラーが発生したり、料金が発生したりする可能性があります。
  2. 利用規約に同意し、再設定用のリソースページをスキップします
  3. ラボを終了する場合や最初からやり直す場合を除き、[ラボを終了] はクリックしないでください。クリックすると、作業内容がクリアされ、プロジェクトが削除されます

このコンテンツは現在ご利用いただけません

利用可能になりましたら、メールでお知らせいたします

ありがとうございます。

利用可能になりましたら、メールでご連絡いたします

1 回に 1 つのラボ

既存のラボをすべて終了して、このラボを開始することを確認してください

シークレット ブラウジングを使用してラボを実行する

このラボの実行には、シークレット モードまたはシークレット ブラウジング ウィンドウを使用してください。これにより、個人アカウントと受講者アカウントの競合を防ぎ、個人アカウントに追加料金が発生することを防ぎます。