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 |
+-------------+----------------------------------------------------------+
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の構築など紹介できればと思います。