ServiceNowとElasticsearchを双方向通信で接続する
Elastic Stack(ELK)がオブザーバビリティとセキュリティに使われるようになって数年が経ち、現在ではそれぞれの目的に特化したソリューションが提供されています。しかし、問題を特定したり、根本原因を発見する作業はプロセスの一部にすぎません。日々の業務ワークフローにElastic Stackを統合することで、さまざまな問題をすばやく解決しようと考える組織は少なくありません。典型的なアプローチでは、何らかのチケット発行、あるいはインシデントトラッキングフレームワークとの統合を検討します。たとえばSlackやメールを使っているチームもあれば、ServiceNowやJiraといったツールを利用しているチームもあります。このシリーズ記事は3部構成で、ServiceNowとElasticsearchをセットアップしてインシデント管理を自動化する手順や、Canvas workpadを使ってインシデントを可視化、プレゼンテーション、および管理する方法をご紹介してまいります。
第1回となる今回は、サービスデスクの機能として使われることも多い人気のワークフロー管理ツール、ServiceNowと、Elasticsearchの間に双方向性の関係をセットアップする方法を検討します。具体的なシナリオとして、(1)機械学習が特定する異常ベースのアラートを通じてチケットを自動作成し、(2)チケットがアップデートされたら自動でElasticsearchをアップデートする、というプロジェクトのアイデアを実演してみます。このプロジェクトの目的はエコシステム全体について、インシデントの検知から、調査、管理まで360度の視界を確立することです。そのプロセスの一環として、次のレジリエンシー(回復性)メトリックを算出します。
- MTTA(平均応答時間、Mean Time to Acknowledgement) — 応答性の追跡に使われる主要なメトリックです。MTTAの値が大きい場合、アラートが氾濫し、チームが応答するまでに時間がかかりすぎる状況となっていることがしばしばあります。
- MTTR(平均復旧時間、Mean Time to Resolution) — チケットの解決までにかかる時間の把握に最適です。チケットのステータスが‘未解決’から‘解決済み’または‘終了’になるまでの平均時間に基づいて算出します。
- MTBF(平均故障間隔、Mean Time between Failures) — 測定対象のレジリエンシー(回復性)の把握に役立ちます。MTBFの値が小さい場合、障害が短時間に高頻度で発生していることを意味します。このメトリックは1時間ごとに計測され、稼働総時間をオフラインとなったインシデントの数で割って算出します。
多数のツールを開いてあちこち移動するよりも、わかりやすいウインドウを1つ操作する方が便利に決まっています。つまり同一のツール上にMTTA、MTTR、MTBFを表示してデータを特定、検索すれば、アプリケーションやサービス、プロジェクト、チーム、部署といった特定のエンティティが上記のレジリエンシーメトリックに及ぼす影響をリアルタイムに把握する取り組みとなります。同じデータも、Kibanaに内蔵された多彩なレンズを通して見ることで、SREsやSOCアナリスト、経営幹部に精選されたインサイトを提供することが可能になります。
サンプルプロジェクト
この記事では、Elasticsearch、ServiceNow、およびHeartbeat(アップタイム監視プロダクト)を使って次のように動作するサンプルプロジェクトを立ち上げてみます。
- Heartbeatがアプリケーションを継続的に監視し、オンラインかどうか、および、応答性を確認する。
- あるアプリケーションが5分以上ダウンしている場合、Watcher(Elasticsearchに内蔵のアラートフレームワーク)がServiceNowでインシデントチケットを作成する。ただし“アラート疲れ”を軽減するため、チケットはその特定のアプリケーションについて未解決、またはアクティブなServiceNowチケットが存在しない場合のみ作成ものとする。
- Alex(筆者です)は作成したチケットを自身にアサインし、メモを加筆して作業を開始する。
- ServiceNowでチケットがアップデートされると、Elasticsearchでもそのレコードがアップデートされる。
- マネジメントのためにCanvasを使って未解決チケットと、MTTA、MTTR、MTBF、最も問題のあるアプリケーションなどを追跡する。
この結果は、次のようなCanvasダッシュボードになります。
このプロジェクトを、いくつかのセクションに分けて進めましょう。
- ServiceNowをセットアップする
- Elasticsearchを自動でアップデートするよう、ServiceNowにbusiness ruleを設定する
- Heartbeatを設定し、アプリケーションを監視する
- Elasticsearchインデックスを設定する
- メトリックを継続的に算出するため、いくつかの変換を作成する
- 機械学習とアラートを使用してServiceNowに自動でチケットを作成する。ただし、ServiceNowにチケットが存在しない場合に限る
- ピボットとCanvas表現など、応用的なElasticsearch SQLを使って上の画像のCanvasダッシュボードを構築する
このサンプルをご自身で再現するためのデプロイをお持ちでない方は、Elastic CloudのElasticsearch Service無料トライアルを通じて、またはローカルに無料でインストールしてお試しいただくことができます。また、ServiceNowのインスタンスをお持ちでない場合、個人開発者向けインスタンスを立ち上げることができます。
ServiceNowを準備する
インシデントフォームをパーソナライズする
本記事は、新規のまっさらなServiceNowインスタンスを使用しており、既存のケースがないという前提で進めます。既存のセットアップがある場合も、非常にシンプルな手順で進めることができます。はじめにIncidentアプリをアップデートし、Applicationと呼ばれる新しいフィールドを追加して、どのアプリケーションに問題があるか追跡します。
- ServiceNowでIncidentアプリを開きます。
- 一時的なインシデントを作成します。値は何でも構いません。
- [Form Design]ウィザードに進みます。
- シンプルにするため、[String]フィールドを追加して問題のアプリケーション名だけを追跡することとします。実際運用する場合のセットアップでは、アプリケーションをServiceNow内の特定のエンティティとしてセットアップするやり方がおそらく最善となります。以下のように、新しい[String]フィールドを設定します。
- この設定を保存してからインシデントフォームに戻り、アイコンを使って表示するフィールドの設定をパーソナライズします。
- この時点で新しい詳細フィールドを備えたインシデントフォームが表示され、どのアプリケーションに問題が起きているか判断できます。次に、インシデントに何らかのアップデートがあった場合にElasticsearchが自動でアップデートされるようにServiceNowを設定する必要があります。
Elasticsearchが作成するインシデント用にServiceNowユーザーを作成する
インシデントソースの把握は重要です。そのために、ServiceNowがCaller
フィールドを使用する必要があります。チケット作成時にこのフィールドが設定されるようにすることで、自動生成のチケットであることを把握できるようにします。新規ユーザーを作成するには、ServiceNowでUsersアプリを開き、以下のフィールドを持つ新規ユーザーを作成し、保存します。
- Id: elastic_watcher
- First name:Elasticsearch Watcher
- Email: admin@elasticutilities.co
ServiceNowとの双方向通信
ServiceNowのインシデントは、シンプルなREST API POSTリクエストを送ることで作成できます。しかし自動でElasticsearchをアップデートするようServiceNowを設定するには、また別の手法を使います。それが、ServiceNowのbusiness ruleです。このルールはインシデントの表を監視し、特定のフィールドに何らかの変化があると、ある種のロジックを実行します。そして、そのロジックを通じて変更内容をElasticsearchにインデックスします。Elasticsearchは認証情報を必要とするため、以下の手順に沿って正しく設定します。
- Elasticsearchに新規のロールとユーザーを作成する(最小権限の原則を適用)
- ServiceNowにRESTメッセージとauthプロフィールをセットアップする
- business ruleを作成する
Elasticsearchにロールとユーザーを作成する
このプロセスについては詳しいドキュメントが公開されていますので、この記事上ではごく簡単な説明に留めます。今回必要となるのは、servicenow-incident-updatesインデックスエイリアス内にドキュメントインデックスを実行する権限しか持たないロールです。最小権限の原則に沿うために、この機能に固有のロールを作成することを推奨しています。Kibana、またはAPIのいずれかを使うオプションがあります。手順は次のとおりです。
Kibana
- [Management](管理) -> [Role](ロール)に進みます
- ロールを作成します
- 各フィールドを以下の通りに設定します
- Indices: servicenow-incident-updates
- Privileges: index
API
Kibanaのコンソールを使って以下を実行します。
POST /_security/role/servicenow_updater { "indices": [ { "names": [ "servicenow-incident-updates" ], "privileges": ["index"] } ] }
これで、上述のロールを持つユーザーを作成することができました。
Kibana
- [Management](管理) -> [Users](ユーザー)に進みます
- ユーザーを作成します
- 各フィールドを以下の通りに設定します
- Username: ServiceNowUpdater
- Password: 独自のパスワードを設定してください
- Role: servicenow_updater
API
POST /_security/user/ServiceNowUpdater { "password" :"任意で設定したパスワード", "roles" : [ "servicenow_updater" ], "full_name" :"ServiceNow Incident Updater", "email" : "admin@example.com" }
ServiceNowにElasticsearch RESTメッセージとauthプロフィールを作成する
1つ前の手順で目的に沿ったユーザーをElasticsearchにセットアップしました。これで、ServiceNowに取り掛かることができます。ServiceNowでREST Messagesアプリを開き、新しいレコードを作成します。名前を“Elasticsearch”に、エンドポイントをお使いのElasticsearchエンドポイントに設定します。筆者はElastic Cloudで実行しているので、エンドポイントはhttps://[CloudID].westeurope.azure.elastic-cloud.c...
のようになります。
次に、認証をセットアップします。[Authentication type]を[Basic]に指定し、[Basic auth profile]フィールドの拡大鏡アイコンをクリックします。
次に、新規のbasic auth configurationレコードを作成します。レコード名を“ElasticsearchIncidentUpdater”に、またユーザー名とパスワードフィールドに前出の手順で使った値を設定します。筆者の場合は、以下のようになります。
- Username: ServiceNowUpdater
- Password: [任意で設定したパスワード]
このレコードを保存し、REST MessageアプリのElasticsearchレコードに戻ります。新しいbasic auth profileをかならず使用してください。[HTTP Methods]セクションが表示されている場合は、[submit]をクリックしてから前の手順でElasticsearch
と命名したREST Messageを再オープンする必要があります。
下の画像のように表示されるはずです。
次に、ServiceNowに新しいHTTPメソッドレコードを作成します。ステップが多数あるので、注意深く進めてください。
- [HTTP Methods]の隣にある[New]ボタンをクリックします。
- [Name]を[UpdateIncident]に設定します。
- [HTTP method]を[POST]に設定します。
- [authentication type]をかならずペアレントから継承したタイプに設定します。
- [endpoint]をお使いのElasticsearchエンドポイント(ポートを含む)に設定し、さらに
/servicenow-incident-updates/_doc
を付記します。たとえばhttps://[CloudID].westeurope.azure.elastic-cloud.c...
のようになります。 - [Content-Type]名と[application/json]値を入力してHTTPヘッダーを作成します。
- [Content]フィールドを以下のように設定します。
{"@timestamp": "${timestamp}", "incidentID": "${incidentID}", "assignedTo": "${assignedTo}", "description": "${description}", "state": "${state}", "updatedDate": "${updatedDate}", "workNotes": "${workNotes}", "app_name": "${appName}"}
- [New]ボタンを使って、下のスクリーンショットで[Name]にリストされている項目を指定することにより、下に示された変数置換を作成します(変数置換UIコンポーネントを表示するには、[Submit]ボタンをクリックしてからエンドポイントに戻る操作が必要となることがあります)。[Related Links]以下に[Auto-generate variables]というリンクがあるので、こちらを使用してみてください。
- 右上の[Update]ボタンをクリックます。クリックすると、RESTメッセージフォームに戻ります。
- [Update]をクリックして保存します。
これで全部です…お疲れさまでした!ほとんどの手順は簡単ですが、手順7と8には説明が必要かもしれません。これは、逆の順番で説明した方がわかりやすいと思います。手順8は、レコードに変数を追加し、リクエストを実行する際に外部に出ていくRESTメッセージのコンテンツ内の変数を置換できるようにしています。手順7は、その変数を活用し、POSTリクエストにコンテンツフィールドを作成しています。このコンテンツフィールドが、Elasticsearchに送信されるところがポイントです。
ServiceNowのbusiness ruleを作成する
このセクションは、インシデントが作成、またはアップデートされたとき、かならずElasticsearchにアップデートを送信する仕組みの核となるコンポーネントです。まずServiceNowでBusiness Rulesアプリを開き、新規のルールを作成します。手順は複数のパートにわかれます。まず実行する表を設定し、いつ実行するかの条件を定め、次にロジックを実行します。まず名前をつけましょう。[name]フィールド名を[Elasticsearch Update Incident]に、表の名前を[incident]に設定します。また、後ほどカスタムスクリプトを使用するので、ここで[Advanced]というチェックボックスを選択しておく必要があります。
[When to run]のタブで下のように設定します。
上の画像の設定は、インシデントが[Insert](挿入)、[Update](アップデート)、または[Delete](削除)された後にbusiness ruleを実行する、という意味になります。これで、[State](ステータス)や[Work notes](作業メモ)、[Assigned to](アサイン先)、Updated field(アップデートフィールド)にアップデートがあった場合、ルールが実行されます。
次に、ここまで準備したすべてのパーツを組み合わせます。[Advanced]タブを開き、次のスニペットと同じスクリプトを設定します。
(function executeRule(current, previous) { try { var r = new sn_ws.RESTMessageV2('Elasticsearch', 'UpdateIncident'); r.setStringParameterNoEscape('incidentID', current.number); r.setStringParameterNoEscape('description', current.description); r.setStringParameterNoEscape('updatedDate', current.sys_updated_on); r.setStringParameterNoEscape('assignedTo', current.getDisplayValue("assigned_to")); r.setStringParameterNoEscape('state', current.getDisplayValue("state")); r.setStringParameterNoEscape('workNotes', current.work_notes); r.setStringParameterNoEscape('appName', current.u_application); r.setStringParameterNoEscape('timestamp', new GlideDateTime().getValue()); r.execute(); } catch (ex) { gs.info(ex.message); } })(current, previous);
このスクリプトは、先ほど作成したElasticsearch RESTメッセージを使用します。具体的には、UpdateIncident POSTリクエストを使用し、先ほど作成した関連フィールドにインシデントから変数置換をポピュレートして、Elasticsearch内のservicenow-incident-updatesに送信します。
スクリプトを保存したら、この手順は完了です。
Heartbeatを使ってアプリケーションを監視する
稼働状況の監視に使われるる質問の1つに、「稼働中か、ダウンしているか?」というものがあります。 その答えは、Heartbeatが生成するデータを使って提供されます。HeartbeatはTCP、HTTPまたはICMP使ってエンドポイントに一定間隔でpingを送り、オブザーバビリティに役立つ情報を収集します。エコシステムの可用性を理解するには、組織のホストやサービス、Webサイト、APIが稼働しているかどうか把握することが重要です。Heartbeatはレスポンスタイムとレスポンスコードを収集することにより、そうした稼働状況を詳しく把握します。収集したデータをログはメトリック、APMデータと組み合わせると、点と点をつないで全体像を把握し、エコシステム全体のアクティビティを簡単に相関付けることができます。
Heartbeatは簡単に使い始めることができます。Heartbeatドキュメントの記載手順に沿ってセットアップしてください。
筆者のプロジェクトでは、4つのサービスを確認するようHeartbeatをセットアップしました。以下は、そのheartbeat.ymlファイルから抜粋したコードの一部です。
heartbeat.monitors: - name:"Authentication Service" type: http urls: ["192.168.1.38/status"] schedule: '@every 1m' check.response.status:200 - name:"Search Service" type: http urls: ["192.168.1.109/status"] schedule: '@every 1m' check.response.status:200 - name:"Frontend" type: http urls: ["192.168.1.95/status"] schedule: '@every 1m' check.response.status:200 - name:"API Gateway" type: http urls: ["192.168.1.108/status"] schedule: '@every 1m' check.response.status:200
双方向通信に成功!
これで完了です!ここまでご説明した手順で、アップタイムデータをElasticsearchにインジェストし、ElasticsearchとServiceNowを双方向通信で接続することができました。冒頭で触れたように、このブログ記事は3部シリーズ構成となっています。この続きをお試しいただくには、次回の記事をご覧ください。次回は、問題が生じた場合にServiceNowにインシデントを作成するようElasticsearchをセットアップする方法をご紹介します。
ご自身で再現される場合は、Elastic Cloudを使う方法が最も簡単です。Elastic Cloudコンソールにログインしていただくか、14日間の無料トライアルを立ち上げてご利用ください。今回ご紹介した手順は既存のServiceNowインスタンスを使って実行できるほか、個人開発者向けインスタンスを立ち上げてお使いいただくこともできます。
さらに、GitHubやGoogle Driveなどの外部ソースに加えてServiceNowデータを検索するには、Elastic Workplace Searchの事前構築済みServiceNowコネクターをご活用ください。Workplace Searchを使うと一元的な業務用検索エクスペリエンスを構築でき、あらゆるコンテンツソースにわたって関連性に優れた検索結果を手にすることができます。Elastic Cloudのトライアルでも、Workplace Searchをお試しいただくことができます。
Kibanaに内蔵されているUptimeアプリも忘れずにお試しください。上では簡単なHeartbeatの設定を紹介しましたが、この設定を拡張してお使いのエコシステム向けに調整し、パフォーマンスとTLS認証ステータスの双方を監視するといったこともできます。ぜひニーズに応じて設定を拡張してみてください。