概要 #
Pub/SubのTopicとSubscriptionをコンソールで作ると、Ackの期限やRetry設定を毎回手作業で揃えることになります。同じ構成を別環境でも再現したいのに、手間がかかります。
Terraformで管理すれば、これらをコードとして残しそのまま再現できます。ここではTopicとPull Subscriptionを作り、gcloudで実際にMessageを送受信します。
Terraformの基本操作は前提としています。Pub/Subが初めての方向けです。
Push Subscription、Dead Letter Topic、Ordering Keyは扱いません。
検証すること #
- Pub/Sub TopicとPull Subscriptionを作成できること
- MessageをPublishし、SubscriptionからPullできること
- Acknowledgementを含む基本的なMessage Flowを確認できること
前提環境 #
- Google Cloud CLIとApplication Default Credentials(ADC)
- Terraform 1.5以降
- Pub/Subを操作できる検証用Google Cloud Project
- 検証時のバージョン:Terraform 1.14.3、google 7.43.0
今回の構成 #
TopicとSubscriptionはRegionに属さないGlobalなResourceです。VPCの中には置きません。
flowchart TB
Pub["Publisher
gcloud / アプリケーション"]
Sub["Subscriber
gcloud / アプリケーション"]
subgraph GCP["Google Cloud"]
subgraph Project["Project"]
subgraph PubSub["Pub/Sub(Global)"]
Topic["Topic: tf-example-topic"]
Subscription["Subscription: tf-example-subscription
Pull方式"]
end
end
end
Pub -->|"publish"| Topic
Topic -->|"配信"| Subscription
Subscription -->|"pull"| Sub
Sub -->|"ack"| Subscription
Pull方式では、SubscriberがSubscriptionへ取りに行きます。Ackを返すまでMessageは保持されるため、処理に失敗しても再度受け取れます。
送受信の流れは次のとおりです。
sequenceDiagram
actor Pub as Publisher
participant Topic as Topic
participant Sub as Subscription
actor Cons as Subscriber
Pub->>Topic: publish "hello terraform"
Topic->>Sub: Messageを配信
Note over Sub: Ackされるまで保持
Cons->>Sub: pull
Sub-->>Cons: Message + ackId
Cons->>Sub: ack
Note over Sub: 配信済みとして削除
使用するTerraformコード #
TopicとSubscription #
resource "google_pubsub_topic" "example" {
name = var.topic_name
}
resource "google_pubsub_subscription" "example" {
name = var.subscription_name
topic = google_pubsub_topic.example.id
ack_deadline_seconds = var.ack_deadline_seconds
}
SubscriptionがTopicのIDを参照するため、TerraformはTopicを先に作成します。
Pull SubscriptionではSubscriberがMessageを取得します。処理が完了したらAckを返し、Ack Deadline内に確認されなかったMessageは再配信される可能性があります。
variable "ack_deadline_seconds" {
type = number
default = 20
validation {
condition = (
var.ack_deadline_seconds >= 10 &&
var.ack_deadline_seconds <= 600
)
error_message = "ack_deadline_seconds must be between 10 and 600."
}
}
処理時間に合わせて10〜600秒の範囲で指定します。長くすればよいとは限らず、再配信までの時間とのBalanceを考えます。
設定と実行 #
cd Basic-Examples/10-pubsub
cp terraform.tfvars.example terraform.tfvars
terraform init
terraform fmt -check
terraform validate
terraform plan
terraform apply
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
Outputs:
subscription_name = "tf-example-subscription"
topic_name = "tf-example-topic"
Messageを送受信する #
TopicへMessageをPublishします。
gcloud pubsub topics publish \
"$(terraform output -raw topic_name)" \
--message="hello terraform" \
--project=YOUR_PROJECT_ID
GCP側で確認する #
SubscriptionからPullしてAckします。
gcloud pubsub subscriptions pull \
"$(terraform output -raw subscription_name)" \
--auto-ack \
--limit=1 \
--project=YOUR_PROJECT_ID
hello terraformが表示されれば完了です。Message配送はAt-least-onceを前提にし、Subscriber側は同じMessageを複数回処理しても問題がない設計を検討します。
後片付けと注意点 #
terraform destroy
Subscriptionを削除すると未処理Messageも保持されなくなります。Pub/SubはData量やOperationなどに応じて課金されるため、不要なSubscriptionを残さないようにします。
まとめ #
- TopicとPull Subscriptionの関係をTerraformで定義できる
- Ack DeadlineをValidation付き変数にできる
gcloudでPublish、Pull、Ackを確認できる- Subscriberは再配信を考慮して設計する
参考資料 #
次回 #
次はArtifact RegistryへDocker Repositoryを作成します。