Cloud Functions 第一世代から第二世代への移行で気を付けるポイント
初めに
こんにちは。クラウドエース バックエンドエンジニアリング部の王です。
この記事では、Cloud Functions を第一世代から第二世代にアップグレードする際に気付いた注意点について紹介します。
Cloud Functions の第一世代と第二世代
Cloud Functions は、サーバーレスコンピューティングの分野で広く利用されているツールですが、2022年夏から Google は第二世代を一般提供しました。
第二世代には、同時実行性の向上や広範な CloudEvents のサポートなど、いくつかの利点があります。
また、公式ドキュメントの Cloud Functions バージョンの比較によると、今後も第一世代のサポートを継続する予定のようですが、「可能な限り、新しい関数には Cloud Functions(第二世代)を選択することをおすすめします」と記載されています。
このため、現状第一世代で実装された関数を改修する際には、第二世代へのアップグレードが求められることが多いでしょう。今回、私も第二世代へのアップグレードを経験し、その中でいくつかの注意点に気付きましたので、紹介いたします。
ログのリソースタイプとラベルの変更
Cloud Functions のログを元に何かの操作を行いたい場合があると思いますが、その際に気を付けるポイントがあります。
今回の私の実装では、ログベース指標を使用してエラーログをキャッチし、その指標を基に Cloud Monitoring のアラートポリシーを設定しました。エラーが発生した場合には通知が送られる仕組みになっています。
改修前は第一世代を使用していたため、ログベース指標を作成するには以下のようなフィルターを使用していました。
resource.type = "cloud_function"
resource.labels.function_name = "OLD_FUNCTION_NAME"
今回の改修では関数名を修正したので、当初私はresource.labels.function_name
だけを修正すれば問題ないと思っていました。しかし、実際にエラーケースのテストを行ったところ、エラーが発生しても通知が送られず、想定した動作になりませんでした。原因を調査したところ、resource.type
とresource.labels
の両方を修正する必要があることがわかりました。
以下は、Google Cloud のサンプルコードを使用して、第一世代と第二世代にデプロイし、それぞれの世代で出力されたログを比較したものです。ログを出力するために、サンプルコードがレスポンスを書き込む前にを書き込む前にfmt.Println("This is stdout")
を追加しました。
(第一世代: function-gen1)
(第二世代: function-gen2)
確認すると、resource.type
がcloud_function
から cloud_run_revision
に変更されており、またresource.labels
のfunction_name
がservice_name
に変更されていることがわかりました。これに伴い、ログベース指標を作成するためのフィルターを以下のように修正する必要があります。
resource.type = "cloud_run_revision"
resource.labels.service_name = "NEW_FUNCTION_NAME"
第二世代の Cloud Functions は、Cloud Run の上で構築されているため、実行中に出力されるログは実際にはCloud Runのログとして出力され、Cloud Run のログと統合されているようです。
権限についての変更
次に、第一世代から第二世代へのアップグレードに伴う権限の変更について説明します。
第一世代から第二世代へのアップグレードに伴い、デフォルトのサービスアカウントも変更されました。第一世代では、App Engine のデフォルトサービスアカウント(PROJECT_ID@appspot.gserviceaccount.com)を使用していましたが、第二世代ではデフォルトのコンピューティングサービスアカウント(PROJECT_NUMBER-compute@developer.gserviceaccount.com)を使用します。
コンピューティングサービスアカウントは多くの Google Cloud サービスに幅広くアクセスできるため、十分な注意が必要です。
また、認証された Cloud Functions の関数を呼び出すには、プリンシパルに呼び出し元の IAM 権限が必要です。
これは第一世代と第二世代で共通ですが、第一世代の関数の場合はcloudfunctions.functions.invoke
権限が必要で、第二世代の関数の場合はrun.routes.invoke
権限が必要になります。
もし、Cloud Function を起動するために個別のサービスアカウントを使用する場合には、第二世代にアップグレードする際に権限の更新を行う必要があります。
そうしないと、エラーが発生する可能性があります。
以下のコマンドを実行することで、これらの権限を簡単に設定できます。
$ gcloud functions add-invoker-policy-binding FUNCTION_NAME \
--member='serviceAccount:SERVICE_ACCOUNT_EMAIL'
これは、Google Cloud CLI が関数の世代を自動的に検出し、適切な呼び出し元ロールを追加してくれるためです。
最後に
Cloud Functions の第一世代から第二世代への移行は、単なるバージョンアップではなく、いくつかの点で大きな変化を伴います。
今回は特に、ログの構造や権限管理に焦点を当てて紹介しました。他にも注意すべきポイントはあるかと思いますが、今回のアップグレード作業を通じて私が気付いた点を共有することで、今後皆さんが Cloud Functions を利用する際に少しでもお役に立てれば幸いです。
Discussion