モジュール 11: Google App Engine から Cloud Functions への移行

1. 概要

サーバーレス移行ステーション シリーズの Codelab(ご自分のペースで進められる実践型のチュートリアル)と関連動画は、主にレガシー サービスからの移行を 1 つ以上行うことで、Google Cloud サーバーレスのデベロッパーがアプリケーションをモダナイズできるよう支援することを目的としています。これにより、アプリの移植性が向上し、オプションと柔軟性が高まるため、幅広い Cloud プロダクトとの統合やアクセスが可能になり、新しい言語リリースへのアップグレードが容易になります。このシリーズは、当初は初期の Cloud ユーザー、主に App Engine(標準環境)のデベロッパーを対象としていましたが、Cloud FunctionsCloud Run などの他のサーバーレス プラットフォームや、該当する場合は他のプラットフォームも対象とするほど幅広くなっています。

App Engine または Cloud Run のリソースを必要とする「アプリ全体」がない場合があります。コードがマイクロサービスまたは単純な関数のみで構成されている場合は、Cloud Functions の方が適している可能性があります。この Codelab では、シンプルな App Engine アプリを移行して(または、大規模なアプリを複数のマイクロサービスに分割して)、Cloud Functions にデプロイする方法を学びます。Cloud Functions は、このようなユースケース専用に作成された別のサーバーレス プラットフォームです。

GCP コンソールの

  • Cloud Shell を使用する
  • Google Cloud Translation API を有効にする
  • API リクエストを認証する
  • 小規模な App Engine アプリを変換して Cloud Functions で実行する
  • Cloud Functions にコードをデプロイする

必要なもの

アンケート

このチュートリアルをどのように使用されますか?

通読のみ 通読して演習を行う

Python のご利用経験はどの程度ありますか?

初心者 中級者 上級者

Google Cloud サービスの使用経験はどの程度ありますか?

初心者 中級者 上級者

2. 背景情報

Google App Engine や Cloud Functions などの PaaS システムは、ユーザーに多くの利便性を提供します。これらのサーバーレス プラットフォームを使用すると、技術チームは使用するプラットフォームの調査や必要なハードウェアの量の決定に時間を費やすのではなく、ビジネス ソリューションの作成に集中できます。アプリケーションは必要に応じて自動的にスケールアップし、従量課金制でゼロにスケールダウンして費用を制御できます。また、今日の一般的な開発言語を幅広くサポートしています。

ただし、フルスタックのウェブ アプリケーション開発やモバイルアプリの複雑なバックエンドには App Engine が最適ですが、多くの場合、デベロッパーはニュースフィードの更新やホームチームのプレーオフの最新スコアの取得など、一部の機能をオンラインに移行しようとしています。どちらのシナリオにもコーディング ロジックは存在しますが、どちらも App Engine のパワーを必要とする本格的な「アプリケーション」ではないようです。そこで Cloud Functions が役に立ちます。

Cloud Functions は、次の小さなコードをデプロイする場合に適しています。

  • アプリケーション全体の一部ではない
  • 開発スタック全体で必要ない
  • 1 つのことに焦点を当てたアプリケーションまたは単一のモバイルアプリのバックエンドにある

Cloud Functions を使用して、大規模なモノリシック アプリケーションを複数のマイクロサービスに分割することもできます。各マイクロサービスは、Cloud FirestoreCloud SQL などの共有共通データベースを使用します。関数またはマイクロサービスをコンテナ化して Cloud Run でサーバーレスで実行することもできます。

移行チュートリアルのほぼすべてで紹介されているサンプル App Engine アプリは、Cloud Functions でも同様に動作する基本的な機能を備えた短いアプリです。このチュートリアルでは、Cloud Functions で実行するようにアプリを変更する方法を学びます。App Engine の観点から見ると、関数はアプリ全体よりも単純であるため、一般的に、開始が簡単で(高速)、オーバーヘッドが少なくなります。この移行では、次の手順に着目します。

  • セットアップ / 事前作業
  • 構成ファイルを削除する
  • アプリケーション ファイルの変更

3. セットアップ/事前作業

Cloud Functions は Python 2 をサポートしていないため、この Codelab は Module 2 Cloud NDB App Engine サンプルアプリの Python 3 バージョンから始まります。まず、プロジェクトをセットアップし、コードを取得してから、ベースライン アプリをデプロイして、作業コードを使って作業を開始することを確認します。

1. プロジェクトのセットアップ

モジュール 2 の Codelab を完了している場合(Python 3 に移植済み)、同じプロジェクト(とコード)を再利用することをおすすめします。または、新しいプロジェクトを作成するか、別の既存のプロジェクトを再利用することもできます。プロジェクトに App Engine サービスが有効になっているアクティブな請求先アカウントがあることを確認します。

2. ベースライン サンプルアプリを入手する

この Codelab の前提条件の 1 つは、機能するモジュール 2 のサンプルアプリを用意することです。まだお持ちでない場合は、先に進む前に上記のいずれかのチュートリアルを完了してください。すでに内容に精通している場合は、以下のモジュール 2 のコーディングから開始してください。

ご自分のコードと Google で用意したコードのいずれを使用される場合も、モジュール 2 の Python 3 コードから開始します。このモジュール 11 の Codelab では、各ステップを順を追って説明します。完了すると、モジュール 11 のリポジトリ フォルダ(FINISH)に似たコードになります。

Python 3 モジュール 2 の開始ファイル(独自のまたは Google のもの)のディレクトリは次のようになります。

$ ls
README.md               main.py                 templates
app.yaml                requirements.txt

3. ベースライン アプリを(再)デプロイする

この段階で実施する必要がある残りの事前作業のステップ:

  1. gcloud コマンドライン ツールを学びなおす
  2. gcloud app deploy を使用してサンプルアプリを再デプロイする
  3. アプリが App Engine で問題なく実行されることを確認する

これらの手順を正常に実行したら、Cloud Functions に変換する準備が整います。

4. 構成ファイルを削除する

app.yaml ファイルは Cloud Functions で使用されない App Engine アーティファクトなので、今すぐ削除します。この操作を行わなくても、Cloud Functions では使用されないため、問題はありません。requirements.txt はモジュール 2 のときと同じなので、構成の変更はこれだけです。

Python 2 App Engine アプリを Python 3 に移植する場合は、appengine_config.pylib フォルダ(存在する場合)を削除します。これらは、Python 3 ランタイムで使用されていない App Engine アーティファクトです。

5. アプリケーション ファイルを変更する

アプリケーション ファイルは main.py の 1 つだけなので、Cloud Functions に移行するために必要な変更はすべてこのファイルで行われます。

インポート

関数のみを扱うため、ウェブ アプリケーション フレームワークは必要ありません。ただし、便宜上、Python ベースの Cloud Functions が呼び出されると、必要に応じてコードで使用するリクエスト オブジェクトが自動的に渡されます。(Cloud Functions チームが、関数に渡される Flask リクエスト オブジェクトとして選択しました)。

ウェブ フレームワークは Cloud Functions の一部ではないため、アプリが他の Flask 機能を使用している場合を除き、Flask からのインポートはありません。テンプレート レンダリングは関数への変換後も行われるため、これはまさにこのケースに当てはまります。つまり、flask.render_template() を呼び出す必要があるため、Flask からのインポートが必要です。ウェブ フレームワークがないため、Flask アプリをインスタンス化する必要はありません。app = Flask(__name__) を削除します。変更を適用する前後のコードは次のようになります。

変更前:

from flask import Flask, render_template, request
from google.cloud import ndb

app = Flask(__name__)
ds_client = ndb.Client()

変更後:

from flask import render_template
from google.cloud import ndb

ds_client = ndb.Client()

アプリ オブジェクト(app)または他のウェブ フレームワーク インフラストラクチャに依存している場合は、それらの依存関係をすべて解決し、適切な回避策を見つけるか、それらの使用を完全に削除するか、プロキシを見つける必要があります。その後、コードを Cloud Functions に変換できます。それ以外の場合は、App Engine を使用するか、Cloud Run 用にアプリをコンテナ化することをおすすめします。

メイン ハンドラ関数のシグネチャを更新

関数シグネチャに必要な変更は次のとおりです。

  1. アプリを Cloud Functions に変換した後は Flask が使用されなくなるため、ルート デコレータを削除します。
  2. Cloud Functions は Flask Request オブジェクトをパラメータとして自動的に渡すため、その変数を宣言します。サンプルアプリでは、これを request とします。
  3. デプロイされた Cloud Functions には名前を付ける必要があります。メイン ハンドラは、その内容(ルート アプリケーション ハンドラ)を説明するために、App Engine で root() という適切な名前が付けられました。Cloud Functions として、その名前を使用するのはあまり意味がありません。代わりに、visitme という名前で Cloud 関数をデプロイします。この名前を Python 関数の名前としても使用します。同様に、モジュール 4 と 5 では、Cloud Run サービスに visitme という名前を付けました。

これらの更新による変更前後の様子は次のとおりです。

変更前:

@app.route('/')
def root():
    'main application (GET) handler'
    store_visit(request.remote_addr, request.user_agent)
    visits = fetch_visits(10)
    return render_template('index.html', visits=visits)

変更後:

def visitme(request):
    'main application (GET) handler'
    store_visit(request.remote_addr, request.user_agent)
    visits = fetch_visits(10)
    return render_template('index.html', visits=visits)

これで、必要な更新はすべて完了しました。変更はアプリケーションの「インフラストラクチャ」コードにのみ影響します。コア アプリケーションのコードを変更する必要はなく、アプリの機能も変更されていません。この点を説明するために、変更内容を図で示します。

668f30e3865b27a9.png

ローカルで開発とテストを行う

App Engine には dev_appserver.py ローカル開発サーバーがありますが、Cloud Functions には Functions Framework があります。このフレームワークを使用すると、ローカルで開発とテストを行うことができます。コードは Cloud Functions にデプロイできますが、Compute EngineCloud Run などの他のコンピューティング プラットフォームや、Knative をサポートするオンプレミスまたはハイブリッド クラウド システムにもデプロイできます。Functions Framework のその他のリンクについては、以下をご覧ください。

6. ビルドとデプロイ

Cloud Functions へのデプロイは、App Engine とは若干異なります。requirements.txt の外部で構成ファイルが使用されていないため、コードに関する詳細情報をコマンドラインで指定する必要があります。次のコマンドを使用して、Python 3.10 で実行される新しい HTTP トリガー Cloud Functions をデプロイします。

$ gcloud functions deploy visitme --runtime python310 --trigger-http --allow-unauthenticated

出力は次のようになることが想定されます。

Deploying function (may take a while - up to 2 minutes)...⠛
For Cloud Build Logs, visit: https://console.cloud.google.com/cloud-build/builds;region=REGION/f5f6fc81-1bb3-4cdb-8bfe?project=PROJECT_ID
Deploying function (may take a while - up to 2 minutes)...done.
availableMemoryMb: 256
buildId: f5f6fc81-1bb3-4cdb-8bfe
buildName: projects/PROJECT_ID/locations/REGION/builds/f5f6fc81-1bb3-4cdb-8bfe
dockerRegistry: CONTAINER_REGISTRY
entryPoint: visitme
httpsTrigger:
  securityLevel: SECURE_OPTIONAL
  url: https://REGION-PROJECT_ID.cloudfunctions.net/visitme
ingressSettings: ALLOW_ALL
labels:
  deployment-tool: cli-gcloud
name: projects/PROJECT_ID/locations/REGION/functions/visitme
runtime: python310
serviceAccountEmail: PROJECT_ID@appspot.gserviceaccount.com
sourceUploadUrl: https://storage.googleapis.com/uploads-853031211983.REGION.cloudfunctions.appspot.com/8c923758-cee8-47ce-8e97-5720a5301c34.zip
status: ACTIVE
timeout: 60s
updateTime: '2022-05-16T18:28:06.153Z'
versionId: '8'

関数がデプロイされたら、デプロイ出力の URL を使用してアプリにアクセスします。URL の形式は REGION-PROJECT_ID.cloudfunctions.net/visitme です。出力は、以前に App Engine にデプロイしたときと同じになります。

2732ae9218f011a2.png

このシリーズの他のほとんどの Codelab や動画と同様に、ベースライン アプリの機能は変更されません。目的は、1 つのモダナイゼーション手法を適用し、アプリを以前とまったく同じように動作させながら、新しいインフラストラクチャで動作させることです。たとえば、古い App Engine レガシー サービスから後継の Cloud スタンドアロン プロダクトに移行したり、このチュートリアルのように、アプリを別の Google Cloud サーバーレス プラットフォームに移行したりします。

7. 概要/クリーンアップ

この小さな App Engine アプリを Cloud Functions に変換できました。お疲れさまでした。もう 1 つの適切なユースケースは、大規模なモノリシック App Engine アプリを、それぞれが Cloud Functions である一連のマイクロサービスに分割することです。これは、より最新の開発手法であり、より「プラグ アンド プレイ」のコンポーネント(「JAM スタック」など)スタイルになります。これにより、混合とマッチング、コードの再利用が可能になります。これらは 2 つの目標ですが、もう 1 つのメリットは、これらのマイクロサービスが時間の経過とともにデバッグされ続けるため、安定したコードと全体的なメンテナンス コストの削減につながることです。

クリーンアップ

この Codelab を完了したら、課金が発生しないように、モジュール 2 の App Engine アプリを無効にすることができます(一時的または永続的に)。App Engine プラットフォームには無料割り当てがあるため、使用量階層の範囲内であれば課金されません。Datastore も同様です。詳細については、Cloud Datastore の料金ページをご覧ください。

App Engine や Cloud Functions などのプラットフォームにデプロイすると、ビルドとストレージの費用がわずかに発生します。一部のリージョンでは、Cloud BuildCloud Storage にそれぞれ独自の無料割り当てがあります。ビルドでは、この割り当ての一部が使用されます。特に、お住まいの地域にこのような無料枠がない場合は、ストレージの使用量を把握して、潜在的なコストを最小限に抑えるようにしてください。

残念ながら、Cloud Functions には「無効化」機能がありません。コードをバックアップして、関数を削除します。同じ名前で後から再デプロイできます。ただし、他の移行 Codelab を続行せず、すべてを完全に削除する場合は、Cloud プロジェクトをシャットダウンしてください。

次のステップ

このチュートリアルの他に、Cloud Run 用 App Engine アプリのコンテナ化など、他の移行モジュールもご覧ください。モジュール 4 とモジュール 5 の Codelab へのリンクをご覧ください。

  • モジュール 4: Docker を使用して Cloud Run に移行する
  • Docker を使用して、Cloud Run で実行できるようにアプリをコンテナ化します。
  • この移行により、Python 2 を引き続き使用できます。
  • モジュール 5: Cloud Buildpacks を使用して Cloud Run に移行する
  • Cloud Build を使用して Cloud Run で実行するようにアプリをコンテナ化します。
  • Docker、コンテナ、Dockerfile についての知識は何も必要ありません。
  • すでに Python 3 に移行しているアプリが必要です(Buildpacks では Python 2 はサポートされていません)。

他のモジュールの多くは、App Engine バンドル サービスから Cloud スタンドアロンの代替サービスに移行する方法をデベロッパーに説明することに重点を置いています。

コンテナ化がアプリケーション開発ワークフローの一部になっている場合(特に CI/CD(継続的インテグレーション/継続的デリバリーまたはデプロイ)パイプラインで構成されている場合)は、Cloud Functions ではなく Cloud Run への移行を検討してください。Docker を使用してアプリをコンテナ化するには、モジュール 4 をご覧ください。コンテナ、Docker の知識、Dockerfile を使用せずにコンテナ化するには、モジュール 5 をご覧ください。Cloud Functions と Cloud Run のどちらを検討する場合でも、別のサーバーレス プラットフォームへの切り替えは任意です。変更を行う前に、アプリとユースケースに最適なオプションを検討することをおすすめします。

次にどの移行モジュールを検討する場合でも、すべてのサーバーレス移行ステーションのコンテンツ(Codelab、動画、ソースコード [利用可能な場合])は、オープンソース リポジトリからアクセスできます。リポジトリの README には、考慮すべき移行と、移行モジュールの関連する「順序」に関するガイダンスも記載されています。

8. 参考情報

App Engine 移行モジュールの Codelab に関する問題 / フィードバック

この Codelab に問題が見つかった場合は、提出する前にまず問題を検索してください。新しい問題の検索と登録を行うためのリンク:

移行に関するリソース

モジュール 8(開始)とモジュール 9(終了)のリポジトリ フォルダへのリンクを以下の表に示します。これらのフォルダには、すべての App Engine Codelab 移行のリポジトリからアクセスすることもでき、クローンを作成する、または ZIP ファイルをダウンロードすることができます。

Codelab

Python 3

モジュール 2

コード

モジュール 11

コード

オンライン リソース

このチュートリアルに関連する可能性のあるオンライン リソースは次のとおりです。

App Engine

Cloud Functions

その他のクラウド情報

動画

ライセンス

この作業はクリエイティブ・コモンズの表示 2.0 汎用ライセンスにより使用許諾されています。