Eventarc + Cloud Run で Google Cloud リソースの作成を Slack 通知する

記事タイトルとURLをコピーする

G-gen の佐々木です。当記事では Google Cloud (旧称: GCP ) の EventarcCloud Run を使用して、Google Cloud 上でリソースが作成されたことを通知する処理を、サーバーレスで実装していきます。

Eventarc & Cloud Run

Eventarc とは?

Eventarc は、Google Cloud もしくは外部のイベントソースで発生したイベントを、 Pub/Sub サブスクリプション 経由 で 様々な宛先(イベントコンシューマ)に転送するサービスです。
インフラストラクチャの管理は不要で、Eventarc を介したイベントはすべて CloudEvents 形式 に標準化され、コンシューマに配信されます。

Eventarc のサーバーレスかつ標準化されたイベント配信により、Google Cloud を用いた イベントドリブンアーキテクチャ の構築が容易になります。

Eventarc で利用できるイベントソース

Eventarc のイベントソースとしては以下がサポートされています(参考)。
この中には現在プレビュー中のイベントソースが多く含まれているため、使用には注意が必要です。

  • Google Cloud のサービスからイベントを直接受け取る( Cloud Storage 、Firebase など)
  • Cloud Audit Logs イベント( Google Cloud リソースの作成・更新・削除など)
  • Pub/Sub トピックにパブリッシュされたメッセージ
  • サードパーティのサービス( Datadog など )

Eventarc で利用できるイベントコンシューマ

Eventarc のイベント送信先となるイベントコンシューマには以下のサービスが選択できます。

  • Cloud Run
  • Cloud Run for Anthos(プレビュー)
  • Workflows(プレビュー)

Cloud Run とは?

Cloud Run はサーバーレスなコンテナ実行基盤を提供するサービスです。
具体的にどんなサービスなのかについては、以下の記事で解説しています。

blog.g-gen.co.jp

作成するもの

当記事では、Cloud IAM でサービスアカウントを作成した際のイベントをCloud Audit Logs と Eventarc を用いて検知し、イベントの情報を Cloud Run に送信して、Slack に通知する仕組みを実装していきます。
Eventarc のドキュメントに チュートリアル があるので、こちらを参考にしつつ進めていきます。

処理の流れ

Eventarc に必要なサービスアカウントの作成

Eventarc で使用するサービスアカウントを作成します。
Eventarc は Augit Logs からのイベント読み取りと、Cloud Run サービスへのリクエスト送信を行うため、以下のロールをサービスアカウントに付与します。

  • Eventarc イベント受信者 ( Eventarc Event Receiver )
  • Cloud Run 起動元 ( Cloud Run Invoker )

サービスアカウントの作成

Cloud Run サービスの作成

Eventarc からイベントを受け取り、Slack に通知する Cloud Run サービスを作成していきます。

Docker コンテナの作成に必要なリソースの準備

Cloud Run には Docker コンテナの形式でデプロイするので、メインの処理を記述したコード main.py(今回は Python を使用しています )と、コード内で使用するライブラリを記載した requirements.txt、そして Dockerfile を作成します。
Google Cloud から提供されている コードサンプル を参考にして作成しています。

main.py の内容

Slack への通知処理は slackweb ライブラリ を使用しています。
今回、通知に使用する Slack Webhook URL は Cloud Run の環境変数「 SLACK_URL 」に設定するため、コード内では環境変数を取得する処理を入れています。

from flask import Flask, request
import slackweb
import os
 
 
# Cloud Runの環境変数からSlack WebhookのURLを取得
slack_url = os.environ.get('SLACK_URL')
 
 
app = Flask(__name__)
 
 
@app.route('/', methods=['POST'])
def index():
 
    # Eventarcから受け取ったイベントの情報から、通知に必要なものを抽出
    res = request.json
    email = res['protoPayload']['authenticationInfo']['principalEmail']  # サービスアカウント作成者の情報
    project_id = res['protoPayload']['response']['project_id']  # プロジェクトID
    sa_name = res['protoPayload']['request']['service_account']['display_name']  # 作成されたサービスアカウント名
 
    # Slack通知文
    text = f'''作成者: {email}
プロジェクトID: {project_id}
サービスアカウント名: {sa_name}
'''
    attachments = [
        {
            'title': 'google.iam.admin.v1.CreateServiceAccount',
            'pretext': '以下の Cloud Audit Logs イベントを検知',
            'text': text,
            'mrkdown_in': ['text', 'pretext']
        }
    ]
 
    # Slack通知処理
    slack = slackweb.Slack(url=slack_url)
    slack.notify(attachments=attachments)    
 
    return ('success!', 200)
 
 
if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=8080)

requirements.txt の内容

Flask==2.2.0
gunicorn==20.1.0
slackweb==1.0.5

Dockerfile の内容

Dockerfile はサンプルコードの内容をそのまま使用しています。

FROM python:3.10-slim
ENV PYTHONUNBUFFERED True
COPY requirements.txt ./
RUN pip install -r requirements.txt
ENV APP_HOME /app
WORKDIR $APP_HOME
COPY . ./
CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app

GitHub リポジトリにコードをアップロードする

Cloud Run では、デプロイ時のソースとして GitHub などのリポジトリプロバイダを選択することで、コンテナのビルドから Cloud Run サービスのデプロイまでを自動で行うことができます。
内部的には Cloud Build によって コンテナイメージがビルドされ、Cloud Run サービスにデプロイされます。
また、ここで作成されたコンテナイメージは Container Registry に格納されます。

リポジトリへの変更があった際に、変更を反映したコンテナイメージを自動で Cloud Run にデプロイするように設定することもできます(参考)。

Cloud Run サービスをデプロイする

Cloud Run サービスの作成画面で ソース リポジトリから新しいリビジョンを継続的にデプロイする を選択し、設定を行っていきます。

GitHub リポジトリを使用したデプロイ①

リポジトリプロバイダとリポジトリを選択し、GitHub のコンテンツが Google Cloud プロジェクトに移行されることに同意するチェックボックスにチェックを入れます。

GitHub リポジトリを使用したデプロイ②

使用するブランチと、Dockerfile のパスを指定します。

GitHub リポジトリを使用したデプロイ③

環境変数に Slack Webhook の URL を設定していきます。
URL の発行手順は こちら を参考にしました。

環境変数の設定

その他の設定値は デフォルトのまま、 Cloud Run サービスを作成します。

Eventarc の設定

Eventarc で Cloud Run サービスにリクエストを送信するトリガーを作成していきます。
今回はサービスアカウントの作成イベントを検知して通知を行いたいので、イベントプロバイダ に「 Cloud IAM 」、イベント に「 google.iam.admin.v1.CreateServiceAccount 」を選択します。
また、Cloud IAM に対する Cloud Audit Logs のイベントキャプチャが有効化されていない場合、ここで有効化します。

イベントプロバイダとイベントの設定

Eventarc から 宛先となる Cloud Run へのリクエスト送信は、内部的には Pub/Sub サブスクリプション経由で行われます。
以下の指示が表示された場合は、Pub/Sub がCloud Run の API を呼び出せるように、Pub/Sub のサービスアカウントに対して ID トークン発行の権限( iam.serviceAccountTokenCreator )を付与します(参考)。

Pub/Sub サービスアカウントへの権限付与

あらかじめ作成した Eventarc トリガー用のサービスアカウントと、Cloud Run サービスを設定し、Eventarc トリガーを作成します。

サービスアカウントと Cloud Run サービスの設定

これで、サービスアカウント作成のイベントを検知し、Cloud Run サービスにイベントの内容を送信することができるようになりました。

動作確認

Cloud IAM でサービスアカウントを作成し、Slack に通知が届くことを確認します。

Cloud Run から送信された Slack 通知

今回は Slack への通知のみを行いましたが、Eventarc で Cloud Audit Logs をイベントソースにすることで、Google Cloud上で作成したリソースへのラベルの自動付与や、ファイアウォールルールなどのセキュリティ上重要なリソースの変更を検知して通知するなど、様々な応用方法が考えられます。

佐々木 駿太 (記事一覧)

G-gen最北端、北海道在住のクラウドソリューション部エンジニア

2022年6月にG-genにジョイン。Google Cloud Partner Top Engineer 2024に選出。好きなGoogle CloudプロダクトはCloud Run。

趣味はコーヒー、小説(SF、ミステリ)、カラオケなど。