Terraform で GCP Pub/Sub トリガーのチュートリアル

2021年1月4日

概要

やりたいこと

Cloud Pub/Sub にメッセージが来たことをトリガーに CloudFunctions を実行したい。

以下を参考に Terraform で行う。

Terraform で CloudFunctions のデプロイは前回を参照。

アーキテクチャ

CloudFunctions は特定のトリガーと紐付けることができる。

今回は Cloud Pub/Sub にメッセージが送られたとき CloudFunctions が実行される。

  • Pub/Sub -> CloudFunctions

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 トリガー