Workflows を使用したサービスの接続


このチュートリアルでは、Workflows を使用して一連のサービスをリンクする方法について説明します。2 つのパブリック HTTP サービス(Cloud Run functions を使用)、外部 REST API、プライベート Cloud Run サービスを接続すると、柔軟でサーバーレスなアプリケーションを作成できます。

目標

このチュートリアルでは、Google Cloud CLI を使用して単一のワークフローを作成します。ここでは、一度に 1 つのサービスに接続します。

  1. 2 つの Cloud Run functions サービスをデプロイします。最初の関数で乱数を生成し、2 番目の関数で渡された数値を乗算します。
  2. Workflows を使用して 2 つの HTTP 関数を接続します。ワークフローを実行し、結果を返して外部 API に渡します。
  3. Workflows を使用して、指定された数値の log を返す外部 HTTP API を接続します。ワークフローを実行し、結果を返して Cloud Run サービスに渡します。
  4. 認証されたアクセスのみを許可する Cloud Run サービスをデプロイします。サービスは、指定された数値の math.floor を返します。
  5. Workflows を使用して Cloud Run サービスに接続し、ワークフロー全体を実行して最終結果を返します。

次の図は、プロセスの概要と、最終的なワークフローを可視化したものを示しています。

Workflows の可視化

費用

このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。 新しい Google Cloud ユーザーは無料トライアルをご利用いただける場合があります。

始める前に

組織で定義されているセキュリティの制約により、次の手順を完了できない場合があります。トラブルシューティング情報については、制約のある Google Cloud 環境でアプリケーションを開発するをご覧ください。

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. Install the Google Cloud CLI.
  3. To initialize the gcloud CLI, run the following command:

    gcloud init
  4. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  5. Make sure that billing is enabled for your Google Cloud project.

  6. Enable the Artifact Registry, Cloud Build, Cloud Run functions, Cloud Run, Cloud Storage, and Workflows APIs:

    gcloud services enable artifactregistry.googleapis.com cloudbuild.googleapis.com cloudfunctions.googleapis.com run.googleapis.com storage.googleapis.com workflows.googleapis.com
  7. Install the Google Cloud CLI.
  8. To initialize the gcloud CLI, run the following command:

    gcloud init
  9. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  10. Make sure that billing is enabled for your Google Cloud project.

  11. Enable the Artifact Registry, Cloud Build, Cloud Run functions, Cloud Run, Cloud Storage, and Workflows APIs:

    gcloud services enable artifactregistry.googleapis.com cloudbuild.googleapis.com cloudfunctions.googleapis.com run.googleapis.com storage.googleapis.com workflows.googleapis.com
  12. Google Cloud CLI のコンポーネントを更新します。
    gcloud components update
  13. Cloud Shell 内でコマンドを実行している場合は、gcloud CLI ですでに認証されています。それ以外の場合は、ご自分のアカウントでログインします。
    gcloud auth login
  14. このチュートリアルで使用するデフォルトのロケーションを設定します。
    gcloud config set project PROJECT_ID
    export REGION=REGION
    gcloud config set functions/region ${REGION}
    gcloud config set run/region ${REGION}
    gcloud config set workflows/location ${REGION}

    REGION は、サポートされている任意の Workflows のロケーションに置き換えます。

  15. プロジェクト作成者には、オーナーロールroles/owner)が付与されます。デフォルトでは、この Identity and Access Management(IAM)ロールには、ほとんどの Google Cloud リソースへの完全アクセス権に必要な権限が含まれており、この手順は省略できます。

    プロジェクト作成者でない場合は、プロジェクトで適切なプリンシパルに必要な権限を付与する必要があります。プリンシパルは Google アカウント(エンドユーザーの場合)やサービス アカウント(アプリケーションとコンピューティング ワークロードの場合)になることもあります。詳細については、イベントの宛先のロールと権限のページをご覧ください。

    必要な権限

    チュートリアルを完了するために必要な権限を取得するには、プロジェクトに対して次の IAM ロールを付与するよう管理者に依頼してください。

    ロールの付与については、プロジェクト、フォルダ、組織へのアクセス権を管理するをご覧ください。

    必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。

最初の Cloud Run functions サービスをデプロイする

HTTP リクエストを受信すると、この HTTP 関数は 1~100 の間の乱数を生成し、その数値を JSON 形式で返します。

  1. randomgen という名前のディレクトリを作成し、そのディレクトリに移動します。

    mkdir ~/randomgen
    cd ~/randomgen
  2. 次の Python コードを含むテキスト ファイルを main.py というファイル名で作成します。

    import functions_framework
    import random
    from flask import jsonify
    
    
    @functions_framework.http
    def randomgen(request):
        randomNum = random.randint(1, 100)
        output = {"random": randomNum}
        return jsonify(output)
  3. HTTP 処理用の Flask への依存関係をサポートするには、pip パッケージ管理システム用のテキスト ファイルを作成します。ファイル名を requirements.txt にして、以下を追加します。

    flask>=1.0.2
    functions-framework==3.0.0
  4. Workflows が使用するサービス アカウントを作成します。

    export SERVICE_ACCOUNT=workflows-sa
    gcloud iam service-accounts create ${SERVICE_ACCOUNT}
  5. サービス アカウントが認証済みの Cloud Run サービスを呼び出すことができるようにするには、Workflows サービス アカウントに run.invoker ロールを付与します。

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member "serviceAccount:${SERVICE_ACCOUNT}@PROJECT_ID.iam.gserviceaccount.com" \
        --role "roles/run.invoker"
  6. HTTP トリガーを使用して関数をデプロイし、未認証アクセスを許可します。

    gcloud functions deploy randomgen-function \
        --gen2 \
        --runtime python310 \
        --entry-point=randomgen \
        --trigger-http \
        --allow-unauthenticated

    関数のデプロイには数分かかる場合があります。また、Google Cloud コンソールで Cloud Run functions のインターフェースを使用して関数をデプロイできます。

  7. randomgen 関数がデプロイされたら、httpsTrigger.url プロパティを確認できます。

    gcloud functions describe randomgen-function \
        --gen2 \
        --format="value(serviceConfig.uri)"
  8. URL を保存します。これは、後半の演習でワークフローのソースファイルに追加する必要があります。

  9. 次の curl コマンドを使用して、この関数を試すことができます。

    curl $(gcloud functions describe randomgen-function \
        --gen2 \
        --format="value(serviceConfig.uri)")

    数値がランダムに生成され、返されます。

2 つ目の Cloud Run functions サービスをデプロイする

HTTP リクエストを受信すると、この HTTP 関数は JSON 本文から input を抽出し、2 を乗算して、結果を JSON 形式で返します。

  1. ホーム ディレクトリに戻ります。

    cd ~
  2. multiply という名前のディレクトリを作成し、そのディレクトリに移動します。

    mkdir ~/multiply
    cd ~/multiply
  3. 次の Python コードを含むテキスト ファイルを main.py というファイル名で作成します。

    import functions_framework
    from flask import jsonify
    
    
    @functions_framework.http
    def multiply(request):
        request_json = request.get_json()
        output = {"multiplied": 2 * request_json['input']}
        return jsonify(output)
  4. HTTP 処理用の Flask への依存関係をサポートするには、pip パッケージ管理システム用のテキスト ファイルを作成します。ファイル名を requirements.txt にして、以下を追加します。

    flask>=1.0.2
    functions-framework==3.0.0
  5. HTTP トリガーを使用して関数をデプロイし、未認証アクセスを許可します。

    gcloud functions deploy multiply-function \
        --gen2 \
        --runtime python310 \
        --entry-point=multiply \
        --trigger-http \
        --allow-unauthenticated

    関数のデプロイには数分かかる場合があります。また、Google Cloud コンソールで Cloud Run functions のインターフェースを使用して関数をデプロイできます。

  6. multiply 関数がデプロイされたら、httpsTrigger.url プロパティを確認できます。

    gcloud functions describe multiply-function \
        --gen2\
        --format="value(serviceConfig.uri)"
  7. URL を保存します。これは、後半の演習でワークフローのソースファイルに追加する必要があります。

  8. 次の curl コマンドを使用して、この関数を試すことができます。

    curl -X POST MULTIPLY_FUNCTION_URL \
        -H "Authorization: Bearer $(gcloud auth print-identity-token)" \
        -H "Content-Type: application/json" \
        -d '{"input": 5}'

    数値 10 が返されます。

ワークフローで 2 つの Cloud Run functions サービスを接続する

ワークフローは、ワークフロー構文で記述された一連のステップで構成され、YAML 形式または JSON 形式のいずれでも記述できます。これがワークフローの定義です。詳細な説明については、構文リファレンスのページをご覧ください。

  1. ホーム ディレクトリに戻ります。

    cd ~
  2. 次の内容を含むテキスト ファイルを workflow.yaml という名前で作成します。

    - randomgen_function:
        call: http.get
        args:
            url: RANDOMGEN_FUNCTION_URL
        result: randomgen_result
    - multiply_function:
        call: http.post
        args:
            url: MULTIPLY_FUNCTION_URL
            body:
                input: ${randomgen_result.body.random}
        result: multiply_result
    - return_result:
        return: ${multiply_result}
    
    • RANDOMGEN_FUNCTION_URL は、randomgen 関数の URL に置き換えます。
    • MULTIPLY_FUNCTION_URL は、multiply 関数の URL に置き換えます。

    このソースファイルにより、2 つの HTTP 関数がリンクされ、最終結果が返されます。

  3. ワークフローを作成したら、デプロイして実行の準備ができます。

    gcloud workflows deploy WORKFLOW_NAME \
        --source=workflow.yaml

    WORKFLOW_NAME は、ワークフローの名前に置き換えます。

  4. ワークフローを実行します。

    gcloud workflows run WORKFLOW_NAME

    実行とは、ワークフローの定義に含まれるロジックを 1 回だけ実行することです。すべてのワークフローの実行は独立しており、Workflows の迅速なスケーリングにより、多数の同時実行が可能になります。

    ワークフローの実行後、出力は次のようになります。

    result: '{"body":{"multiplied":120},"code":200,"headers":{"Alt-Svc":"h3-29=\":443\";
    ...
    startTime: '2021-05-05T14:17:39.135251700Z'
    state: SUCCEEDED
    ...
    

ワークフローでパブリック REST サービスを接続する

既存のワークフローを更新し、数式を評価できるパブリック REST API(math.js)を接続します。例: curl https://api.mathjs.org/v4/?'expr=log(56)'

ワークフローをデプロイしたため、Google Cloud コンソールの [ワークフロー] ページからワークフローを編集することもできます。

  1. ワークフローのソースファイルを編集し、次の内容で置き換えます。

    - randomgen_function:
        call: http.get
        args:
            url: RANDOMGEN_FUNCTION_URL
        result: randomgen_result
    - multiply_function:
        call: http.post
        args:
            url: MULTIPLY_FUNCTION_URL
            body:
                input: ${randomgen_result.body.random}
        result: multiply_result
    - log_function:
        call: http.get
        args:
            url: https://api.mathjs.org/v4/
            query:
                expr: ${"log(" + string(multiply_result.body.multiplied) + ")"}
        result: log_result
    - return_result:
        return: ${log_result}
    
    • RANDOMGEN_FUNCTION_URL は、randomgen 関数の URL に置き換えます。
    • MULTIPLY_FUNCTION_URL は、multiply 関数の URL に置き換えます。

    これにより、外部 REST サービスが Cloud Run functions サービスにリンクされ、最終結果が返されます。

  2. 変更されたワークフローをデプロイします。

    gcloud workflows deploy WORKFLOW_NAME \
        --source=workflow.yaml

Cloud Run サービスをデプロイする

HTTP リクエストを受信後に JSON 本文から input を抽出してその math.floor を計算し、結果を返す Cloud Run サービスをデプロイします。

  1. floor という名前のディレクトリを作成し、そのディレクトリに移動します。

    mkdir ~/floor
    cd ~/floor
  2. 次の Python コードを含むテキスト ファイルを app.py というファイル名で作成します。

    import json
    import logging
    import os
    import math
    
    from flask import Flask, request
    
    app = Flask(__name__)
    
    
    @app.route('/', methods=['POST'])
    def handle_post():
        content = json.loads(request.data)
        input = float(content['input'])
        return f"{math.floor(input)}", 200
    
    
    if __name__ != '__main__':
        # Redirect Flask logs to Gunicorn logs
        gunicorn_logger = logging.getLogger('gunicorn.error')
        app.logger.handlers = gunicorn_logger.handlers
        app.logger.setLevel(gunicorn_logger.level)
        app.logger.info('Service started...')
    else:
        app.run(debug=True, host='0.0.0.0', port=int(os.environ.get('PORT', 8080)))

  3. 同じディレクトリに、次の内容の Dockerfile を作成します。

    # Use an official lightweight Python image.
    # https://hub.docker.com/_/python
    FROM python:3.7-slim
    
    # Install production dependencies.
    RUN pip install Flask gunicorn
    
    # Copy local code to the container image.
    WORKDIR /app
    COPY . .
    
    # Run the web service on container startup. Here we use the gunicorn
    # webserver, with one worker process and 8 threads.
    # For environments with multiple CPU cores, increase the number of workers
    # to be equal to the cores available.
    CMD exec gunicorn --bind 0.0.0.0:8080 --workers 1 --threads 8 app:app

  4. Docker コンテナ イメージを保存できる Artifact Registry 標準リポジトリを作成します。

    gcloud artifacts repositories create REPOSITORY \
        --repository-format=docker \
        --location=${REGION}

    REPOSITORY は、リポジトリの一意の名前に置き換えます。

  5. コンテナ イメージをビルドします。

    export SERVICE_NAME=floor
    gcloud builds submit --tag ${REGION}-docker.pkg.dev/PROJECT_ID/REPOSITORY/${SERVICE_NAME}
  6. コンテナ イメージを Cloud Run にデプロイし、認証された呼び出しのみが受け入れられるようにします。

    gcloud run deploy ${SERVICE_NAME} \
        --image ${REGION}-docker.pkg.dev/PROJECT_ID/REPOSITORY/${SERVICE_NAME}:latest \
        --no-allow-unauthenticated

サービス URL が表示されたら、デプロイは完了しています。ワークフロー定義を更新するときに、この URL を指定する必要があります。

ワークフローで Cloud Run サービスを接続する

既存のワークフローを更新して、Cloud Run サービスの URL を指定します。

  1. ワークフローのソースファイルを編集し、次の内容で置き換えます。

    - randomgen_function:
        call: http.get
        args:
            url: RANDOMGEN_FUNCTION_URL
        result: randomgen_result
    - multiply_function:
        call: http.post
        args:
            url: MULTIPLY_FUNCTION_URL
            body:
                input: ${randomgen_result.body.random}
        result: multiply_result
    - log_function:
        call: http.get
        args:
            url: https://api.mathjs.org/v4/
            query:
                expr: ${"log(" + string(multiply_result.body.multiplied) + ")"}
        result: log_result
    - floor_function:
        call: http.post
        args:
            url: CLOUD_RUN_SERVICE_URL
            auth:
                type: OIDC
            body:
                input: ${log_result.body}
        result: floor_result
    - create_output_map:
        assign:
          - outputMap:
              randomResult: ${randomgen_result}
              multiplyResult: ${multiply_result}
              logResult: ${log_result}
              floorResult: ${floor_result}
    - return_output:
        return: ${outputMap}
    
    • RANDOMGEN_FUNCTION_URL は、randomgen 関数の URL に置き換えます。
    • MULTIPLY_FUNCTION_URL は、multiply 関数の URL に置き換えます。
    • CLOUD_RUN_SERVICE_URL は、Cloud Run サービス URL に置き換えます。

    これにより、ワークフローで Cloud Run サービスが接続されます。auth キーを使用すると、Cloud Run サービスの呼び出しで認証トークンが渡されます。詳細については、ワークフローから認証済みリクエストを行うをご覧ください。

  2. 変更されたワークフローをデプロイします。

    gcloud workflows deploy WORKFLOW_NAME \
        --source=workflow.yaml
  3. 最終ワークフローを実行します。

    gcloud workflows run WORKFLOW_NAME

    出力は次のようになります。

    result: '{"Floor":{"body":"4","code":200
      ...
      "Log":{"body":"4.02535169073515","code":200
      ...
      "Multiply":{"body":{"multiplied":56},"code":200
      ...
      "Random":{"body":{"random":28},"code":200
      ...
    startTime: '2023-11-13T21:22:56.782669001Z'
    state: SUCCEEDED
    

これで完了です。一連のサービスを接続するワークフローのデプロイと実行が完了しました。

式、条件付きジャンプ、Base64 エンコードまたはデコード、サブワークフローなどを使用して複雑なワークフローを作成するには、Workflows 構文リファレンス標準ライブラリの概要をご覧ください。

クリーンアップ

このチュートリアル用に新規プロジェクトを作成した場合は、そのプロジェクトを削除します。既存のプロジェクトを使用し、このチュートリアルでの変更を加えずに残す場合は、チュートリアル用に作成したリソースを削除します。

プロジェクトを削除する

課金をなくす最も簡単な方法は、チュートリアル用に作成したプロジェクトを削除することです。

プロジェクトを削除するには:

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

チュートリアル リソースを削除する

次のステップ