Terraform で Cloud Functions + Cloud Pub/Sub トリガーのチュートリアル

概要

やりたいこと

Cloud Pub/Sub でメッセージを受信した時に CloudFunctions を実行したい。

Cloud Pub/Sub のチュートリアルを Terraform で行う。

Terraform で CloudFunctions をデプロイする方法は前回を参照。

Cloud Functions の呼び出し

CloudFunctions は特定のイベントをトリガーとして実行するタイミングを選択できる。

タイミングとしては以下。

今回は 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 のログを確認すると、送ったメッセージを受け取れている。

参考

Cloud Pub/Sub のチュートリアル

google_cloudfunctions_function

Google Cloud Pub/Sub トリガー

コメント

タイトルとURLをコピーしました