StackStormコトハジメ


DMM.com Advent Calendar 2018 16日目の記事です。

インフラにてサーバの面倒見たりしてます @sinnershiki です。

去年のDMM.comアドベントカレンダーではAnsibleとNW機器的な話をしましたが、今年は社内で使っているツールであるStackStormについて紹介できたらと思います。

StackStormとは

StackStormは、イベントドリブンな自動化ツールとなります。OSSツールなIFTTTサービスをイメージしていただくとわかりやすいかと思います。

有名なところではNetflixで使われていたりします。

具体的にどういったことができるかというと、zabbixからnginxのダウン検知を受けてnginxのプロセスを起動させるみたいなことが可能です。

DMMのオウンドメディアであるinsideでも記事が公開されていますので、参照してみてください。

日本StackStormユーザ会も存在します

概要

StackStormは、簡単に下記のような仕組み1でできています。

  • Sensor

StackStormでは、センサーを利用して外部イベントを監視しています。

  • Trigger

センサーは全てのイベントを監視しており、トリガーはその内容を元にイベントのハンドリングを行います。

  • Action/Workflow

アクションは、実際に実行する動作を指します。Slackにメッセージを投稿やnginxを起動など。ワークフローは、アクションの組み合わせになります。Aというアクションを実行後Bを実行など流れを記載する形です。

  • Rule

センサー・トリガーやアクションは一般的にpackと呼ばれるStackStormから提供されるパッケージを利用する場合が多いです。ルールは、その提供されるアクションとトリガーを紐付けるために運用するユーザで記載するものになります。

システム構成

StackStormは、StackStorm本体以外に複数のミドルウェアから成り立ちます。2

  • StackStorm本体
  • nginx
  • mongo
  • RabbitMQ
  • etc...

実際に使う場合は、All in Oneで全てを1台に入れることも可能ですが、HA構成として各コンポーネントを別々に用意し、可用性を高めることも可能です。

使ってみる

インストール

公式には様々なインストール方法3が用意してあるのですが、今回はDockerイメージを使って手軽に試してみましょう

% git clone https://github.com/stackstorm/st2-docker
% cd st2-docker
% make env
% docker-compose up -d
% docker-compose exec stackstorm bash
root@853b4719244d:/# st2 --version
st2 2.9.1, on Python 2.7.6

Web UIもあるので、そちらも確認してみましょう。ログインに必要な情報は下記にあります。

% ls conf/
mongo.env       postgres.env    rabbitmq.env    redis.env       stackstorm.env
% cat conf/stackstorm.env
ST2_USER=st2admin
ST2_PASSWORD=Ch@ngeMe

pack

先程も少し話したように、StackStormではpackを入れて使います。

packの一覧はExchangeにまとまっています。

今回はSlack packを入れてみましょう。

root@853b4719244d:/# st2 pack install slack

For the "slack" packs, the following content will be registered:

rules     |  1
sensors   |  3
aliases   |  0
actions   |  146
triggers  |  0

Installation may take a while for packs with many items.

    [ succeeded ] download pack
    [ succeeded ] make a prerun
    [ succeeded ] install pack dependencies
    [ succeeded ] register pack

+---------+-------------------------+---------+------------------+
| name    | description             | version | author           |
+---------+-------------------------+---------+------------------+
| slack   | Slack Chat integrations | 0.12.5  | StackStorm, Inc. |
+---------+-------------------------+---------+------------------+
root@853b4719244d:/# st2 pack list
+----------+----------+---------------------+---------+------------------+
| ref      | name     | description         | version | author           |
+----------+----------+---------------------+---------+------------------+
| chatops  | chatops  | ChatOps integration | 1.0.0   | StackStorm, Inc. |
|          |          | pack                |         |                  |
| core     | core     | Basic core actions. | 1.0.0   | StackStorm, Inc. |
| default  | default  | Default pack where  | 1.0.0   | StackStorm, Inc. |
|          |          | all resources       |         |                  |
|          |          | created using the   |         |                  |
|          |          | API with no pack    |         |                  |
|          |          | specified get       |         |                  |
|          |          | saved.              |         |                  |
| examples | examples | Example sensors,    | 0.2.1   | StackStorm, Inc. |
|          |          | triggers, actions   |         |                  |
|          |          | and rules.          |         |                  |
| linux    | linux    | Generic Linux       | 1.0.1   | StackStorm, Inc. |
|          |          | actions             |         |                  |
| packs    | packs    | Pack management     | 1.0.0   | StackStorm, Inc. |
|          |          | functionality.      |         |                  |
| slack    | slack    | Slack Chat          | 0.12.5  | StackStorm, Inc. |
|          |          | integrations        |         |                  |
+----------+----------+---------------------+---------+------------------+

GUIだとこんな形で確認できます

Action

先程入れたSlackのActionを確認してみるには下記の方法で確認できます。

root@853b4719244d:/# st2 action list --pack=slack
+-----------------------------------+-------+-----------------------------------+
| ref                               | pack  | description                       |
+-----------------------------------+-------+-----------------------------------+
| slack.api.test                    | slack | Checks API calling code.          |
| slack.apps.permissions.info       | slack | Returns list of permissions this  |
|                                   |       | app has on a team.                |
| slack.chat.postMessage            | slack | Sends a message to a channel.     |
| slack.chat.unfurl                 | slack | Provide custom unfurl behavior    |
|                                   |       | for user-posted URLs              |
| slack.chat.update                 | slack | Updates a message.                |
| slack.conversations.leave         | slack | Leaves a conversation.            |
| slack.conversations.list          | slack | Lists all channels in a Slack     |
|                                   |       | team.                             |
~~ いっぱいあるので省略 ~~
| slack.users.setPhoto              | slack | Set the user profile photo        |
| slack.users.setPresence           | slack | Manually sets user presence.      |
| slack.users_filter_by             | slack | Lists users in a Slack team       |
|                                   |       | matching certain creterias.       |
+-----------------------------------+-------+-----------------------------------+

当然Web UIからも確認できます。また、試しにActionを実行することも可能です。

Triggerを指定してActionを動かす

では、実際にRuleを作ってアクションを実行してみましょう

GUIからもルールは作れるのですが、ルールをyamlで記載し、git等で管理ができることもまたStackStormのメリットであるため、CLIからルールの作成と登録をやってみましょう

また、全てのルールには登録するpack名を決める必要があるため、今回は test-pack という名前を利用することを決めておきます

ルールを置くディレクトリ名をStackStormのpack保存ルールに合わせるために予めディレクトリも用意します

root@853b4719244d:/# mkdir -p  /opt/stackstorm/packs/test-pack/rules
root@853b4719244d:/# vi /opt/stackstorm/packs/test-pack/rules/st2-webhook-to-slack.yaml
root@853b4719244d:/# st2 rule create /opt/stackstorm/packs/test-pack/rules/st2-webhook-to-slack.yaml
+-------------+----------------------------------------------------------+
| Property    | Value                                                    |
+-------------+----------------------------------------------------------+
| id          | 5c15114db29dc70173918139                                 |
| name        | st2-webhook-to-slack                                     |
| pack        | test-pack                                                |
| description | post message to slack from webhook.                      |
| action      | {                                                        |
|             |     "ref": "slack.post_message",                         |
|             |     "parameters": {                                      |
|             |         "username": "st2",                               |
|             |         "webhook_url": "<webhook_url>",                  |
|             |         "message": "{{trigger.body.message}}",           |
|             |         "icon_emoji": ":ok_woman:",                      |
|             |         "channel": "{{trigger.body.channel}}"            |
|             |     }                                                    |
|             | }                                                        |
| context     | {                                                        |
|             |     "user": "st2admin"                                   |
|             | }                                                        |
| criteria    | {                                                        |
|             |     "trigger.body.event_name": {                         |
|             |         "pattern": "post_message",                       |
|             |         "type": "equals"                                 |
|             |     }                                                    |
|             | }                                                        |
| enabled     | True                                                     |
| ref         | test-pack.st2-webhook-to-slack                           |
| tags        |                                                          |
| trigger     | {                                                        |
|             |     "type": "core.st2.webhook",                          |
|             |     "ref": "core.9c059214-c1a9-43d9-9e3a-18635b63261e",  |
|             |     "parameters": {                                      |
|             |         "url": "webhook2slack"                           |
|             |     }                                                    |
|             | }                                                        |
| type        | {                                                        |
|             |     "ref": "standard",                                   |
|             |     "parameters": {}                                     |
|             | }                                                        |
| uid         | rule:test-pack:st2-webhook-to-slack                      |
+-------------+----------------------------------------------------------+
/opt/stackstorm/packs/test-pack/rules/st2-webhook-to-slack.yaml
name: "st2-webhook-to-slack"
pack: "test-pack"
description: "post message to slack from webhook."
enabled: true

trigger:
  type: "core.st2.webhook"
  parameters:
    url: "webhook2slack"

criteria:
  trigger.body.event_name:
    pattern: "post_message"
    type: "equals"

action:
  ref: "slack.post_message"
  parameters:
    message: "{{trigger.body.message}}"
    channel: "{{trigger.body.channel}}"
    username: "st2"
    icon_emoji: ":ok_woman:"
    webhook_url: "<webhook_url>"

これで https://localhost/api/v1/webhooks/webhook2slack をトリガーにするRuleができました

criteria は、Ruleにおける条件です。今回は、webhookのbodyにevent_nameという項目があり、その項目の中身がpost_messageの場合イベントが発火します。また、メッセージやチャンネルの情報はwebhookから受け取った情報を利用します。

StackStormのwebhookを利用するには、StackStormへのログイン情報が必要になります。今回は、st2 authコマンドを利用して事前にtokenを取得しておき、その値を利用します。

root@853b4719244d:/# st2 auth st2admin -p Ch@ngeMe
+----------+----------------------------------+
| Property | Value                            |
+----------+----------------------------------+
| user     | st2admin                         |
| token    | 90190020e2a94040a38c551132ab86c1 |
| expiry   | 2018-12-16T14:29:35.455141Z      |
+----------+----------------------------------+
root@853b4719244d:/# curl -k https://localhost/api/v1/webhooks/webhook2slack -d '{"message": "test message from webhook", "event_name": "post_message", "channel": "<channel_name>"}' -H 'Content-Type: application/json' -H 'X-Auth-Token: 90190020e2a94040a38c551132ab86c1'
{
    "event_name": "post_message",
    "message": "test message from webhook",
    "channel": "<channel_name>"

とまあこんな具合でwebhookのイベントをトリガーとしてslackへ投稿することができました。

まとめ

StackStormの使い方について紹介しました。StackStormでは、イベントハンドリングによる自動化を実現することが可能です。また、今回は紹介しませんでしたが、ワークフローを用いればより高度なことを実現することも可能になります。

機会があれば、Workflowの作り方やHA構成でのStackStormの構築など紹介できればと思います。