DataflowのSplunkテンプレートを用いてSplunk CloudにログをPUSHしてみた

DataflowのSplunkテンプレートを用いてSplunk CloudにログをPUSHしてみた

Clock Icon2025.01.25

概要

SplunkにGoogle Cloudのログを連携する方法は現在以下の2パターンがGoogle Cloudのリファレンスで紹介されています。

https://cloud.google.com/architecture/stream-logs-from-google-cloud-to-splunk?hl=ja

方式 概要
PUSH方式 Splunk側でHEC(Http Event Controller)を構築して、Google CloudからDataflowなどを用いてログをPUSHする方法。Google CloudからDataflowを用いる方法(テンプレート)が提供されている。サービスアカウントキーは不要。HECトークンをGoogle Cloud側で用いてログをPUSHする
PULL方式 Splunk側でアドオンをインスタンスにインストールしてPub/SubトピックからPULLする方式。サービスアカウントキーが必要。Splunkにサービスアカウントキーをアップロードする。

PUSH方式のイメージ
スクリーンショット 2024-11-11 22.24.53

PULL方式のイメージ
スクリーンショット 2024-11-11 22.15.12

上記2つの方法のうち、Google Cloudが推奨しているのはPUSH方式です。
今回はGoogle Cloudが推奨しているPUSH方式を、Dataflowのテンプレートを用いて実現してみます。
Google CloudからPub/Subを用いたDataflowテンプレートが公開されているのでそれを使用します。
https://cloud.google.com/dataflow/docs/guides/templates/provided/pubsub-to-splunk?hl=ja

PULL方式は実際に試してみて以前記事にしています
https://dev.classmethod.jp/articles/20241112-google-cloud-log-to-splunk/

やってみる

前提

  • HECトークンは作成済みであること
  • Splunk Cloudに対してログ送信

構成と流れ

構成は以下のイメージです。
スクリーンショット 2024-11-11 22.24.53

以下のリソースを作成します。

リソース 概要・役割
Pub/Sub PULL型サブスクリプション。シンクの向き先をこのトピックにする。DataflowがPULLしてSplunkへ送信(PUSH)
ログシンク ログをPub/Subへ流すことでDataflowがPULLできるようにする。作成したPub/Subトピックへ向ける。今回は検証なので送信ログはフィルターしてテスト用だけ送る
Dataflow Splunkテンプレートベースで作成。Pub/SubからメッセージをPULLしてSplunkへ送信する
VPC Firewall Rule dataflowタグのついたトラフィックをIngress/Egressで許可。※必要に応じて

手順としては以下となります。

  1. Pub/Subトピックとサブスクリプションを作成
  2. ログシンクを作成
  3. VPC Firewall Ruleを作成
  4. Dataflowのジョブを作成
  5. Splunkにログが送信されているか検証

それでは順番にやってみます。

1. Pub/Subトピックとサブスクリプション作成

コマンドで片付けます。実行するとPULL型のサブスクリプションが作成されます。

# トピック、サブスクリプションを作成
gcloud pubsub topics create splunk-logs
gcloud pubsub subscriptions create --topic splunk-logs logs-to-splunk

サブスクリプション作成時にPUSHするエンドポイントを指定しない場合はPULL型で作成されます。

Creates one or more Cloud Pub/Sub subscriptions for a given topic. The new subscription defaults to a PULL subscription unless a push endpoint is specified.

https://cloud.google.com/sdk/gcloud/reference/pubsub/subscriptions/create

2. ログシンクを作成

続いて、作成したトピックにログをシンクするようにログシンクをコマンドで設定します。

# ログシンクを作成
gcloud logging sinks create my-logs pubsub.googleapis.com/projects/プロジェクト名/topics/splunk-logs \
--log-filter='logName:"projects/プロジェクト名/" NOT (resource.type = "dataflow_step" AND resource.labels.job_name = "Dataflowジョブ名") AND (resource.type = "cloud_run_revision" AND resource.labels.service_name = "Cloud Run関数名" AND resource.labels.location = "asia-northeast1" AND severity>=ERROR)'

検証用なので全てのログを連携するのではなく、--log-filterでフィルタをしています。Dataflowジョブ名を指定して動作させているDataflowジョブのログが流れないようにもしています。
そして、以下の記述で指定したCloud Run関数のエラーログだけを連携するようにしています。

resource.type = "cloud_run_revision" AND resource.labels.service_name = "Cloud Run関数名" AND resource.labels.location = "asia-northeast1" AND severity>=ERROR

コマンドの中で以下の項目は作成するDataflowジョブ・Cloud Run関数名に置き換えます。

設定項目 設定値
resource.labels.job_name Dataflowジョブ名
resource.labels.service_name Cloud Run関数名

他のログを設定したい場合などは以下をご参照ください。
https://cloud.google.com/logging/docs/view/query-library?hl=ja#getting-started

3. VPC Firewall Ruleを作成

今回の検証ではEgressでタグdataflowを全て許可しています。こちらに関してはDataflow・VPC・Splunkの設定によって異なる箇所なのでご注意ください。実行する際はワークロードへの影響を十分事前にご検討ください。
以下のコマンドを実行するとdefaultVPCにEgressルールが設定されます。

# Egressの許可
gcloud compute firewall-rules create allow-dataflow-egress \
    --direction=EGRESS \
    --priority=1000 \
    --network=default \
    --action=ALLOW \
    --rules=all \
    --destination-ranges=0.0.0.0/0 \
    --target-tags=dataflow

Egressを許可しないと、DataflowのワーカーからSplunk Cloudへのログ送信ができません。IP範囲に関してはSplunk Cloud、AWS・Google Cloudに構築した場合などで異なるのでより詳細に絞る場合は環境に応じた設定が必要です。

4. Dataflowのジョブを作成

Dataflowのコンソールのジョブを選択して、テンプレートからジョブを作成を押下します。
スクリーンショット 2025-01-25 14.32.56.png

ジョブ名は適当な値を、リージョンエンドポイントはasia-northeast1を設定してDataflowテンプレートでPub/Sub to Splunkを選択します。
スクリーンショット 2025-01-25 14.35.22.png
テンプレートを選択すると、設定項目がたくさん出てくるので最低限必要な項目だけ設定します。

設定項目名 設定値 役割
Pub/Sub input subscription (1.)で作成したPub/Subサブスクリプション DataflowがPULLしてメッセージを取得
Splunk HEC URL SplunkのHEC URL 注意点として、/services/collectorは記載してはいけません※。またSplunk Cloudの場合は8088のポート記載も不要です。AWSやGoogle CloudのEC2、GCEに自身でインストールしている場合はポート番号は必要となります
一時的な場所 Cloud Storage バケット Dataflowの一時ファイルを書き込むためのバケット名とパス
Output deadletter Pub/Sub topic (1.)で作成したPub/Subトピックまたは任意のトピック デットレターを受け取る
ストリーミングモード 正確に1回 イベントの重複を排除
HEC Authentication token HECトークンの値 Splunk側で発行するHECトークン
Disable SSL certificate validation 任意 SSL証明書の検証が不要な場合はチェック
Source of the token passed PLAINTEXT HECトークンをそのまま貼り付けた場合はPLAINTEXT。Secret Managerに保存している場合はSECRET_MANAGER。KMSを使用している場合はKMS
デフォルトのマシンタイプを使用する 任意 デフォルトn1-standard-1で問題なければチェック。検証なのでデフォルトのマシンタイプや低スペックのもので問題ない
ワーカーIPアドレスの構成 指定なし 指定なしの場合、パブリック IP アドレスとプライベート IP アドレスの両方が割り当てられる。内部IP(プライベートIP)の場合はCloud NATなどVPC外との通信ができる仕組みが必要
ネットワーク デフォルト 指定しない場合はdefaultが設定される

上記を設定してジョブを実行を押下するとDataflowジョブが作成されます。
スクリーンショット 2025-01-25 15.05.03.png

5. Splunkにログが送信されているか確認

Cloud Run関数のエラーログが流れるように設定しているので以下のソースでCloud Run関数を作成して実行します。

import functions_framework

@functions_framework.http
def hello_http(request):
    raise ValueError("エラー発生")
    return "OK"

この関数を実行すると、例外がスローされます。Cloud Functionsでは、未処理の例外がスローされると、HTTPステータスコード 500 Internal Server Errorが返されてseverity: "ERROR"のログがCloud Loggingに記録されます。よってログシンク作成時に設定したフィルタに引っかかるためSplunkへログが送信されるという寸法です。

実行した時のログ出力例は以下です。
スクリーンショット 2025-01-25 15.15.12.png

関数を実行したらSplunk Cloudでログが連携されているかを確認します。
スクリーンショット 2025-01-25 15.19.48.png

severity: ERRORの、logNameもGoogle Cloudのものがしっかりと記載されていました。
問題なくDataflowからSplunk CloudへログをPUSHできているのが確認できました!

Dataflowジョブの停止

一通り検証できたのでDataflowジョブは停止します。
停止を押下してキャンセルを選択してSTOP JOBを押下します。
スクリーンショット 2025-01-25 15.07.38.png

ログシンクやPub/Subなども不要であれば削除してしまいましょう。

補足:HEC URLに関して

DataflowのテンプレートのHEC URLに/services/collectorを含めたHEC URLを設定すると以下のエラーをDataflowは吐き続けます。

Error message from worker: java.lang.RuntimeException: org.apache.beam.sdk.util.UserCodeException: java.lang.IllegalArgumentException: Invalid url format. Url format should match PROTOCOL://HOST[:PORT], where PORT is optional. Supported Protocols are http and https. eg: http://hostname:8088

このエラーが出た場合は、HEC URLに/services/collectorをつけてしまっていないかご確認ください。どうやらDataflow側で/services/collectorのパスを追加してくれているようです。
エラーメッセージにも以下の記載が出ていますので。

Url format should match PROTOCOL://HOST[:PORT]
URL 形式は PROTOCOL://HOST[:PORT] と一致する必要があります

見落としがちなのでご注意ください!

まとめ

Dataflowのテンプレートを用いることで実装することなくSplunkへログ送信することができました。PULL式では必要だったサービスアカウントキーの発行は不要でセキュリティ面ではかなり良いのですが一方でDataflowを使用しなければいけないため費用や構成の複雑さがネックにもなるなと思いました。
VPC Firewallの設定、場合によってはCloud NATも設定する必要がある、Dataflow障害発生時の切り分けや対処など、運用負荷が発生する可能性はあると思います。
PULL式、PUSH式を選定する上ではセキュリティ面以外で運用面も踏まえて考えたほうがよいと考えます。

ちなみに、私がこの検証をした時はEgressの許可やHEC URLでつまってしまいかなり時間がかかりました。私のDataflowへの理解力が低いということも一因ではありますが、そもそも使うサービスが[Pub/Sub、Dataflow、Splunk、VPC]と多岐にわたるためなかなか問題の切り分けに難儀しました・・・無事ログが連携できた時の喜びもその分大きかったですが(*´д`)

それではまた。ナマステー

参考

https://cloud.google.com/architecture/stream-logs-from-google-cloud-to-splunk#deploy_the_dataflow_pipeline
https://cloud.google.com/architecture/stream-logs-from-google-cloud-to-splunk?hl=ja

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.