これは エーピーコミュニケーションズ Advent Calendar 2019 の17日目の記事です。
- Dockerで始めるStackstorm再入門1/3(環境構築からOrquestaで書いたWorkflowの結果をslackに通知する)
- Dockerで始めるStackstorm再入門2/3(条件分岐させるWorkflowと定期実行させるRuleを書く)
- Dockerで始めるStackstorm再入門3/3(pythonスクリプトとmockを使ったテストコードを書く)
- 番外編
0. そもそもStackstormとは
Stackstorm
みなさん、ご存知でしょうか?
Stackstormは、イベント駆動型
でひとつひとつの処理を下の図のようにWorkflowとして繋げながら、定形処理の自動化を進めることができるOSSです。
出所:StackstormというIFTTT的なツールをDockerコンテナに乗せた小話
Stackstormではこのひとつひとつの処理をActionと呼ぶので、WorkflowとはActionを組み合わせたものともいえるでしょう。
もし、IFTTTというサービスをご存知でしたら、IFTTTでやっていることができると考えてください。
実際、Stackstormはその特性からIFTTT for Ops
なんて呼ばれることもあります。
Stackstorm v.s. Jenkins
Stackstormは類似OSSとしてJenkinsと比較されることがありますが、
学習コストを抑えて手っ取り早く自動化を推し進めるならJenkins、切り戻しや処理の並列処理などワークフローを柔軟に定義
したい場合はStackstormを選ぶのがいいのかなと思います。
外部サービスを活用することはJenkinsと同様に簡単です。
Stackstormではpackと呼ばれる拡張プラグインが提供されています。
1. Orquestaという新しいワークフローエンジン
さて、そんなStackstormに新しいワークフローエンジンのOrquesta
が発表されました。
公式のドキュメントによれば、このように謳われています。
- Orquestaは
Stackstorm自身が開発
したネイティブなワークフローエンジン - 目標はMistralやActionChainを代替できるところまでもっていくこと
- Mistralはopenstackが開発
Orquesta is a workflow engine designed specifically to run natively in StackStorm. The goal is to replace ActionChain and Mistral in the future.
参考:
[Orquesta — StackStorm 3.1.0 documentation]
(https://docs.stackstorm.com/orquesta/index.html)
ただ残念なことにサンプルコードが充実していません!!!!!!!!泣
そこで、今回複数サンプルコードを作ってみました。
(めちゃくちゃがんばったので、みなさん奮って記事にいいね!をお願いします!!)
st2からの出力結果を整形した。 pic.twitter.com/BtQNnInIzf
— gkz (@gkzvoice) December 15, 2019
これらのサンプルコードはDocker上で動くStackstormを使うので、どなたでもStackstormの雰囲気を感じることができるはずです。
ぜひチャレンジしてみてください。
本記事ではこちらのリポジトリをベースにお話するので、併せてご参照ください。
2020/02/05更新
masterブランチにマージしたので、tutorial-install-packにcheck outしなくて大丈夫です。
gkzz/st2-docker-gkz
前置きが長くなりましたが、本記事の目次です。
2. 目次
-
- 構成図とバージョン情報
-
- Dockerホスト側で準備すること
-
- Dockerコンテナ側で準備すること
-
- Actionを使ってディストリビューションを確かめる
-
- ActionとWorkflowを使ってディストリビューションを確かめてslackに通知する
-
- ファイルの編集方法やトラブルシュートと次回予告
3. 構成図とバージョン情報
構成図
※1
Stackstormコンテナ内から同コンテナ外にあるアプリ(flask/nginx)コンテナに接続するために、
ホストのDockerデーモンのソケットファイル(var/run/docker.sock)
をマウントさせています。
ubuntu@st2-pub-1a ~/st2-docker-gkz (tutorial-install-pack) $ cat docker-compose-dev.yml | grep -n -E "/var/run/docker|app"
55: - /var/run/docker.sock:/var/run/docker.sock
56: - /app:/usr/src/app
※2
Gtihubからリポジトリをcloneする際、ssh鍵やパスワードを使わずにおこなうべく、Personal access tokens
を使いました。
トークンの取得方法は下記の記事をご参照ください。
私はrepoをスコープとしてトークンを取得しました。
ubuntu@st2-pub-1a ~/st2-docker-gkz (tutorial-install-pack) $ cat images/stackstorm/opt/reload.d/clone_repo.sh | grep -n -E "clone|x-oauth-basic@github.com/"
6: git clone \
7: "https://${GITHUB_SECRET_TOKEN}:x-oauth-basic@github.com/${GITHUB_ACCT}/${SERVICE_DIR}.git"
参考
Creating a personal access token for the command line - GitHub Help
GITHUB_SECRET_TOKEN、ACCT、SERVICE_DIRはそれぞれ環境変数として扱い、docker-compose-dev.ymlでコンテナ側に渡しています。
$ cat docker-compose-dev.yml | grep -n -E "GITHUB_SECRET_TOKEN|ACCT|SERVICE_DIR"
26: - GITHUB_ACCT #https://github.com/$YOURNAMEの$YOURNAME
27: - GITHUB_SECRET_TOKEN #上述したPersonal access tokens
28: - SERVICE_DIR #flask-docker
バージョン情報
- AWS (EC2, VPC, EIP, etc)
Ubuntu 18.04.3 LTS
- t2.large
- パブリックサブネット1つのみ
- パブリックIP有効化(Auto-assign Public IP Enable)
- ストレージはGeneral Purpose SSD (gp2)、8size (t2.largeを選択した場合の初期値)
- セキュリティグループはsshはローカルのみ接続許可、HTTPとHTTPSはフルオープン
(HTTPはアプリコンテナ、HTTPSはStackstormをwebからそれぞれ閲覧できるように許可)
- Stackstormらバージョン
-
Stackstorm: 3.1.0, on Python 2.7.6
#Stackstormでorquestaを使うためにはバージョンが3.0以上である必要があります。 - RabbitMQ: 3.6
- MongoDB: 3.4
- Redis: 4.0
- Postgresql: 9.6
- Docker version 19.03.5, build 633a0ea838
- docker-compose version 1.24.1, build 4667896b
-
- Stackstormで管理する対象のDockerコンテナで使っているFlaskらのバージョン
- python:3.7.2-stretch
- nginx:1.17.6
4. Dockerホスト側で準備すること
- 4-1. EC2インスタンス立ち上げ
- 4-2. 今回扱うst2-dockerのリポジトリをクローン
- 4-3. 必要な環境変数を~/.bashrcらに記載
- 4-4. 適宜インストール
4-1. EC2インスタンス立ち上げ
基本的には上述しているEC2のスペックを参考に設定をおこなってください。
とくにディストリビューションはubuntu18.04
でしか動作確認をおこなっていないので、ご注意ください。
ところで、起動するインスタンスを設定する際にホスト名をワンライナーで設定することもできます。
設定する場所はStep 3: Configure Instance Detailsと書かれたところです。
ホスト名をst2-pub-1aとする場合はこのように書きます。
#!/bin/bash
EC2_HOSTNAME="st2-pub-1a" \
&& sudo sed \
-i -e 's|127.0.0.1 localhost|127.0.0.1 localhost '"${EC2_HOSTNAME}"'|' \
/etc/hosts \
&& sudo hostnamectl set-hostname ${EC2_HOSTNAME}
あとはインスタンスを起動させてください。
4-2. 今回扱うst2-dockerのリポジトリをクローン
ブランチですが、2091年12月16日現在、git checkout tutorial-install-pack
に移動して以下のチュートリアルを進めてください。
変更があれば、本記事に追記します。
ubuntu@st2-pub-1a ~ $ git clone https://github.com/gkzz/st2-docker-gkz.git
ubuntu@st2-pub-1a ~ $ cd st2-docker-gkz && git checkout tutorial-install-pack
4-3. ~/.basrhcなどに環境変数を記入
(source ~/.bashrcなどで読み込みも。)
ubuntu@st2-pub-1a ~/st2-docker-gkz (tutorial-install-pack) $ tail ~/.bashrc
export HOST_IP='xxx.xxx.xxx.xxx'
export SLACKBOT_NAME='$YOURBOTNAME'
#xoxb-your-slack-token
export SLACKBOT_TOKEN='$YOURBOTTOKEN'
export INCOMING_WEBHOOK_URL='https://hooks.slack.com/services/xxx/yyy/zzz'
export DST_CHANNEL='$CHANNEL'
#https://github.com/$YOURNAME
export GITHUB_ACCT='$YOURNAME'
export GITHUB_SECRET_TOKEN='xxxxxxxxxxxxxxxxxxxx'
export SERVICE_DIR='flask-docker'
4-4. 適宜インストール
make、docker、docker-composeがそれぞれ入っているか確かめたい場合は、以下のようにコマンドを叩いてください。
make
ubuntu@st2-pub-1b-1a ~/st2-docker-gkz (tutorial-install-pack) $ make --version
GNU Make 4.1
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
docker
ubuntu@st2-pub-1a ~/st2-docker-gkz (tutorial-install-pack) $ docker --version
Docker version 19.03.5, build 633a0ea838
docker-compose
ubuntu@st2-pub-1a ~/st2-docker-gkz (tutorial-install-pack) $ docker-compose --version
docker-compose version 1.24.1, build 4667896b
リポジトリをクローンした方は./sh/install.sh
を実行すれば、同スクリプトがインストールされていないことを確認してから、インストールコマンドが実行されます。
ubuntu@st2-pub-1a ~/st2-docker-gkz (tutorial-install-pack) $ source sh/install.sh
いよいよ、stackstormのDockerコンテナを立ち上げるのですが、st2-dockerではstackstormのユーザー名やパスワードなどセキュアな情報は/conf/*.envから読み込んでいます。
そのため、make envを実行して/conf/*.envを作りましょう。
こちらのユーザー名とパスワードはstackstormのwebポータル(https://${HOST_IP})にログインする際に使います。
ログインするとこのようにGUIからでも登録されたpackなどが確認できます。
ubuntu@st2-pub-1a ~/st2-docker-gkz (tutorial-install-pack) $ make env
bin/write-env.sh conf
おまたせしました!
それでは、docker-compose upでstackstormコンテナを立ち上げましょう。
ubuntu@st2-pub-1a ~/st2-docker-gkz (tutorial-install-pack) $ docker-compose -f docker-compose-dev.yml up -d --build
5. Dockerコンテナ側で準備すること
コンテナ側で行うことは、必要なpackなどをインストールためにst2-docker/opt/reload.sh
を実行するだけです。
#!/bin/bash
# login
st2 login $ST2_USER -p $ST2_PASSWORD
# publish ST2_API_KEY
export ST2_API_KEY=$(st2 apikey create -k -m '{"used_by": "my integration"}')
# install packs, clone my repo
FILES=/st2-docker/opt/reload.d/*
for f in $FILES;
do
echo "Execute $f"
bash "$f" -H
done
# change owner, mode of mydemo_pack
chown -R root:st2packs /opt/stackstorm/packs/mydemo_pack/ \
&& chmod -R +x /opt/stackstorm/packs/mydemo_pack/
# create, and reload my specified actions one by one
# if you don't need to, just run the following commnad
st2ctl reload --register-all
#actions_dir="/opt/stackstorm/packs/mydemo_pack/actions" \
#&& files=$(ls $actions_dir | grep -E "*.yaml")
#for f in $files;
#do
# st2 action create /opt/stackstorm/packs/mydemo_pack/actions/$f
#done
#
#pack_name="mydemo_pack" \
#&& st2 run packs.setup_virtualenv packs=$pack_name
# run actions
st2 run ansible.playbook \
inventory_file=/opt/stackstorm/packs/ansible/inventory/hosts \
playbook=/opt/stackstorm/packs/ansible/playbook/ping.yaml
st2 run slack.post_message \
message="Hello World! $HOSTNAME by $SLACKBOT_NAME"
#st2 run mydemo_pack.poll-repo
#st2 run mydemo_pack.my-first-wf爆速
ubuntu@st2-pub-1a ~/st2-docker-gkz (tutorial-install-pack) $ docker-compose exec \
> stackstorm bash
root@$HOSTNAME:/# . st2-docker/opt/reload.sh
st2-docker/opt/reload.shでは同シェルスクリプトと同じパスにあるreload.dディレクトリ内にあるシェルスクリプトをひとつずつ実行
しています。
ご自身で追加したいpackや変更したい内容があればreload.dディレクトリ内にシェルスクリプトを追加するか、既存のシェルスクリプトを修正すればOKです。
root@$HOSTNAME:/# tree /st2-docker/opt/
/st2-docker/opt/
├── reload.d
│ ├── add-ansible-pack.sh # ansible packを追加
│ ├── add-slack-pack.sh # slack packを追加
│ ├── clone_repo.sh # stackstormで管理する対象アプリのリポジトリがなければクローン
| # アプリ(flask/nginx)コンテナを立ち上げる
│ └── create-pack-mydemo.sh # mydemo packを追加
├── reload.sh # reload.d内にあるシェルスクリプトの実行ファイル
└── requirements.txt.dev
1 directory, 6 files
ansible,slack, mydemo packの3つのpackが入っているか確認しましょう。
root@$HOSTNAME:/# st2 pack list | grep -E "ansible|slack|mydemo_pack"
| ansible | ansible | ansible | 0.5.9 | StackStorm, Inc. |
| mydemo_pack | mydemo_pack | st2 mydemo pack | 0.0.1 | Gakuji Tamaki |
| slack | slack | Slack Chat | 0.12.8 | StackStorm, Inc. |
root@db8b2e092ffd:/#
用意したslackのチャンネルをみてみると、Botがコンテナの$HOSTNAMEを投稿していることが確認できます。
やっと下準備が終わりました。
Stackstormはユーザーがカスタマイズできるがゆえに、下ごしらえが大変です。
なので、今回僕が用意したリポジトリのように、Dockerfileや環境変数、シェルスクリプトなどを使って少しでもインフラ構成のコード化を推し進めることが、Stackstormの運用が多少なりともラクになるのではないかと考えます。
(うれしいことにStackstormのミートアップが近々行われるということなので、そこでみなさんの運用術をお聞きして、また記事に起こせれば!)
ドンピシャでst2のミートアップがきた。 https://t.co/PTeevL0IjH
— gkz (@gkzvoice) December 16, 2019
6. Actionを使ってディストリビューションを確かめる
ここからActionやWorkflowを使っていくので、まずどんなものがあるか確認しましょう。
st2 action list -p=$PACK
と叩いてみてください。
root@$HOSTNAME:/# st2 action list -p=mydemo_pack
+-------------------------------------+-------------+-------------------------------------+
| ref | pack | description |
+-------------------------------------+-------------+-------------------------------------+
| mydemo_pack.get_distro | mydemo_pack | get distro #6. |
| mydemo_pack.git_status | mydemo_pack | git status |
| mydemo_pack.git_status_python | mydemo_pack | git status with python |
| mydemo_pack.my-first-wf | mydemo_pack | return code depends on the result |
| mydemo_pack.orquesta-ping-with- | mydemo_pack | A workflow demonstrating with |
| items | | items. |
| mydemo_pack.playbook-demo | mydemo_pack | Playbook Demo |
| mydemo_pack.poll-repo | mydemo_pack | poll repo |
| mydemo_pack.poll-repo-python | mydemo_pack | poll repo with python |
| mydemo_pack.rebuild_app | mydemo_pack | Rebuild App Container |
+-------------------------------------+-------------+-------------------------------------+
root@$HOSTNAME:/#
続いて引数(parameters)として何を渡せばよいか確認するために、st2 action get $PACK.$ACTION
と叩いて、parametersの横に書かれたnameやdefault、descriptionを参照します。
(結論をいうと、centosやubuntuなどディストリビューションをdistro_name=centosとして渡してほしいです。)
root@$HOSTNAME:/# st2 action get mydemo_pack.get_distro
+---------------+-------------------------------+
| Property | Value |
+---------------+-------------------------------+
| id | 5df796581b25dd0132571c0f |
| uid | action:mydemo_pack:get_distro |
| ref | mydemo_pack.get_distro |
| pack | mydemo_pack |
| name | get_distro |
| description | get distro |
| enabled | True |
| entry_point | scripts/get_distro.sh |
| runner_type | local-shell-script |
| parameters | { |
| | "distro_name": { |
| | "position": 0, |
| | "required": true, |
| | "type": "string" |
| | "default": "centos" |
| | } |
| | } |
| metadata_file | actions/get_distro.yaml |
| notify | |
| output_schema | |
| tags | |
+---------------+-------------------------------+
root@$HOSTNAME:/#
それではActionを実行してみましょう。
root@$HOSTNAME:/# st2 run mydemo_pack.get_distro distro_name=centos
.
id: 5df797271b25dd0132571c22
status: failed
parameters:
distro_name: centos
result:
failed: true
return_code: 1
stderr: ''
stdout: ''
succeeded: false
root@$HOSTNAME:/#
succeededがfalse、あるいはfailedがtrueであればそのActionは失敗したことになります。
続いてdistro_nameにubuntu
を渡して再度実行してみましょう。
root@$HOSTNAME:/# st2 run mydemo_pack.get_distro distro_name=ubuntu
.
id: 5df797141b25dd0132571c1f
status: succeeded
parameters:
distro_name: ubuntu
result:
failed: false
return_code: 0
stderr: ''
stdout: ''
succeeded: true
root@$HOSTNAME:/#
今度は上手く行きました。
このようにActionの実行コマンドは st2 run $PACK.$ACTION
となっています。
Actionの結果を確認する場合のコマンドはst2 execution get $ID
です。
$IDは、Actionごとにユニークに割り当てられており、IDが分からない場合は、st2 execution list
で確認できます。
root@$HOSTNAME:/# st2 execution list
+--------------------------+------------+--------------+-------------------------+-----------------+---------------+
| id | action.ref | context.user | status | start_timestamp | end_timestamp |
+--------------------------+------------+--------------+-------------------------+-----------------+---------------+
| 5df84aa3b530ad0122f3ac93 | packs.setu | st2admin | succeeded (9s elapsed) | Tue, 17 Dec | Tue, 17 Dec |
| | p_virtuale | | | 2019 03:25:23 | 2019 03:25:32 |
| | nv | | | UTC | UTC |
| 5df84b0cb530ad0122f3ac97 | packs.inst | st2admin | succeeded (47s elapsed) | Tue, 17 Dec | Tue, 17 Dec |
| | all | | | 2019 03:27:08 | 2019 03:27:55 |
| | | | | UTC | UTC |
| 5df84b3fb530ad0122f3aca3 | packs.inst | st2admin | succeeded (24s elapsed) | Tue, 17 Dec | Tue, 17 Dec |
| | all | | | 2019 03:27:59 | 2019 03:28:23 |
| | | | | UTC | UTC |
| 5df84b5cb530ad0122f3ad3b | packs.inst | st2admin | succeeded (17s elapsed) | Tue, 17 Dec | Tue, 17 Dec |
| | all | | | 2019 03:28:28 | 2019 03:28:45 |
| | | | | UTC | UTC |
| 5df84b7eb530ad0122f3ad48 | ansible.pl | st2admin | succeeded (20s elapsed) | Tue, 17 Dec | Tue, 17 Dec |
| | aybook | | | 2019 03:29:02 | 2019 03:29:22 |
| | | | | UTC | UTC |
| 5df84b95b530ad0122f3ad4b | slack.post | st2admin | succeeded (1s elapsed) | Tue, 17 Dec | Tue, 17 Dec |
| | _message | | | 2019 03:29:25 | 2019 03:29:26 |
| | | | | UTC | UTC |
| 5df84d05b530ad0122f3ad4e | mydemo_pac | st2admin | failed (0s elapsed) | Tue, 17 Dec | Tue, 17 Dec |
| | k.get_dist | | | 2019 03:35:33 | 2019 03:35:33 |
| | ro | | | UTC | UTC |
| 5df84d10b530ad0122f3ad51 | mydemo_pac | st2admin | succeeded (0s elapsed) | Tue, 17 Dec | Tue, 17 Dec |
| | k.get_dist | | | 2019 03:35:44 | 2019 03:35:44 |
| | ro | | | UTC | UTC |
+--------------------------+------------+--------------+-------------------------+-----------------+---------------+
root@$HOSTNAME:/# st2 execution get 5df84d05b530ad0122f3ad4e
id: 5df84d05b530ad0122f3ad4e
status: failed (0s elapsed)
parameters:
distro_name: centos
result:
failed: true
return_code: 1
stderr: ''
stdout: ''
succeeded: false
root@$HOSTNAME:/# st2 execution get 5df84d10b530ad0122f3ad51
id: 5df84d10b530ad0122f3ad51
status: succeeded (0s elapsed)
parameters:
distro_name: ubuntu
result:
failed: false
return_code: 0
stderr: ''
stdout: ''
succeeded: true
root@$HOSTNAME:/#
このように都度実行結果を確認しながらActionを実行してもよいのですが、Stackstormでは複数のActionを出力結果や引数に応じて柔軟に繋げることができるWorkflowという機能も提供されているので、Workflowを使ってみましょう。
7. ActionとWorkflowを使ってディストリビューションを確かめてslackに通知する
workflowで行っていることをフロー図に起こしました。
出所:近日参加予定のLT資料より。(完成次第、リンクを貼ります。)
それでは、下記のとおりworkflowを実行してみましょう。
root@$HOSTNAME:/# st2 run mydemo_pack.my-first-wf
....
id: 5df8bec8b530ad0122f3ad54
action.ref: mydemo_pack.my-first-wf
parameters: None
status: succeeded
start_timestamp: Tue, 17 Dec 2019 11:40:56 UTC
end_timestamp: Tue, 17 Dec 2019 11:41:03 UTC
result:
output:
failed: false
+--------------------------+------------------------+----------+------------+-----------------+
| id | status | task | action | start_timestamp |
+--------------------------+------------------------+----------+------------+-----------------+
| 5df8bec8b530ad0035fd7575 | succeeded (1s elapsed) | init | core.noop | Tue, 17 Dec |
| | | | | 2019 11:40:56 |
| | | | | UTC |
| 5df8bec9b530ad0035fd7578 | failed (1s elapsed) | main | mydemo_pac | Tue, 17 Dec |
| | | | k.get_dist | 2019 11:40:57 |
| | | | ro | UTC |
| 5df8becbb530ad0035fd757b | succeeded (0s elapsed) | main | mydemo_pac | Tue, 17 Dec |
| | | | k.get_dist | 2019 11:40:59 |
| | | | ro | UTC |
| 5df8beccb530ad0035fd757e | succeeded (0s elapsed) | post_msg | slack.post | Tue, 17 Dec |
| | | | _message | 2019 11:41:00 |
| | | | | UTC |
| 5df8becdb530ad0035fd7581 | succeeded (1s elapsed) | last | core.noop | Tue, 17 Dec |
| | | | | 2019 11:41:01 |
| | | | | UTC |
+--------------------------+------------------------+----------+------------+-----------------+
root@$HOSTNAME:/#
Actionとworkflowに関する解説は次回に譲りますが、ポイントはfailedというフラグを用意している点です。
workflowはひとつでもActionがfailedとなったとき、workflow(Actio全体)の結果としてもfailedとなってしまいます。
workflowのなかでActionがfailedのルートに入った場合の切り戻しのActionが成功した場合のworkflowの結果はfailedではなく、succeededとしたいですよね。
そこでworkflowの成否を判定するためのフラグを用意しました。
version: 1.0
description: return code depends on the result
input:
- distro_name
- timeout
output:
- failed: <% ctx().failed %>
tasks:
init: # failedフラグを初期化(False)とするだけのAction
action: core.noop
next:
- publish:
- failed: False
do: main
main: # ディストリビューションを確認する本workflowメインのAction
action: mydemo_pack.get_distro
input:
distro_name: <% ctx().distro_name %>
timeout: <% ctx().timeout %>
next:
- when: <% succeeded() %>
do: post_msg
publish:
- failed: False
- msg: "result: <% result() %>"
# Actionはfailed、かつフラグのfaildはFalse(not True)、かつ引数のdistro_nameは'centos'であるとき
- when: <% failed() and not ctx().failed and (ctx().distro_name = 'centos') %>
do: main # distro_nameは'ubuntu' failedはTrueとしてmainを再実行
publish:
- distro_name: "ubuntu"
- failed: True
- when: <% failed() and ctx().failed %>
do: post_msg
publish:
- msg: "result: <% result() %>"
post_msg:
action: slack.post_message
input:
message: <% ctx().msg %>
next:
- do: last
# failedフラグがTrueである場合、orqeustaが用意する必ず結果がfailedになるfailというActionを実行し、
# workflowの結果もfailedとする
last:
action: core.noop
next:
- when: <% ctx().failed %>
do: fail
AnsibleのPackを使うこともできます。
root@$HOSTNAME: # st2 run mydemo_pack.playbook-demo
............
id: 5df8cabfb530ad0122f3ad5a
action.ref: mydemo_pack.playbook-demo
parameters: None
status: succeeded
start_timestamp: Tue, 17 Dec 2019 12:31:59 UTC
end_timestamp: Tue, 17 Dec 2019 12:32:22 UTC
result:
output:
msg:
exit_code: 0
result: true
stderr: 'st2.actions.python.PostMessageAction: INFO Message successfully posted
'
stdout: ''
+--------------------------+-------------------------+----------+------------+-----------------+
| id | status | task | action | start_timestamp |
+--------------------------+-------------------------+----------+------------+-----------------+
| 5df8cac0b530ad0035fd758b | succeeded (21s elapsed) | playbook | ansible.pl | Tue, 17 Dec |
| | | | aybook | 2019 12:32:00 |
| | | | | UTC |
| 5df8cad5b530ad0035fd758e | succeeded (0s elapsed) | echo | core.local | Tue, 17 Dec |
| | | | | 2019 12:32:21 |
| | | | | UTC |
| 5df8cad5b530ad0035fd7591 | succeeded (1s elapsed) | last | slack.post | Tue, 17 Dec |
| | | | _message | 2019 12:32:21 |
| | | | | UTC |
+--------------------------+-------------------------+----------+------------+-----------------+
root@$HOSTNAME: #
stackstormのActionから、Juniper社のネットワークスイッチのQFXに対してこのようなshow versionを流すこともAnsible packを使えば可能です。
jcluser@Template-vQFX-Light> show version | no-more
fpc0:
--------------------------------------------------------------------------
Hostname: Template-vQFX-Light
Model: vqfx-10000
Junos: 15.1X53-D63.9
JUNOS Base OS boot [15.1X53-D63.9]
JUNOS Base OS Software Suite [15.1X53-D63.9]
JUNOS Online Documentation [15.1X53-D63.9]
JUNOS Crypto Software Suite [15.1X53-D63.9]
JUNOS Packet Forwarding Engine Support (qfx-10-f) [15.1X53-D63.9]
JUNOS Kernel Software Suite [15.1X53-D63.9]
JUNOS Web Management [15.1X53-D63.9]
JUNOS Enterprise Software Suite [15.1X53-D63.9]
JUNOS SDN Software Suite [15.1X53-D63.9]
JUNOS Routing Software Suite [15.1X53-D63.9]
JUNOS py-base-i386 [15.1X53-D63.9]
{master:0}
jcluser@Template-vQFX-Light>
Ansible Packのplaybook Actionの引数はinventory_fileとplaybookです。
root@$HOSTNAME: # st2 run ansible.playbook \
inventory_file=/opt/stackstorm/packs/ansible/inventory/hosts \
playbook=/opt/stackstorm/packs/ansible/playbook/gather_facts_junos.yaml
....
id: 5df8d56eb530ad0122f3ad6f
status: succeeded
parameters:
cwd: /opt/stackstorm/packs/ansible
inventory_file: /opt/stackstorm/packs/ansible/inventory/hosts
playbook: /opt/stackstorm/packs/ansible/playbook/gather_facts_junos.yaml
result:
failed: false
return_code: 0
stderr: "/opt/stackstorm/virtualenvs/ansible/lib/python2.7/site-packages/cryptography/hazmat/primitives/constant_time.py:26: CryptographyDeprecationWarning: Support for your Python version is deprecated. The next version of cryptography will remove support. Please upgrade to a release (2.7.7+) that supports hmac.compare_digest as soon as possible.
utils.PersistentlyDeprecated2018,
[WARNING]: arguments wait_for, match, rpcs are not supported when using
transport=cli"
stdout: "
PLAY [junos] *******************************************************************
TASK [show version] ************************************************************
ok: [66.129.235.3]
PLAY RECAP *********************************************************************
66.129.235.3 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
"
succeeded: true
root@HOSTNAME: #
8. ファイルの編集方法やトラブルシュートと次回予告
ActionやWorkflowのメタファイルやWorkflowを編集
したら、st2 runで実行する前にst2ctl reload
でyamlファイルの編集をStackstormに認識させください。
Actionの実行スクリプト
(mydemo_pack/actions/scripts/*のスクリプト)の編集についてはst2ctl reload
する必要はないです。
root@HOSTNAME: # st2ctl reload --register-all
もし、うまくパラメータが認識されないといったことがありましたら、yamlのインデントを下記のツールなどを使って調べてみてください。
あるいは/var/log/st2/st2api.log
を追ったり、st2ctl status
でst2関連のステータスを確認することもありです。
root@HOSTNAME:/# tail -f /var/log/st2/st2api.log
2019-12-17 13:55:34,158 140522372926512 INFO logging [-] ca8bb925-9695-46f1-8031-6698aad411d9 - GET /v1/executions/5df8de45b530ad0122f3ad7e with query={} (remote_addr='127.0.0.1',method='GET',request_id='ca8bb925-9695-46f1-8031-6698aad411d9',query={},path='/v1/executions/5df8de45b530ad0122f3ad7e')
root@HOSTNAME:/# st2ctl status
##### st2 components status #####
st2actionrunner PID: 140
st2actionrunner PID: 178
st2api PID: 61
st2api PID: 282
st2stream PID: 64
st2stream PID: 287
st2auth PID: 49
st2auth PID: 314
st2garbagecollector PID: 47
st2notifier PID: 54
st2resultstracker PID: 51
st2rulesengine PID: 59
st2sensorcontainer PID: 46
st2chatops is not running.
st2timersengine PID: 63
st2workflowengine PID: 55
st2scheduler PID: 57
mistral-server PID: 491
mistral.api PID: 486
mistral.api PID: 523
mistral.api PID: 524
root@HOSTNAME:/#
それでもダメでしたら、st2ctl restart
を実行してください。Stackstorm関連の複数プロセスを再起動するか、Dockerコンテナ自体をビルドし直しましょう。
環境構築の手順をコード化しているので、ラクチンです。
root@HOSTNAME: # st2ctl restart
ホスト側で更新したファイルをコンテナに反映させるにはコンテナを削除してから改めてdocker-compose upする必要があるのですが、
面倒くさいのでシェルスクリプトを書きました。
-bをつけるとコンテナを削除した後、立ち上げ、-nをつけるとコンテナを削除するだけというものです。
ubuntu@st2-pub-1a ~/st2-docker-gkz (tutorial-install-pack) $ bash sh/setup.sh -b
(略)
Successfully built 373fcf9dbfcd
Successfully tagged stackstorm/stackstorm:3.1
Creating st2-docker-gkz_rabbitmq_1 ... done
Creating st2-docker-gkz_postgres_1 ... done
Creating st2-docker-gkz_redis_1 ... done
Creating st2-docker-gkz_mongo_1 ... done
Creating st2-docker-gkz_stackstorm_1 ... done
ubuntu@st2-pub-1a ~/st2-docker-gkz (tutorial-install-pack) $ docker-compose exec stackstorm bash
root@HOSTNAME:/#
getopsを使ったのは個人的に書いてみたかったからというだけです笑。
#!/bin/bash
function help {
cat <<- EOF
overview:wheter run "docker-compose up -d --build", or not
usage:bash sh/setup.sh [-h|-b|-n|
option:
-h this message
-b ->> run "docker-compose up -d --build", after removing all contrainers
-n ->> run "nothing" after removing them
EOF
exit 1
}
while getopts ":bn" OPT;
do
case ${OPT} in
b)
BUILD_FLAG=1;
;;
n)
BUILD_FLAG=0;
;;
\?)
help
;;
esac
done
shift $((OPTIND - 1))
IDS=$(docker container ls -aq)
for i in $IDS
do
echo "$i"
docker container stop $i && docker container rm $i
done
#IMAGES=$(docker images -aq)
#for i in $IMAGES
#do
# echo "$i"
# docker image rmi "$i"
#done
docker container prune --force
docker image prune --force
docker volume prune --force
docker-compose down -v
if [ "$BUILD_FLAG" -eq 1 ]; then
echo 'Run "docker-compose up -d --build"'
docker-compose -f docker-compose-dev.yml up -d --build
elif [ "$BUILD_FLAG" -eq 0 ]; then
echo 'Not Run "docker-compose up -d --build"'
else
echo "option is unexpected."
help
fi
本当はここからActionの具体的な編集方法やワークフローの定義のやりかたに関するサンプルコードを載せたかったのですが、
力尽きたので次回に譲ります、、。
Stackstormの魅力、ちょっとworkflow書いてみようかなと思っていただけたらうれしいです。
第二部できました!!
Dockerで始めるStackstorm再入門2/3(条件分岐させるWorkflowと定期実行させるRuleの書き方)
参考
-
[Ubuntu Linux を実行しているプライベート Amazon EC2 インスタンスに静的ホスト名を割り当てる]
(https://aws.amazon.com/jp/premiumsupport/knowledge-center/linux-static-hostname) -
[シェルスクリプトのreturn - 考える人、コードを書く人]
(https://bokko.hatenablog.com/entry/20090223/1235400626) -
orqeustaのサンプルコード
-
[github.com/StackStorm/st2/blob/master/contrib/examples/actions/workflows/orquesta-streaming-demo.yaml]
(https://github.com/StackStorm/st2/blob/master/contrib/examples/actions/workflows/orquesta-streaming-demo.yaml)
-
-
Ansible pack
-
Slack pack
-
本記事で扱ったStackstormのサンプルコード
-
Stackstormの管理対象のアプリコンテナ
-
ActionとWorkflowのサンプルコード