こんにちは、SRE部カート決済SREブロックの飯島です。普段はZOZOTOWNのカート決済機能のリプレイス・運用・保守に携わっています。またSplunkの管理者としても活動しています。
本記事ではSplunk CloudにおけるInfrastructure as Code(IaC)についてご紹介します。
背景
弊社では様々な用途でSplunkを活用しています。過去にいくつかテックブログを公開していますので、興味のある方はぜひご覧ください。
Splunkには、オンプレミスやクラウドプロバイダーにインストールして運用するSplunk Enterpriseと、SaaSとして提供されるSplunk Cloudの2種類があります。弊社では後者のSplunk Cloudを利用しています。
Splunkに対して感じていた課題
冒頭でも説明した通り、弊社ではSplunkを様々な用途で活用しており、その重要性は導入時よりも高まっています。一方で以下の課題が生じていました。
- SPLの習得難易度が高く新規利用の開始までのハードルが高い
- コード管理されていないためダッシュボードなどがいつの間にか変更されていることがある
- 何の用途で作成したか不明なリソースが存在する
IaCを導入すると以下のメリットが生まれ、上記の課題を解決できます。
- Splunkが不慣れでも他のコードを参考にして効率よくリソースの作成、変更が可能
- コード管理されているとSplunkを触ったことがない人にも勧めやすい
- コード管理ツール(例えばGitHub)に変更履歴が残る
- コード管理ツールでレビューできる/レビューが受けられる
Splunk CloudのIaC化検討
上述した課題を解決するためにSplunk Cloudをコード管理する方法を検討しました。
社内でインフラ構成管理ツールとしてTerraformを利用しているケースが多かったため、まずはTerraformでの管理を検討しました。しかしSplunk CloudではTerraformで管理できるリソースが一部に限られており、ダッシュボードなどのコード管理に対応できないことから課題解決に至らないと判断しました。
補足としてSplunk Enterpriseはほぼ全てのリソースがTerraformに対応しているため、Splunk Cloudについても今後対応リソースが増えていく可能性は十分あります。
Splunk Appを使ったIaC
そこで今回Splunk App(以下、App)と、Splunk社から提供されるApp用の2つのAPIを使ってIaCを実現しました。
App
Appとは、Splunkの設定を集約して管理するための単位です。デフォルトではSearch & ReportingというAppがあらかじめ利用可能になっています。ユーザー自身でAppを新規作成したり、SplunkbaseからAppをインストールしたりもできます。
今回Search & Reportingの既存リソースを、新規作成したAppに移行してコード管理する方針としました。
API
以下が使用した2つのAPIです。
- AppInspect API
- Appの品質と準拠性を検証するためのAPI(ref. Validate your private app)
- Admin Config Service (ACS) API
- AppをSplunk Cloudにデプロイすることが可能(ref. Install an app)
- デプロイするにはAppInspect APIの検証に合格する必要がある
IaC対象のSplunkリソース
弊社でよく利用されているダッシュボードとアラート・レポートを対象としました。
Appを使ったIaCでは、Terraformのようにリソースをインポートして既存リソースをコード管理下に置く手段がありません。リソースをコードで定義すると、新規リソースとして作成されます。そのため、既存リソースを新規リソースに置き換えることが難しいもの(例えばIndex)は対象外としました。
既存のリソースのエクスポート
既存リソースの構成ファイルはエクスポート可能です。Splunk Enterpriseでは利用者自身でエクスポート可能ですが、Splunk Cloudではこの機能が存在せずSplunkサポートに依頼する必要があります。
今回既存のリソースが集約されているSearch & Reporting Appをエクスポートし、IaC対象のダッシュボードとアラート・レポートの構成ファイルを入手しました。
IaCの全体像
Appの構成ファイルはGitHubで管理しています。また、AppInspect APIとACS APIを使用し、GitHub ActionsのWorkflowを利用して、アプリの検証とデプロイを行うCI/CDパイプラインを構築しました。
Appのディレクトリ構成
Appは開発者ガイドにある通り、決められたディレクトリ構成に準拠する必要があります。もし準拠できていない場合、AppInspect APIの検証に失敗します。
以下はAppの必要最低限のディレクトリ構成に、ダッシュボードとアラート・レポートを追加した構成です。
. ├── bin │ └── README ├── default │ ├── app.conf │ ├── data │ │ └── ui │ │ ├── nav │ │ │ └── default.xml │ │ └── views │ │ └── README │ │ └── sample_dashboard.xml │ └── savedsearches.conf ├── metadata │ └── default.meta └── static ├── appIcon.png ├── appIconAlt.png ├── appIconAlt_2x.png └── appIcon_2x.png
以下は上記の構成の主なファイルの説明です。
ファイル | 説明 |
---|---|
./default/app.conf | Appの設定 |
./default/savedsearches.conf | アラート・レポートの設定 |
./default/data/ui/views/dashboard.xml | ダッシュボードの設定 |
./metadata/default.meta | 各種リソースのアクセス権限の設定 |
CI/CDパイプライン
GitHub上でPRを作成すると、ダッシュボードのXMLファイルのLintと、AppInspect APIを使用したAppの検証が実行されます(CI)。マージすると再度CIが実行され、その後ACS APIを使用したAppのデプロイと(CD)、CI/CDの結果のSlack通知が実行されます。
以後、Appの検証とデプロイの処理について説明します。
検証の詳細
以下がAppの検証処理の流れです。
- splunk.comにログインしてアクセストークンを取得 -(1)
- Appのコードをtarコマンドでgzip圧縮 -(2)
- (1)と(2)を添付してAppInspect APIを実行
- AppInspectの結果から検証の合否を判定
以下サンプルコードです。
# splunk.comにログインしてアクセストークンを取得 loginstatus=$(curl -u "$username:$password" --url "https://api.splunk.com/2.0/rest/login/splunk") access_token=$(echo "${loginstatus}" | jq .data.token | tr -d '"') # Appのコードをtarコマンドでgzip圧縮 COPYFILE_DISABLE=1 tar --format ustar -cvzf "${appname}".tar.gz "${appname}" tarfile_path=$(realpath "${appname}.tar.gz") # AppInspect API実行 request=$(curl -X POST \ -H "Authorization: bearer ${access_token}" \ -H "Cache-Control: no-cache" \ -F "app_package=@${tarfile_path}" \ -F "included_tags=cloud" \ --url "https://appinspect.splunk.com/v1/app/validate" ) # AppInspectの進捗を確認 request_id=$(echo "${request}" | jq .request_id | tr -d '"') appinspect_status="PROCESSING" while [ "${appinspect_status}" = "PROCESSING" ]; do echo "waiting the app inspect reviewing" echo "fetch to check the status of inspecting from https://appinspect.splunk.com/v1/app/validate/status/${request_id}" sleep 10 status_request=$(curl -s -X GET \ -H "Authorization: bearer ${token}" \ --url "https://appinspect.splunk.com/v1/app/validate/status/${request_id}" ) echo ""; echo "-------------- App Inspect Status --------------" echo "${status_request}" | jq . appinspect_status=$(echo "${status_request}" | jq -r .status ) done # AppInspectの成否の判定 errors=$(echo "${status_request}" | jq -r .info.error ) failures=$(echo "${status_request}" | jq -r .info.failure ) result="failed" if [ "${errors}" -eq 0 ] && [ "${failures}" -eq 0 ]; then result="success" fi
AppInspectの結果(上記サンプルコードのstatus_request
)には以下の項目が含まれます。errorとfailureが0であれば検証は合格です。
"status": "SUCCESS", "info": { "error": 0, "failure": 0, "skipped": 0, "manual_check": 0, "not_applicable": 0, "warning": 0, "success": 1 }
AppInspectの結果の詳細はレポートで確認できます。レポートにはJSON形式とHTML形式があり、Content-Typeでファイル形式を選択できます。
# JSON形式 curl -X GET \ -H "Authorization: bearer ${access_token}" \ -H "Cache-Control: no-cache" \ -H "Content-Type: application/json" \ --url "https://appinspect.splunk.com/v1/app/report/${request_id}" # HTML形式 curl -X GET \ -H "Authorization: bearer ${access_token}" \ -H "Cache-Control: no-cache" \ -H "Content-Type: text/html" \ --url "https://appinspect.splunk.com/v1/app/report/${request_id}"
デプロイの詳細
以下がACS APIを実行してSplunk CloudにAppをデプロイする処理です。
curl -X POST "https://admin.splunk.com/${STACK}/adminconfig/v2/apps/victoria" \ --header "X-Splunk-Authorization: ${access_token}" \ --header "Authorization: Bearer ${json_web_token}" \ --header "ACS-Legal-Ack: Y" \ --data-binary "@${tarfile_path}" | jq .
CIで取得したアクセストークンとtarコマンドでgzip圧縮したAppのコードを添付します。またJSON Web Tokenが必要になるため、事前にSplunk CloudのUIもしくはACS APIで作成します。
効果、メリット
IaC化により、他のコードを参考にしてリソースの作成や変更が可能となりました。これにより、Splunkに不慣れな場合でも効率的にリソースの作成や変更ができ、Splunkに触っていない人にもSplunkの利用を勧めやすくなりました。またGitHub上のPRで変更内容をレビューでき、その変更内容が履歴に残るメリットも得られました。
終わりに
弊社と同様にSplunk Cloudを使い、IaC化を検討している方の参考になれば幸いです。
今回Splunkのカスタマーサクセスチームの皆様には多大なご協力をいただきました。この場を借りて、心から感謝申し上げます。
ZOZOでは、一緒にサービスを作り上げてくれる方を募集中です。ご興味のある方は、以下のリンクからぜひご応募ください。