🍣

RubyではじめるGoogle Cloud Functions

2022/12/18に公開約3,500字

この記事はCODE BASE OKINAWA Advent Calendar 2022の18日目の記事です。
プライベートでCloud FunctionsをRubyで使う機会があったため、その際に得たノウハウをまとめていきます。

Cloud Functionsとは

GCPでのLambda的なポジションのプロダクトです。
https://cloud.google.com/functions?hl=ja

事前にインストールが必要なツール

  • gcloud CLI
    • 関数のデプロイ等に利用します。

公式チュートリアル

公式に簡単なチュートリアルが用意されているため、まずは手元で動かしてみるのが吉。
関数の作成〜ローカルでのビルドとテストの項目だけでも使用感が何となく掴めるかと思います。
https://cloud.google.com/functions/docs/create-deploy-http-ruby?hl=ja

関数の種類について

Cloud Functionsの関数は、起動方法によって大きく2タイプに分かれます。

  • HTTPトリガー
    関数ごとにURLが割り当てられ、アクセスがあった場合に発火する。
  • イベントトリガー
    Cloud Pub/SubやCloud Storageなど、GCP内の別サービスからのイベント受信により発火する
    Cloud Scheduler → Cloud Pub/Sub → Cloud Functionsと連携することでcronでの起動設定ができるため、バッチ等の用途で使う場合はこちらで使用する。

記述方法はブロックを囲むメソッドを切り替えるだけでOK。

require "functions_framework"

# HTTP関数
FunctionsFramework.http "hello-from-http" do |request|
  # Return the response body.
  "Hello, world!\n"
end

# イベントドリブン関数
FunctionsFramework.cloud_event "hello-from-event" do |event|
  logger.info "I received an event of type #{event.type}!"
end

↑のHTTP関数を下記のコマンドで指定して起動後、curlを叩けば関数が発火する。

bundle exec functions-framework-ruby --target hello-from-http
curl localhost:8080
# Output: Hello World!

イベントドリブン関数に関しては、ローカルで発火させる際にCloud Pub/Subのエミュレータの導入が必要になり手間がかかるため、一旦HTTP関数として起動して動作確認していました。(もっといいやり方がありそう...)

CloudSQLとの連携

接続したいDBが同一プロジェクトに属する場合は、各DBインスタンスに設定されているINSTANCE_CONNECTION_NAMEをホスト名にすることで接続が可能です。

インスタンスの INSTANCE_CONNECTION_NAME を取得します。この値は、次の方法で取得できます。
Google Cloud コンソールのインスタンスの [概要] ページ
次のコマンドの実行: gcloud sql instances describe [INSTANCE_NAME]

https://cloud.google.com/sql/docs/postgres/connect-functions?hl=ja

Cloud Functions 第2世代を使っている場合は、基盤となるCloud Run側で明示的に接続するDBを指定する必要があるので要注意。
https://cloud.google.com/sql/docs/postgres/connect-run?hl=ja#create-deploy

秘匿情報の管理

DBのパスワードなどの秘匿情報は、Secret Manager経由で環境変数として各関数の編集画面からセットできます。
https://cloud.google.com/blog/ja/products/serverless/cloud-functions-integrates-with-google-secret-manager/

cloud functions 編集画面のサンプル

レスポンスタイプ

HTTP関数で実装する場合、最後に評価されるオブジェクトのクラスによって、レスポンスの内容が変わります。
String
ステータスコード200と共にテキストを返す
Array
Rackの仕様に準拠するレスポンスと解釈されます。またRackクラスのオブジェクトをそのまま渡す事も可能です。
Hash
ステータスコード200と共に、application/jsonとして渡されます。
StandardError
ステータスコード500を返します

400エラーを渡したい場合はRackの仕様に則った配列を返してあげる必要がありそうです。

cronで定期実行する

Cloud Scheduler & Cloud Pub/Subと連携することで、cronを使った定期実行が可能になります。
https://cloud.google.com/scheduler/docs/tut-pub-sub?hl=ja

Cloud Schedulerからメッセージを渡して引数のように使えますが、Base64でエンコーディングされるため、functions側でのデコードが必要になります。

メッセージ送信時のサンプル

デコードのサンプル

FunctionsFramework.cloud_event 'sample-function' do |event|
  payload = Base64.decode64(event.data['message']['data'])
  options = JSON.parse(payload)

  puts options['message'] # => "Hello!"
end

デプロイコマンド

下記のコマンドで最低限の設定上でのデプロイが可能です。

gcloud functions deploy sample-function \ 
--gen2 \ # Cloud Functions 第二世代を利用
--region=asia-northeast1 \ # リージョンを指定(東京)
--runtime=ruby30 \ # ランタイム言語を指定(Ruby3.0)
--entry-point=sample-function \ # 起動する関数名を指定
--trigger-http # Cloud Pub/Sub 用に事前に作っておいたトピックを指定

イベントドリブン関数の場合は、先に作成したトピックを指定する必要があります。

--trigger-topic=sample-function-topic

外のオプションはこちら
https://cloud.google.com/sdk/gcloud/reference/functions/deploy?hl=ja

役に立ったドキュメント

Functions Framework for Ruby Doc
https://googlecloudplatform.github.io/functions-framework-ruby/v1.2.0/index.html

Discussion

ログインするとコメントできます