概要
背景
ImageFlux Live Streamingでは、ライブ配信のアーカイブを保存することができる。
しかし、その保存完了通知やファイルパス情報等を受け取るには、チャンネル作成時にイベントWebhook通知先を設定する必要がある。
イベントWebhookの仕組み構築は非技術者にはなじみがないことから、今回はイベントWebhook通知を受け取ったうえで、その内容をメール通知する仕組みを構築し、非技術者でもこの通知を気軽に受けられるようにした。
成果
ImageFlux Live StreamingのイベントWebhook通知のうち、アーカイブ保存完了通知およびアーカイブ保存エラーに絞って、メール通知するシステムを構築した。メール通知対象外のWebhookについても、ログに出力できるようにした。
システムはさくらのクラウドで構成し、WebhookハンドリングをAppRun共用型、メール通知機能をシンプル通知、権限管理をIAM(サービスプリンシパルキー)、ログ管理をモニタリングスイートで実現した。AppRun共用型のコンテナイメージはコンテナレジストリに格納している。

構築
サービスプリンシパルキーの作成
AppRun共用型からシンプル通知のAPIを呼べるようにするために、サービスプリンシパルおよびサービスプリンシパルキーを作成した。シンプルにAPIキーを作成して呼んでも良いのだが、ITサービスから呼ぶにはサービスプリンシパルを用いるのがより適している。


登録する鍵ペア(秘密鍵・公開鍵)の作成については他資料を参照されたし。
アクセス権限の付与

作成したサービスプリンシパルに対し、シンプル通知の作成に必要な「作成・削除」権限を追加した。これで権限設定は完了だ。
基盤構築
DockerイメージとGo言語のロジックはリポジトリを参照してほしい。
コンテナレジストリにDockerイメージをpush後、Terraformで基盤を構築する。
問題となったのは、サービスプリンシパルキーを用いるときの秘密鍵の渡し方である。基本的にはsecretでコンテナイメージに格納し、イメージ自体をプライベート運用すべきである。しかし今回は、公開イメージとして気軽に人に使ってほしかったので、環境変数で渡す形とした。
当然値が長すぎて環境変数1つでは渡せないので、分割・エンコードをしたうえで渡す形としている。本番運用ではsecretとすべきだが、お試しで使う分にはこれでも問題ない。
というわけで、Terraformソースは以下の通り:
resource "sakura_simple_notification_destination" "notification_target_for_imageflux_live_streaming_archive_notifier" {
name = "通知先メールアドレス"
description = "ImageFlux Live Streamingアーカイブ完了時の通知先メールアドレス"
type = "email"
value = var.email_address
}
resource "sakura_simple_notification_group" "notification_group_for_imageflux_live_streaming_archive_notifier" {
name = "ImageFlux Live Streamingアーカイブ通知グループ"
description = "ImageFlux Live Streamingアーカイブ完了時の通知グループ"
destinations = [sakura_simple_notification_destination.notification_target_for_imageflux_live_streaming_archive_notifier.id]
}
//1変数で秘密鍵の値を保持できないため、分割
locals {
service_principal_private_key_pem_content = file(var.service_principal_private_key_pem_path)
service_principal_private_key_pem_b64 = base64encode(local.service_principal_private_key_pem_content)
service_principal_private_key_b64_chunk_count = ceil(length(local.service_principal_private_key_pem_b64) / var.service_principal_private_key_b64_chunk_size)
service_principal_private_key_b64_chunk_envs = [for i in range(local.service_principal_private_key_b64_chunk_count) : {
key = format("SERVICE_PRINCIPAL_PRIVATE_KEY_PEM_B64_%03d", i)
value = substr(local.service_principal_private_key_pem_b64, i * var.service_principal_private_key_b64_chunk_size, var.service_principal_private_key_b64_chunk_size)
}]
}
resource "sakura_apprun_shared" "imageflux_live_streaming_archive_notifier" {
name = "ImageFlux Live Streamingアーカイブ通知機能"
max_scale = 3
min_scale = 1
port = 8080
timeout_seconds = 60
components = [{
name = "ImageFlux Live Streamingアーカイブ通知コンテナ"
max_cpu = "0.5"
max_memory = "1Gi"
deploy_source = {
container_registry = {
image = var.container_registry_image
}
}
//あとで決める環境変数
env = concat([
{
key = "SERVICE_PRINCIPAL_KEY_KID"
value = var.service_principal_key_kid
},
{
key = "SERVICE_PRINCIPAL_RESOURCE_ID"
value = var.service_principal_resource_id
},
{
key = "SERVICE_PRINCIPAL_PRIVATE_KEY_PEM_B64_CHUNK_COUNT"
value = tostring(local.service_principal_private_key_b64_chunk_count)
},
{
key = "NOTIFICATION_GROUP_ID"
value = sakura_simple_notification_group.notification_group_for_imageflux_live_streaming_archive_notifier.id
}
], local.service_principal_private_key_b64_chunk_envs)
}]
traffics = [{
version_index = 0
percent = 100
}]
}
シンプルな作りである。ただし、シンプル通知とサービスプリンシパルキーを使う分、Terraformの変数として必要な情報はやや多い。
- 通知先メールアドレス
- サービスプリンシパルキーのKID
- サービスプリンシパルのリソースID
- 署名用秘密鍵
これに加えて、当然Terraformを動かすためのアクセストークン、アクセストークンシークレットが必要である。
というわけで、Terraform applyすると、すぐに基盤が構築された。

シンプル通知有効化
シンプル通知でメールを受け取るには、仮登録(Terraformで済ませている)後にメールアドレス宛に届いた本登録リンクを開く必要がある。「勝手に大量の通知メールを送って嫌がらせをする」行為を防ぐ仕組みだ。
Terraform apply後ほどなくしてメールが届いたので、本登録を済ませる。


AppRun共用型設定(任意)
AppRun共用型のログを有効にする。Terraform完了時にも出力されるが、公開URLをなくした場合はここで再取得が可能だ。これで、AppRun共用型も構築完了。あとは動かすだけである。

動作検証
自作のデモサイトでイベントWebhook送信先にAppRun共用型の公開URLを入力し、チャンネルを作成、配信をしてみる。


そして配信を終了すると……

無事アーカイブ完了通知が届いた。成功である。
AppRun共用型にもログが記録されていることがわかる。

まとめ
今回はImageFlux Live Streamingのアーカイブ完了通知をメールで受け取れる仕組みを構築した。
ここではGoのロジックはただ通知を流すだけだが、例えばさくらのウェブアクセラレータのドメインと.m3u8ファイルのパスを結合してメール通知から直接ブラウザに遷移してアーカイブを再生できるようにしたり、チャンネルIDと.m3u8のパス、録画日時などをデータベースに保存するような仕組みにすることも可能である。
ぜひ試行錯誤してみてほしい。