👌

Cloud Functions 第一世代から第二世代への移行で気を付けるポイント

2024/06/25に公開

初めに

こんにちは。クラウドエース バックエンドエンジニアリング部の王です。
この記事では、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.typeresource.labelsの両方を修正する必要があることがわかりました。
以下は、Google Cloud のサンプルコードを使用して、第一世代と第二世代にデプロイし、それぞれの世代で出力されたログを比較したものです。ログを出力するために、サンプルコードがレスポンスを書き込む前にを書き込む前にfmt.Println("This is stdout")を追加しました。

(第一世代: function-gen1)
第一世代ログ
(第二世代: function-gen2)
第二世代ログ

確認すると、resource.typecloud_functionから cloud_run_revisionに変更されており、またresource.labelsfunction_nameservice_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