Pic-a-daily: ラボ 6—Workflows を使用したオーケストレーション

1. 概要

これまでのラボでは、Pic-a-daily アプリのイベント ドリブン バージョンをビルドしました。このアプリは、Google Cloud Storage でトリガーされる Cloud Functions の関数を画像分析サービスで使用し、GCS が Pub/Sub 経由で Cloud Run コンテナをトリガーし、サムネイル サービス、Eventarc を介して Cloud Run で Image Garbage Collector サービスをトリガーします。また、Cloud Scheduler によってトリガーされるコラージュ サービスもあります。

d93345bfc235f81e.png

このラボでは、オーケストレーションされたアプリを作成します。さまざまなタイプのイベントがシステム内を流れるのではなく、次のように Workflows を使用してサービスをオーケストレートして呼び出します。

b763efcbf5589747.png

学習内容

  • App Engine
  • Cloud Firestore
  • Cloud Functions
  • Cloud Run
  • Workflows

2. 設定と要件

セルフペース型の環境設定

  1. Cloud コンソールにログインして、新しいプロジェクトを作成するか、既存のプロジェクトを再利用します(Gmail アカウントも Google Workspace アカウントもまだお持ちでない場合は、アカウントを作成してください)。

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

プロジェクト ID を忘れないようにしてください。プロジェクト ID はすべての Google Cloud プロジェクトを通じて一意の名前にする必要があります(上記の名前はすでに使用されているので使用できません)。以降、このコードラボでは PROJECT_ID と呼びます。

  1. 次に、Google Cloud リソースを使用するために、Cloud Console で課金を有効にする必要があります。

このコードラボを実行しても、費用はほとんどかからないはずです。このチュートリアル以外で請求が発生しないように、リソースのシャットダウン方法を説明する「クリーンアップ」セクションの手順に従うようにしてください。Google Cloud の新規ユーザーは、$300 USD 分の無料トライアル プログラムをご利用いただけます。

Cloud Shell の起動

Google Cloud はノートパソコンからリモートで操作できますが、この Codelab では、Google Cloud Shell(Cloud 上で動作するコマンドライン環境)を使用します。

GCP Console で右上のツールバーにある Cloud Shell アイコンをクリックします。

bce75f34b2c53987.png

プロビジョニングと環境への接続にはそれほど時間はかかりません。完了すると、次のように表示されます。

f6ef2b5f13479f3a.png

この仮想マシンには、必要な開発ツールがすべて用意されています。永続的なホーム ディレクトリが 5 GB 用意されており、Google Cloud で稼働します。そのため、ネットワークのパフォーマンスと認証機能が大幅に向上しています。このラボでの作業はすべて、ブラウザから実行できます。

3. Workflows の概要

90fcd42d556e310e.jpeg

Workflows を使用すると、一連のサーバーレス タスクを定義した順序でリンクするサーバーレス ワークフローを作成できます。Google Cloud の API、Cloud Functions や Cloud Run などのサーバーレス プロダクト、外部 API の呼び出し機能を組み合わせて、柔軟なサーバーレス アプリケーションを作成できます。

オーケストレーターから想像できるように、Workflows ではビジネス ロジックのフローを YAML/JSON ベースのワークフロー定義言語で定義し、それらのフローをトリガーする Workflows Execution API と Workflows UI を提供します。

単なるオーケストレーターにとどまらない、次のような構成可能な組み込み機能を備えています。

  • ステップ間の柔軟な再試行とエラー処理により、ステップを確実に実行できます。
  • グルーコードを回避するために、ステップ間での JSON 解析と変数の受け渡し。
  • 決定の式により、条件付きステップを実行できます。
  • モジュール型の再利用可能な Workflows のサブワークフロー。
  • 外部サービスのサポートにより、Google Cloud 以外のサービスのオーケストレーションが可能になります。
  • ステップを安全に実行するための、Google Cloud と外部サービスの認証サポート。
  • Pub/Sub、Firestore、Tasks、Secret Manager などの Google Cloud サービスへのコネクタにより簡単に統合。

言うまでもなく、Workflows はフルマネージドのサーバーレス プロダクトです。サーバーの構成やスケーリングは不要で、使用した分だけ料金が発生します。

4. API を有効にする

このラボでは、Cloud Functions と Cloud Run サービスを Workflows で接続します。また、App Engine、Cloud Build、Vision API などのサービスも使用します。

Cloud Shell で、必要なサービスがすべて有効になっていることを確認します。

gcloud services enable \
  appengine.googleapis.com \
  cloudbuild.googleapis.com \
  cloudfunctions.googleapis.com \
  compute.googleapis.com \
  firestore.googleapis.com \
  run.googleapis.com \
  vision.googleapis.com \
  workflows.googleapis.com \

しばらくすると、オペレーションが正常に完了したことがわかります。

Operation "operations/acf.5c5ef4f6-f734-455d-b2f0-ee70b5a17322" finished successfully.

5. コードを取得する

以前の Codelab をまだ受講していない場合は、コードを取得します。

git clone https://github.com/GoogleCloudPlatform/serverless-photosharing-workshop

このラボに関連する次のフォルダ構造が表示されます。

frontend
 |
workflows
 |
 ├── functions
 ├── |── trigger-workflow
 ├── |── vision-data-transform
 ├── services
 ├── |── collage
 ├── |── thumbnails
 ├── workflows.yaml

関連するフォルダは次のとおりです。

  • frontend には、ラボ 4 で再利用する App Engine フロントエンドが含まれています。
  • functions には、このワークフロー用に作成された Cloud Functions の関数が含まれます。
  • services には、ワークフロー用に変更された Cloud Run サービスが含まれています。
  • workflows.yaml は、ワークフロー定義ファイルです。

6. Workflows YAML を確認する

workflows.yaml では、一連のステップでワークフローが定義されます。では、実際に操作して理解を深めましょう。

ワークフローの最初に渡されるパラメータがいくつかあります。これらは、Workflows をトリガーする 2 つの Cloud Functions の関数によって渡されます。これらの関数については後で説明しますが、Workflows では次のように開始されます。

d44a5e18aa9d4660.png

YAML では、これらのパラメータが、イベントをトリガーするファイル名やバケット名、Workflows が呼び出す一部の Cloud Functions と Cloud Run サービスの URL など、init ステップの変数に割り当てられていることがわかります。

main:
  params: [args]
  steps:
    - init:
        assign:
          - file: ${args.file}
          - bucket: ${args.bucket}
          - gsUri: ${"gs://" + bucket + "/" + file}
          - projectId: ${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}
          - urls: ${args.urls}

次に、Workflows でイベントタイプを確認します。サポートされているイベントタイプは、object.finalize(ファイルが Cloud Storage バケットに保存されるときに出力)と object.delete(ファイルが削除されたときに出力)の 2 つです。それ以外の場合、サポートされていないイベントの例外が発生します。

dd1f450983655619.png

YAML ワークフロー定義のステップでは、ファイル ストレージ イベントのタイプを確認します。

    - eventTypeSwitch:
        switch:
            - condition: ${args.eventType == "google.storage.object.finalize"}
              next: imageAnalysisCall
            - condition: ${args.eventType == "google.storage.object.delete"}
              next: pictureGarbageCollectionGCS
    - eventTypeNotSupported:
        raise: ${"eventType " + args.eventType + " is not supported"}
        next: end

Workflows では、switch 命令とそのさまざまな条件、イベントが認識されないときにエラーを出力する raise 命令により、switch 文と例外処理がサポートされています。

次に、imageAnalysisCall を見てみましょう。これは Workflows からの一連の呼び出しで、Vision API を呼び出して画像を分析し、Vision API レスポンス データを変換して画像内で認識されたもののラベルを並べ替え、ドミナント カラーを選択し、画像が安全に表示可能かどうかを確認してから、メタデータを Cloud Firestore に保存します。

Vision Transform Cloud Functions(後ほどデプロイします)を除き、すべて Workflows で行われます。

ca2ad16b9cbb436.png

YAML での手順は次のようになります。

    - imageAnalysisCall:
        call: http.post
        args:
          url: https://vision.googleapis.com/v1/images:annotate
          headers:
            Content-Type: application/json
          auth:
            type: OAuth2
          body:
            requests:
            - image:
                source:
                  gcsImageUri: ${gsUri}
              features:
              - type: LABEL_DETECTION
              - type: SAFE_SEARCH_DETECTION
              - type: IMAGE_PROPERTIES
        result: imageAnalysisResponse
    - transformImageAnalysisData:
        call: http.post
        args:
          url: ${urls.VISION_DATA_TRANSFORM_URL}
          auth:
            type: OIDC
          body: ${imageAnalysisResponse.body}
        result: imageMetadata
    - checkSafety:
        switch:
          - condition: ${imageMetadata.body.safe == true}
            next: storeMetadata
        next: end
    - storeMetadata:
        call: http.request
        args:
          url: ${"https://firestore.googleapis.com/v1/projects/" + projectId + "/databases/(default)/documents/pictures/" + file + "?updateMask.fieldPaths=color&updateMask.fieldPaths=labels&updateMask.fieldPaths=created"}
          auth:
            type: OAuth2
          method: PATCH
          body:
            name: ${"projects/" + projectId + "/databases/(default)/documents/pictures/" + file}
            fields:
              color:
                stringValue: ${imageMetadata.body.color}
              created:
                timestampValue: ${imageMetadata.body.created}
              labels:
                arrayValue:
                  values: ${imageMetadata.body.labels}
        result: storeMetadataResponse

画像を解析したら、次の 2 つのステップとして、画像のサムネイルと最新の画像のコラージュを作成します。これを行うには、2 つの Cloud Run サービスをデプロイし、thumbnailCall ステップと collageCall ステップから呼び出します。

76f9179323c3144.png

YAML の手順:

   - thumbnailCall:
        call: http.post
        args:
          url: ${urls.THUMBNAILS_URL}
          auth:
            type: OIDC
          body:
              gcsImageUri: ${gsUri}
        result: thumbnailResponse
    - collageCall:
        call: http.get
        args:
          url: ${urls.COLLAGE_URL}
          auth:
            type: OIDC
        result: collageResponse

この実行分岐は、finalizeCompleted ステップで各サービスからステータス コードを返すことで終了します。

    - finalizeCompleted:
        return:
          imageAnalysis: ${imageAnalysisResponse.code}
          storeMetadata: ${storeMetadataResponse.code}
          thumbnail: ${thumbnailResponse.code}
          collage: ${collageResponse.code}

もう一つの実行分岐は、高解像度バージョンの画像を含むファイルがメイン ストレージ バケットから削除された場合です。このブランチでは、サムネイルを含むバケット内の画像のサムネイルを削除し、Firestore からメタデータを削除します。どちらも Workflows からの HTTP 呼び出しを使用して行います。

f172379274dcb3c2.png

YAML の手順:

    - pictureGarbageCollectionGCS:
        try:
          call: http.request
          args:
            url: ${"https://storage.googleapis.com/storage/v1/b/thumbnails-" + projectId + "/o/" + file}
            auth:
              type: OAuth2
            method: DELETE
          result: gcsDeletionResult
        except:
          as: e
          steps:
              - dummyResultInOutVar:
                  assign:
                      - gcsDeletionResult:
                          code: 200
                          body: "Workaround for empty body response"
    - pictureGarbageCollectionFirestore:
        call: http.request
        args:
          url: ${"https://firestore.googleapis.com/v1/projects/" + projectId + "/databases/(default)/documents/pictures/" + file}
          auth:
            type: OAuth2
          method: DELETE
        result: firestoreDeletionResult

削除ブランチは、各ステップの結果 / コードを返すことで終了します。

    - deleteCompleted:
        return:
          gcsDeletion: ${gcsDeletionResult}
          firestoreDeletion: ${firestoreDeletionResult.code}

以降のステップでは、Workflows の外部依存関係(バケット、Cloud Functions、Cloud Run サービス、Firestore データベース)をすべて作成します。

7. バケットを作成する

画像には 2 つのバケットが必要です。元の高解像度画像を保存するバケットと画像のサムネイルを保存するバケットです。

gsutil ツールを使用して、ユーザーが写真をアップロードするための均一なアクセス権を持つ一般公開のリージョン(この場合はヨーロッパ)バケットを作成します。

export BUCKET_PICTURES=uploaded-pictures-${GOOGLE_CLOUD_PROJECT}
gsutil mb -l EU gs://${BUCKET_PICTURES}
gsutil uniformbucketlevelaccess set on gs://${BUCKET_PICTURES}
gsutil iam ch allUsers:objectViewer gs://${BUCKET_PICTURES}

サムネイル用に別のリージョンの一般公開バケットを作成します。

export BUCKET_THUMBNAILS=thumbnails-${GOOGLE_CLOUD_PROJECT}
gsutil mb -l EU gs://${BUCKET_THUMBNAILS}
gsutil uniformbucketlevelaccess set on gs://${BUCKET_THUMBNAILS}
gsutil iam ch allUsers:objectViewer gs://${BUCKET_THUMBNAILS}

バケットが作成され、公開されていることは、Cloud コンソールの Cloud Storage セクションにアクセスして再確認できます。

15063936edd72f06.png

8. ビジョンデータ変換(Cloud Functions)

Workflows.yaml は、initeventTypeSwitcheventTypeNotSupported のステップで始まります。これにより、バケットからのイベントが適切なステップに確実にルーティングされます。

object.finalize イベントの場合、imageAnalysisCall ステップで Vision API が呼び出され、作成された画像のメタデータを抽出します。これらのステップはすべて、Workflows 内で行います。

daaed43a22d2b0d3.png

次に、Vision API から返されたデータを変換してから Firestore に保存する必要があります。具体的には、次のことを行う必要があります。

  • 画像に対して返されたラベルを一覧表示します。
  • 画像の主要な色を取得します。
  • 写真が安全かどうかを判断します。

これは Cloud Functions の関数のコードで行われ、Workflows はこの関数を呼び出すだけです。

5e120e70c67779cd.png

コードを確認する

この Cloud Functions の関数は vision-data-transform と呼ばれます。コードの全文は index.js で確認できます。ご覧のように、この関数の唯一の目的は、JSON から JSON への変換を行い、画像のメタデータを Firestore に容易に保存できるようにすることです。

Cloud Functions にデプロイする

フォルダに移動します。

cd workflows/functions/vision-data-transform/nodejs

任意のリージョンを設定します。

export REGION=europe-west1
gcloud config set functions/region ${REGION}

次のコマンドで関数をデプロイします。

export SERVICE_NAME=vision-data-transform
gcloud functions deploy ${SERVICE_NAME} \
  --source=. \
  --runtime nodejs10 \
  --entry-point=vision_data_transform \
  --trigger-http \
  --allow-unauthenticated

関数がデプロイされると、Workflows の transformImageAnalysisData ステップでこの関数を呼び出して、Vision API データ変換を実行できるようになります。

9. データベースを準備する

Workflows で次に、画像データから画像の安全性をチェックし、Vision API から返された画像に関する情報を Cloud Firestore データベースに保存します。Cloud Firestore データベースは、高速、フルマネージド、サーバーレス、クラウドネイティブの NoSQL ドキュメント データベースです。

6624c616bc7cd97f.png

どちらも Workflows で行いますが、メタデータのストレージを機能させるには Firestore データベースを作成する必要があります。

まず、Firestore データベースを配置するリージョンに App Engine アプリを作成します(Firestore の要件)。

export REGION_FIRESTORE=europe-west2
gcloud app create --region=${REGION_FIRESTORE}

次に、同じリージョンに Firestore データベースを作成します。

gcloud firestore databases create --region=${REGION_FIRESTORE}

ドキュメントはコレクション内でプログラマティックに作成され、次の 4 つのフィールドを含みます。

  • name(文字列): アップロードされた画像のファイル名。ドキュメントのキーでもあります。
  • labels(文字列の配列): Vision API によって認識されたアイテムのラベル
  • color(文字列): ドミナント カラーの 16 進数のカラーコード(#ab12ef)
  • 作成日(日付): この画像のメタデータが保存されたときのタイムスタンプ
  • thumbnail(ブール値): この画像のサムネイル画像が生成された場合に true になるオプション フィールド。

Firestore でサムネイルのある画像を検索し、作成日で並べ替えるため、検索インデックスを作成する必要があります。インデックスを作成するには、次のコマンドを使用します。

gcloud firestore indexes composite create --collection-group=pictures \
  --field-config field-path=thumbnail,order=descending \
  --field-config field-path=created,order=descending

インデックスの作成には 10 分ほどかかることがあります。

インデックスが作成されると、Cloud コンソールに表示されます。

43af1f5103bf423.png

Workflows の storeMetadata ステップで、イメージのメタデータを Firestore に保存できるようになりました。

10. サムネイル サービス(Cloud Run)

チェーンの次は、画像のサムネイルを作成します。これは Cloud Run サービスのコードで行われ、Workflows は thumbnailCall ステップでこのサービスを呼び出します。

84d987647f082b53.png

コードを確認する

Cloud Run サービスは thumbnails と呼ばれます。コードの全文は index.js で確認できます。

コンテナ イメージをビルドして公開する

Cloud Run はコンテナを実行しますが、まずコンテナ イメージ(Dockerfile で定義)をビルドする必要があります。Google Cloud Build を使用してコンテナ イメージをビルドし、Google Container Registry にホストできます。

フォルダに移動します。

cd workflows/services/thumbnails/nodejs

構築:

export SERVICE_SRC=thumbnails
export SERVICE_NAME=${SERVICE_SRC}-service
gcloud builds submit \
  . \
  --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME}

1 ~ 2 分後にビルドが成功し、コンテナが Google Container Registry にデプロイされます。

Cloud Run へのデプロイ

必要な変数と構成を設定します。

export BUCKET_THUMBNAILS=thumbnails-${GOOGLE_CLOUD_PROJECT}
export REGION=europe-west1
gcloud config set run/region ${REGION}
gcloud config set run/platform managed

次のコマンドを使用してデプロイします。

gcloud run deploy ${SERVICE_NAME} \
    --image gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME} \
    --no-allow-unauthenticated \
    --memory=1Gi \
    --update-env-vars BUCKET_THUMBNAILS=${BUCKET_THUMBNAILS}

サービスがデプロイされると、Workflows の thumbnailCall ステップでこのサービスを呼び出すことができます。

11. コラージュ サービス(Cloud Run)

チェーンの次は、最新の画像からコラージュを作成します。これは Cloud Run サービスのコードで行われ、Workflows は collageCall ステップでこのサービスを呼び出します。

591e36149066e1ba.png

コードを確認する

Cloud Run サービスは collage と呼ばれます。コードの全文は index.js で確認できます。

コンテナ イメージをビルドして公開する

Cloud Run はコンテナを実行しますが、まずコンテナ イメージ(Dockerfile で定義)をビルドする必要があります。Google Cloud Build を使用してコンテナ イメージをビルドし、Google Container Registry にホストできます。

フォルダに移動します。

cd services/collage/nodejs

構築:

export SERVICE_SRC=collage
export SERVICE_NAME=${SERVICE_SRC}-service
gcloud builds submit \
  . \
  --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME}

1 ~ 2 分後にビルドが成功し、コンテナが Google Container Registry にデプロイされます。

Cloud Run へのデプロイ

必要な変数と構成を設定します。

export BUCKET_THUMBNAILS=thumbnails-${GOOGLE_CLOUD_PROJECT}
export REGION=europe-west1
gcloud config set run/region ${REGION}
gcloud config set run/platform managed

デプロイ:

gcloud run deploy ${SERVICE_NAME} \
    --image gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME} \
    --no-allow-unauthenticated \
    --memory=1Gi \
    --update-env-vars BUCKET_THUMBNAILS=${BUCKET_THUMBNAILS}

サービスがデプロイされたら、Cloud コンソールの Cloud Run セクションで両方のサービスが実行されていることを確認できます。また、Workflows の collageCall ステップでこのサービスを呼び出すことができます。

3ae9873f4cbbf423.png

12. Workflows のデプロイ

Workflows の外部依存関係をすべてデプロイしました。残りのステップ(finalizeCompletedpictureGarbageCollectionGCSpictureGarbageCollectionFirestoredeleteCompleted)はすべて、Workflows 自体で完了できます。

それでは、Workflows をデプロイします。

workflows.yaml ファイルを含むフォルダに移動し、次のコマンドでデプロイします。

export WORKFLOW_REGION=europe-west4
export WORKFLOW_NAME=picadaily-workflows
gcloud workflows deploy ${WORKFLOW_NAME} \
  --source=workflows.yaml \
  --location=${WORKFLOW_REGION}

数秒後にワークフローがデプロイされ、Cloud コンソールの [ワークフロー] セクションに表示されます。

94a720149e5df9c5.png

ワークフローをクリックして、必要に応じて編集できます。編集中に、ワークフローがわかりやすく表示されます。

55441b158f6027f3.png

このワークフローは、Cloud コンソールから適切なパラメータを使用して手動で実行することもできます。代わりに、次のステップで Cloud Storage イベントに応答して自動的に実行します。

13. Workflows トリガー(Cloud Functions)

これでワークフローがデプロイされ、準備が整いました。次に、Cloud Storage バケットでファイルが作成または削除されたときに Workflows をトリガーする必要があります。これらはそれぞれ storage.object.finalize イベントと storage.object.delete イベントです。

Workflows には、Workflows を作成、管理、実行するための API とクライアント ライブラリがあります。この場合は、Workflows Execution API、具体的には Node.js クライアント ライブラリを使用してワークフローをトリガーします。

Cloud Storage イベントをリッスンする Cloud Functions の関数から Workflows をトリガーします。Cloud Functions の関数は 1 つのイベントタイプしかリッスンできないため、2 つの Cloud Functions をデプロイして作成イベントと削除イベントの両方をリッスンします。

c4d79646de729e4.png

コードを確認する

この Cloud Functions の関数は trigger-workflow と呼ばれます。コードの全文は index.js で確認できます。

Cloud Functions にデプロイする

フォルダに移動します。

cd workflows/functions/trigger-workflow/nodejs

必要な変数と構成を設定します。

export BUCKET_PICTURES=uploaded-pictures-${GOOGLE_CLOUD_PROJECT}
export REGION=europe-west1
export WORKFLOW_NAME=picadaily-workflows
export WORKFLOW_REGION=europe-west4
export COLLAGE_URL=$(gcloud run services describe collage-service --format 'value(status.url)')
export THUMBNAILS_URL=$(gcloud run services describe thumbnails-service --format 'value(status.url)')
export VISION_DATA_TRANSFORM_URL=$(gcloud functions describe vision-data-transform --format 'value(httpsTrigger.url)')
gcloud config set functions/region ${REGION}

ファイナライズ イベントに応答する関数をデプロイします。

export SERVICE_NAME=trigger-workflow-on-finalize
gcloud functions deploy ${SERVICE_NAME} \
  --source=. \
  --runtime nodejs10 \
  --entry-point=trigger_workflow \
  --trigger-resource=${BUCKET_PICTURES} \
  --trigger-event=google.storage.object.finalize \
  --allow-unauthenticated \
  --set-env-vars GOOGLE_CLOUD_PROJECT=${GOOGLE_CLOUD_PROJECT},WORKFLOW_REGION=${WORKFLOW_REGION},WORKFLOW_NAME=${WORKFLOW_NAME},THUMBNAILS_URL=${THUMBNAILS_URL},COLLAGE_URL=${COLLAGE_URL},VISION_DATA_TRANSFORM_URL=${VISION_DATA_TRANSFORM_URL}

削除イベントに応答する 2 番目の関数をデプロイします。

export SERVICE_NAME=trigger-workflow-on-delete
gcloud functions deploy ${SERVICE_NAME} \
  --source=. \
  --runtime nodejs10 \
  --entry-point=trigger_workflow \
  --trigger-resource=${BUCKET_PICTURES} \
  --trigger-event=google.storage.object.delete \
  --allow-unauthenticated \
  --set-env-vars GOOGLE_CLOUD_PROJECT=${GOOGLE_CLOUD_PROJECT},WORKFLOW_REGION=${WORKFLOW_REGION},WORKFLOW_NAME=${WORKFLOW_NAME},THUMBNAILS_URL=${THUMBNAILS_URL},COLLAGE_URL=${COLLAGE_URL},VISION_DATA_TRANSFORM_URL=${VISION_DATA_TRANSFORM_URL}

デプロイが完了すると、Cloud コンソールに両方の機能が表示されます。

7d60c8b7851f39f5.png

14. フロントエンド(App Engine)

このステップでは、Pic-a-daily: ラボ 4 - ウェブ フロントエンドを作成するから、Google App Engine でウェブ フロントエンドを作成します。ユーザーはウェブ アプリケーションから画像をアップロードしたり、アップロードされた写真やサムネイルを閲覧したりできます。

223fb2281614d053.png

App Engine の詳細とコードの説明については、Pic-a-daily: ラボ 4 - ウェブ フロントエンドを作成するをご覧ください。

コードを確認する

App Engine アプリの名前は frontend です。コードの全文は index.js で確認できます。

App Engine にデプロイする

フォルダに移動します。

cd frontend

任意のリージョンを設定し、app.yaml の GOOGLE_CLOUD_PROJECT を実際のプロジェクト ID に置き換えます。

export REGION=europe-west1
gcloud config set compute/region ${REGION}
sed -i -e "s/GOOGLE_CLOUD_PROJECT/${GOOGLE_CLOUD_PROJECT}/" app.yaml

デプロイ:

gcloud app deploy app.yaml -q

1 ~ 2 分後、アプリケーションがトラフィックを処理していることが通知されます。

Beginning deployment of service [default]...
╔════════════════════════════════════════════════════════════╗
╠═ Uploading 8 files to Google Cloud Storage                ═╣
╚════════════════════════════════════════════════════════════╝
File upload done.
Updating service [default]...done.
Setting traffic split for service [default]...done.
Deployed service [default] to [https://GOOGLE_CLOUD_PROJECT.appspot.com]
You can stream logs from the command line by running:
  $ gcloud app logs tail -s default
To view your application in the web browser run:
  $ gcloud app browse

また、Cloud コンソールの [App Engine] セクションに移動して、アプリがデプロイされていることを確認したり、バージョニングやトラフィック分割などの App Engine の機能を確認したりすることもできます。

f4bd5f4de028bd83.png

15. Workflows をテストする

テストするには、アプリ(https://<YOUR_PROJECT_ID>.appspot.com/)アプリのデフォルトの App Engine URL に移動すると、フロントエンド UI が稼働しているのを確認できます。

1649ac060441099.png

画像をアップロードします。これにより Workflows がトリガーされ、Cloud コンソールでワークフローの実行が Active 状態であることを確認できます。

b5a2a3d7a2bc094.png

Workflows が完了したら、実行 ID をクリックすると、さまざまなサービスからの出力を確認できます。

8959df5098c21548.png

画像をあと 3 枚アップロードしてください。また、Cloud Storage バケットと App Engine フロントエンドの画像のサムネイルとコラージュが更新されます。

d90c786ff664a5dc.png

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

アプリを残すつもりがない場合は、プロジェクト全体を削除することで、リソースをクリーンアップすることで費用を節約し、クラウド全般的に正しい行動を取ることができます。

gcloud projects delete ${GOOGLE_CLOUD_PROJECT} 

17. 完了

Workflows を使用して、サービスのオーケストレーションと呼び出しを行うオーケストレートされたバージョンのアプリを作成しました。

学習した内容

  • App Engine
  • Cloud Firestore
  • Cloud Functions
  • Cloud Run
  • Workflows