概要
やりたいこと
Cloud Pub/Sub でメッセージを受信した時に CloudFunctions を実行したい。
Cloud Pub/Sub のチュートリアルを Terraform で行う。
Terraform で CloudFunctions をデプロイする方法は前回を参照。
Cloud Functions の呼び出し
CloudFunctions は特定のイベントをトリガーとして実行するタイミングを選択できる。
タイミングとしては以下。
- HTTP トリガー
- Cloud Pub/Sub トリガー
- Cloud Storage トリガー
- ダイレクト トリガー
- Cloud Firestore
- Firebase 向けアナリティクス
- Firebase Realtime Database
- Firebase Authentication
今回は Cloud Pub/Sub でメッセージを受信したときに CloudFunctions を実行するトリガーを設定する。
Cloud Pub/Sub とは
Cloud Pub/Sub は多対多の非同期メッセージグング機能を提供するもの。
用語
- Topic : Publisher が Message を送信する Pub/Sub の機能
- Subscription :Topic と Subscriber を関連付ける Pub/Sub の機能
- Message : Publisher が Topic に送信するデータ
- Publisher : Topic に対して Message を送信するアプリケーション
- Subscriber : 特定の Subscription に関する Message を受信するアプリケーション
Subscriber はその特性によって 2 種類存在する。
- Pull型 : Subscriber が Pub/Sub にリクエストし、Message を取得
- Push型 : Pub/Sub が Subscriber にリクエストし、Message を取得
今回は Topic のみを作成する。
Terraform
Terraform で Pub/Sub Topic
Pub/Sub Topic を作成する。
vi pubsub.tf
resource "google_pubsub_topic" "example" {
name = "example-topic"
labels = {
foo = "bar"
}
}
Terraform でデプロイ。
terraform deploy
下記のように example-topic が作成される。
Terraform で CloudFunctions
Terraform での CloudFunctions のデプロイについては以下参照。
Python のチュートリアルサンプルを利用する(importの場所ここでいいの?)。
単純なメッセージを受け取ってログに書き出す処理。
topic のメッセージは base64 エンコードされているため、データを抽出する際にデコードしている。
vi code/main.tf
def hello_pubsub(event, context):
"""Background Cloud Function to be triggered by Pub/Sub.
Args:
event (dict): The dictionary with data specific to this type of
event. The `data` field contains the PubsubMessage message. The
`attributes` field will contain custom attributes if there are any.
context (google.cloud.functions.Context): The Cloud Functions event
metadata. The `event_id` field contains the Pub/Sub message ID. The
`timestamp` field contains the publish time.
"""
import base64
print("""This Function was triggered by messageId {} published at {}
""".format(context.event_id, context.timestamp))
if 'data' in event:
name = base64.b64decode(event['data']).decode('utf-8')
else:
name = 'World'
print('Hello {}!'.format(name))
entry_point を修正し、event_trigger ブロックを追加。
vi cloudfunctions.tf
data "archive_file" "function_archive" {
type = "zip"
source_dir = "code" # main.pyやrequirement.txtが入ってるdir
output_path = "code/main.zip" # zipファイルの出力パス
}
resource "google_storage_bucket" "bucket" {
name = "test-bucket-slackbot-test"
}
resource "google_storage_bucket_object" "archive" {
name = "index.zip"
bucket = google_storage_bucket.bucket.name
source = data.archive_file.function_archive.output_path
}
resource "google_cloudfunctions_function" "function" {
name = "function-test"
description = "My function"
runtime = "python37"
available_memory_mb = 128
source_archive_bucket = google_storage_bucket.bucket.name
source_archive_object = google_storage_bucket_object.archive.name
#trigger_http = true
event_trigger {
event_type = "providers/cloud.pubsub/eventTypes/topic.publish"
resource = google_pubsub_topic.example.name
}
entry_point = "hello_pubsub"
}
Terraform でデプロイ。デプロイのタイミングで code/ に main.zip が作成され、GCSにアップロードされる。
terraform deploy
以下のように CloudFunctions にトリガーが設定される。
トリガーされるか確認
トリガーされるか試すため、Cloud Pub/Sub にメッセージを送信。
gcloud pubsub topics publish example-topic --message runble1
CloudFunctions のログを確認すると、送ったメッセージを受け取れている。
コメント