CentOS 7にトリガーに応じてワークフローやアクションを行わせるIT自動化ツール「StackStorm」をインストールする

先日行われてた「【IoT x クラウド】自動化・IoTプラットフォーム StackStorm勉強会」に行ってきたのだが、今回は勉強会の主題であった自動化ツール「StackStorm(Githubではこちら)」をCentOS 7にインストールしてみることにする。ツールの概要については以下のスライドを見てもらえるとわかるかと思うが、ざっくり「いろんなイベントをトリガーにジョブを実行できるツール」という認識(IFTTTライクなツールといえばわかりやすいのだろうか?)。つまり、メールとか特定のログやセンサーの閾値をオーバーした場合などにジョブを実行できるということなので、かなり便利そうなツールだ。
(まぁ、先日Brocadeに買収されたというところから某Vy〇Sとかが連想されるので、そのうちフォークされるかもしれないけど…)

特性上、単一障害点になりやすいため冗長化やサービス監視が必要になるが、今回はお試しなのでシングル構成で構築する。

1.インストール

こちらに公式ドキュメントがあるので、これを参考に進めていく。
なお、CentOS 7の場合は自動インストールスクリプトが用意されているのでそれを使えばよい(以前はよくこけたらしい)。

curl -sSL https://stackstorm.com/packages/install.sh | bash -s -- --user=st2admin --password=foo

…で残念ながら実際こけたので、今回は手動でインストールを進めていく。
スクリプト直すの面倒くさいし。

1-1.SELinuxの設定変更

まず、SELinuxが有効になっている場合は以下のコマンドでSELinuxについての設定変更を行う。
(SELinuxが最初から無効になっている場合はこの手順は不要)

sudo yum install -y policycoreutils-python
sudo semanage port --list | grep -q 25672 || sudo semanage port -a -t amqp_port_t -p tcp 25672
sudo setsebool -P httpd_can_network_connect 1

1-2.MongoDB・RappidMQ・PostgreSQLのインストール

次に、MongoDB・RappidMQ・PostgreSQLのインストールを行う。
まず、以下のコマンドでEpelリポジトリを導入する。

sudo yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

以下のコマンドでMongoDBのインストールをする。

sudo rpm --import https://www.mongodb.org/static/pgp/server-3.2.asc
sudo sh -c "cat <<EOT > /etc/yum.repos.d/mongodb-org-3.2.repo
[mongodb-org-3.2]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/7Server/mongodb-org/3.2/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.2.asc
EOT"
sudo yum -y install mongodb-org

以下のコマンドでRappidMQをインストールする。

sudo yum -y install rabbitmq-server

最後に、PostgreSQLのインストールを行う。

sudo yum -y install postgresql-server postgresql-contrib postgresql-devel
sudo postgresql-setup initdb
sudo sed -i "s/\(host.*all.*all.*127.0.0.1\/32.*\)ident/\1md5/" /var/lib/pgsql/data/pg_hba.conf
sudo sed -i "s/\(host.*all.*all.*::1\/128.*\)ident/\1md5/" /var/lib/pgsql/data/pg_hba.conf

無事にインストールが完了したら、以下のコマンドでサービスの起動設定を行う。

sudo systemctl start mongod rabbitmq-server postgresql
sudo systemctl enable mongod rabbitmq-server postgresql

1-3.StackStormのインストール

前提パッケージを導入したら、以下のコマンドでStackStormのインストールを行う。

curl -s https://packagecloud.io/install/repositories/StackStorm/stable/script.rpm.sh | sudo bash
sudo yum install -y st2 st2mistral

2.初期設定

2-1.データベースの作成

StackStormのインストールができたら、データベースの作成を行う。
以下のコマンドを実行する。

cat << EHD | sudo -u postgres psql
CREATE ROLE mistral WITH CREATEDB LOGIN ENCRYPTED PASSWORD 'StackStorm';
CREATE DATABASE mistral OWNER mistral;
EHD
/opt/stackstorm/mistral/bin/mistral-db-manage --config-file /etc/mistral/mistral.conf upgrade head
/opt/stackstorm/mistral/bin/mistral-db-manage --config-file /etc/mistral/mistral.conf populate
[root@BS-PUB-STACKSTORM ~]# /opt/stackstorm/mistral/bin/mistral-db-manage --config-file /etc/mistral/mistral.conf upgrade head
INFO  [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO  [alembic.runtime.migration] Will assume transactional DDL.
INFO  [alembic.runtime.migration] Running upgrade  -> 001, Kilo release
INFO  [alembic.runtime.migration] Running upgrade 001 -> 002, Kilo
INFO  [alembic.runtime.migration] Running upgrade 002 -> 003, cron_trigger_constraints
INFO  [alembic.runtime.migration] Running upgrade 003 -> 004, add description for execution
INFO  [alembic.runtime.migration] Running upgrade 004 -> 005, Increase executions_v2 column size from JsonDictType to JsonLongDictType
INFO  [alembic.runtime.migration] Running upgrade 005 -> 006, add a Boolean column 'processed' to the table  delayed_calls_v2
INFO  [alembic.runtime.migration] Running upgrade 006 -> 007, Move system flag to base definition
INFO  [alembic.runtime.migration] Running upgrade 007 -> 008, Increase size of state_info column from String to Text
INFO  [alembic.runtime.migration] Running upgrade 008 -> 009, Add database indices
INFO  [alembic.runtime.migration] Running upgrade 009 -> 010, add_resource_members_v2_table
INFO  [alembic.runtime.migration] Running upgrade 010 -> 011, add workflow id for execution
[root@BS-PUB-STACKSTORM ~]# /opt/stackstorm/mistral/bin/mistral-db-manage --config-file /etc/mistral/mistral.conf populate
/opt/stackstorm/mistral/lib/python2.7/site-packages/sqlalchemy/sql/default_comparator.py:153: SAWarning: The IN-predicate on "action_definitions_v2.id" was invoked with an empty sequence. This results in a contradiction, which nonetheless can be expensive to evaluate.  Consider alternative strategies for improved performance.
  'strategies for improved performance.' % expr)
/opt/stackstorm/mistral/lib/python2.7/site-packages/sqlalchemy/sql/default_comparator.py:153: SAWarning: The IN-predicate on "workflow_definitions_v2.id" was invoked with an empty sequence. This results in a contradiction, which nonetheless can be expensive to evaluate.  Consider alternative strategies for improved performance.
  'strategies for improved performance.' % expr)

2-2.ユーザの作成・設定

StackStorm用のプロセスユーザ(stanley)の作成及び設定を行う。

sudo useradd stanley
sudo mkdir -p /home/stanley/.ssh
sudo chmod 0700 /home/stanley/.ssh

stanleyユーザで利用する鍵ファイルの作成をする。

sudo ssh-keygen -f /home/stanley/.ssh/stanley_rsa -P ""
sudo sh -c 'cat /home/stanley/.ssh/stanley_rsa.pub >> /home/stanley/.ssh/authorized_keys'
sudo chown -R stanley:stanley /home/stanley/.ssh

sudo実行時にパスワードを要求されないようにする。

sudo sh -c 'echo "stanley ALL=(ALL) NOPASSWD: SETENV: ALL" >> /etc/sudoers.d/st2'
sudo chmod 0440 /etc/sudoers.d/st2
sudo sed -i -r "s/^Defaults\s+\+?requiretty/# Defaults +requiretty/g" /etc/sudoers

2-3.サービス起動

もろもろの設定ができたら、以下のコマンドを実行してStackStormのサービスを起動する。

st2ctl reload
sudo st2ctl start
st2ctl reload

3.認証情報の登録

さて、とりあえずサービスとしては起動させたけど、まだ管理ユーザの認証情報などの設定が終わっていない。
以下のコマンドを実行し、StackStormの管理ユーザ「st2admin」のパスワードを設定する。

sudo yum -y install httpd-tools
echo "パスワード" | sudo htpasswd -i /etc/st2/htpasswd st2admin
sed -i '/^[auth]/,/enable/s/enable = False/enable = True/g' /etc/st2/st2.conf

パスワードの設定が完了したら、以下のコマンドでサービスの再起動等を行う。

sudo st2ctl restart-component st2api

最後に、認証情報についての情報をAUTH TOKENとして設定しておく。

st2 auth st2admin
export ST2_AUTH_TOKEN=$(st2 auth st2admin -p パスワード -t)
st2 action list
[root@BS-PUB-STACKSTORM ~]# st2 auth st2admin
Password:
+----------+----------------------------------+
| Property | Value                            |
+----------+----------------------------------+
| user     | st2admin                         |
| token    | c51a3c5331d541dc8adfca0833262568 |
| expiry   | 2016-10-16T13:52:44.200376Z      |
+----------+----------------------------------+
[root@BS-PUB-STACKSTORM ~]# export ST2_AUTH_TOKEN=$(st2 auth st2admin -p password -t)
[root@BS-PUB-STACKSTORM ~]# st2 action list
+---------------------------------+---------+---------------------------------+
| ref                             | pack    | description                     |
+---------------------------------+---------+---------------------------------+
| chatops.format_execution_result | chatops | Format an execution result for  |
|                                 |         | chatops                         |
| chatops.post_message            | chatops | Post a message to stream for    |
|                                 |         | chatops                         |
| chatops.post_result             | chatops | Post an execution result to     |
|                                 |         | stream for chatops              |
| core.announcement               | core    | Action that broadcasts the      |
|                                 |         | announcement to all stream      |
|                                 |         | consumers.                      |
| core.http                       | core    | Action that performs an http    |
|                                 |         | request.                        |
| core.local                      | core    | Action that executes an         |
|                                 |         | arbitrary Linux command on the  |
|                                 |         | localhost.                      |
| core.local_sudo                 | core    | Action that executes an         |
|                                 |         | arbitrary Linux command on the  |
|                                 |         | localhost.                      |
| core.noop                       | core    | Action that does nothing        |
| core.remote                     | core    | Action to execute arbitrary     |
|                                 |         | linux command remotely.         |
| core.remote_sudo                | core    | Action to execute arbitrary     |
|                                 |         | linux command remotely.         |
| core.sendmail                   | core    | This sends an email             |
| core.windows_cmd                | core    | Action to execute arbitrary     |
|                                 |         | Windows command remotely.       |
| linux.check_loadavg             | linux   | Check CPU Load Average on a     |
|                                 |         | Host                            |
| linux.check_processes           | linux   | Check Interesting Processes     |
| linux.cp                        | linux   | Copy file(s)                    |
| linux.diag_loadavg              | linux   | Diagnostic workflow for high    |
|                                 |         | load alert                      |
| linux.dig                       | linux   | Dig action                      |
| linux.file_touch                | linux   | Touches a file                  |
| linux.lsof                      | linux   | Run lsof                        |
| linux.lsof_pids                 | linux   | Run lsof for a group of PIDs    |
| linux.mv                        | linux   | Move file(s)                    |
| linux.netstat                   | linux   | Run netstat                     |
| linux.netstat_grep              | linux   | Grep netstat results            |
| linux.pkill                     | linux   | Kill processes using pkill      |
| linux.rm                        | linux   | Remove file(s)                  |
| linux.rsync                     | linux   | Copy file(s) from one place to  |
|                                 |         | another w/ rsync                |
| linux.scp                       | linux   | Secure copy file(s)             |
| linux.service                   | linux   | Stops, Starts, or Restarts a    |
|                                 |         | service                         |
| linux.traceroute                | linux   | Traceroute a Host               |
| linux.vmstat                    | linux   | Run vmstat                      |
| linux.wait_for_ssh              | linux   | Action which waits for a SSH    |
|                                 |         | server to become accessible. By |
|                                 |         | default, if no credentials are  |
|                                 |         | provided, this action will try  |
|                                 |         | to authenticate using the       |
|                                 |         | system user username and key    |
|                                 |         | file.                           |
| packs.check_auto_deploy_repo    | packs   | Check if a given branch in a    |
|                                 |         | ST2 Pack's Git repository       |
|                                 |         | should be auto deployed         |
| packs.delete                    | packs   | Deletes the pack from local     |
|                                 |         | content repository.             |
| packs.deploy                    | packs   | Deploy StackStorm Pack(s)       |
| packs.download                  | packs   | Downloads packs and places it   |
|                                 |         | in the local content            |
|                                 |         | repository.                     |
| packs.expand_repo_name          | packs   | For supplied ST2 pack Repo      |
|                                 |         | return the Git URL and if it    |
|                                 |         | has a subtree.                  |
| packs.info                      | packs   | Get currently deployed pack     |
|                                 |         | information                     |
| packs.install                   | packs   | Installs packs from st2-contrib |
|                                 |         | into local content repository.  |
|                                 |         | Will download pack, load the    |
|                                 |         | actions, sensors and rules from |
|                                 |         | the pack. Note that install     |
|                                 |         | require reboot of some st2      |
|                                 |         | services.                       |
| packs.load                      | packs   | Action that reloads all st2     |
|                                 |         | content.                        |
| packs.restart_component         | packs   | Action that restarts st2        |
|                                 |         | service.                        |
| packs.setup_virtualenv          | packs   | Set up virtual environment for  |
|                                 |         | the provided packs              |
| packs.uninstall                 | packs   | Uninstalls packs from local     |
|                                 |         | content repository. Removes     |
|                                 |         | pack and content from st2. Note |
|                                 |         | that uninstall require reboot   |
|                                 |         | of some st2 services.           |
| packs.unload                    | packs   | Unregisters all content from a  |
|                                 |         | pack.                           |
| packs.update_virtualenv         | packs   | Update / reinstall Python       |
|                                 |         | dependencies listed in          |
|                                 |         | requirements.txt inside the     |
|                                 |         | pack virtual environment        |
| packs.virtualenv_prerun         | packs   | Transformation step to conver   |
|                                 |         | packs_status to list of packs.  |
+---------------------------------+---------+---------------------------------+

4.WebUIのインストール

コンソールからだけではなくWebブラウザから操作できるようにするため、WebUIのインストールを行う。
その際にSSL対応についても実施するため、Nginxについてもインストールをする。

sudo rpm --import http://nginx.org/keys/nginx_signing.key
sudo sh -c "cat <<EOT > /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/rhel/7/x86_64/
gpgcheck=1
enabled=1
EOT"
sudo yum install -y st2web nginx

SSLの設定を行う。

sudo mkdir -p /etc/ssl/st2
sudo openssl req -x509 -newkey rsa:2048 -keyout /etc/ssl/st2/st2.key -out /etc/ssl/st2/st2.crt -days 365 -nodes -subj "/C=JP/ST=Tokyo/L=Tacikawa/O=/OU=/CN=$(hostname)"
sudo cp /usr/share/doc/st2/conf/nginx/st2.conf /etc/nginx/conf.d/
sudo sed -i 's/default_server//g' /etc/nginx/nginx.conf

Nginxのサービス起動設定を行う。

sudo systemctl restart nginx
sudo systemctl enable nginx

5.ブラウザから管理画面にアクセスする

これでブラウザからのアクセスもできるようになるはずだ。
StackStormをインストールしたサーバにアクセスしてみよう。

ID/PWは「st2admin/先ほど設定したパスワード」になる。
ログイン直後の画面がこちら。

実際に処理をさせる場合は、上部メニューのACTIONSから行わせることができる。
今回はインストールまでとし、実際の動作については次回以降に触れることにする。