概要
やりたいこと
GCP のアラートを Slack へ通知したい。
AWS の場合 AWS Chatbot という Slack 連携サービスが存在するが、GCP にはないため、 Cloud Functions で Slack WebHook URL を叩くことにする。
アーキテクチャ
Cloud Pub/Sub でアラートとなるデータを受信し、CloudFunctions を呼び出す。
今回は Cloud Pub/Sub にメッセージが送られたとき CloudFunctions が実行される。
- Pub/Sub -> CloudFunctions -> Slack
Terraform
Slack Incoming WebHook
通知したい Slack チャンネルの Slack WebHook URL を取得。
Slack へ通知できることを確認。
curl -X POST -H 'Content-type: application/json' --data '{"text":"Hello, World!"}' https://hooks.slack.com/services/xxxx
Slack やりとり Python
Slack 通知用 Python を作成。
vi code/main.py
import json
import urllib.request
import base64
WEB_HOOK_URL = "https://hooks.slack.com/services/xxxxx"
def handle_slack_event(event, context):
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))
headers = {
"Content-Type": "application/json; charset=UTF-8"
}
data = {
"text": 'Hello {}!'.format(name),
"icon_emoji" : ":mostly_sunny:",
"username" : "weather_news_bot"
}
req = urllib.request.Request(WEB_HOOK_URL, data=json.dumps(data).encode("utf-8"), method="POST", headers=headers)
try:
res = urllib.request.urlopen(req, timeout=5)
except Exception as e:
print(e)
Terraform で Pub/Sub, CloudFunctions
Terraform の準備は下記。
Pub/Sub Topic を作成する。
vi pubsub.tf
resource "google_pubsub_topic" "example" {
name = "example-topic"
labels = {
foo = "bar"
}
}
CloudFunctions を作成する。
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
event_trigger {
event_type = "providers/cloud.pubsub/eventTypes/topic.publish"
resource = google_pubsub_topic.example.name
}
entry_point = "handle_slack_event"
}
デプロイ。
terraform init
terraform apply
PubSub 宛にメッセージを送信し、Slack に通知が来たら成功。
gcloud pubsub topics publish example-topic --message runble1
コメント