SlackからAnsibleを実行させる

# ことの始まり
例えばAnsibleを実行して、Callbackプラグインなどでslackに通知を送っていたとします。
「**あぁー、このエラー再実行させたらすぐ通りそうだなぁ・・**」とか
「**slackからAnsible実行出来ないかなぁ・・**」とか
思う人もいると思います。

というわけで、今回はSlackからAnsibleを実行させちゃいましょう！

# 環境
環境：**Centos7**
**Ansible** がインストールされていることが前提(インストール方法は今回は割愛)

# Hubotのインストール
Hubotは、Github社が開発した、オープンソースのボットフレームワークです。
Slackと連携させる事でボットとして働いてくれます。

## Slack側の設定
先ずはSlackから **Hubot** をインストールしていきます。

Slackサイドは、やり方はとても簡単です。
① 「**App**」をクリックします。
![screen_000.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386905/21ee8ba7-de51-4f90-c4c9-a7ea357f13b3.jpeg)

② 「**hubot**」と検索します。
すると下に**Hubot**と表示されるので、「**インストール**」をクリックします。
![screen_001.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386905/03c2d8d5-ccc9-7170-0341-55d5789f124a.jpeg)

③ **Hubot**の詳細画面が表示されるので、「**インストール**」をクリックします。
![screen_002.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386905/12b62b43-89ad-dc27-3a16-f3bc613ff012.jpeg)

④適当に名前を入力して、「**Hubotインテグレーションの追加**」をクリックします。
![screen_003.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386905/07f8e0d6-4400-0437-b8c8-8a16b54f30ca.jpeg)

⑤ APIトークンが出てきます。後で使うので、メモ帳などに控えておいてください。
![screen_004.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386905/07c295bc-3bc0-3221-3053-8bff833a569b.jpeg)

ここまで来ると、Slackに作成したボットが追加されていると思います。
後は、使いたいチャンネルにボットを招待します。

⑥ チャンネルを開き、「**アプリを追加する**」をクリックします。
![screen_086.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386905/bd63c32f-658a-2dd7-25ea-8d35846b7846.jpeg)

⑦ 作成したボットが出てくると思うので、「**追加**」をクリックします。
![screen_087.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386905/a9a54378-62ed-c883-1d98-5dcf0eaccffd.jpeg)

Slackサイドは以上です。

## Ansibleサーバー側の設定
次に、実際にAnsibleを実行するサーバー側の設定をしていきます。

① epelリポジトリを追加します。既にしている場合は、飛ばしてＯＫです。

```bash:
$ sudo yum -y install epel-release
$ sudo rpm -ivh http://ftp.riken.jp/Linux/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
```

② redisとnpmのインストールを行います。

```bash:
$ sudo yum install npm redis
```

③ redisを起動させます。(再起動しても設定が残るようにしておきます。)

```bash:
$ sudo systemctl start redis
$ sudo systemctl enable redis
```

④ **Hubot** の前提条件として、必要なnpmモジュールをインストールしていきます。

```bash:
$ sudo npm install -g coffee-script hubot
$ sudo npm install -g yo generator-hubot
$ sudo npm install hubot-slack -save
```

⑤ 適当な場所に **Hubot** の作業ディレクトリを作ります。

```bash:
$ mkdir mybot
$ cd mybot
```

⑥ 「**よぉ、Hubot**」と呼んであげます。~~（ふざけてないです。マジです。）~~

```bash:
$ yo hubot
```

⑦ 色々と質問が出てくるので、最初に「**Yes**」と入力し、ボット名などを入力していきます。

```
? ==========================================================================
We're constantly looking for ways to make yo better!
May we anonymously report usage statistics to improve the tool over time?
More info: https://github.com/yeoman/insight & http://yeoman.io
========================================================================== Yes
                     _____________________________
                    /                             \
   //\              |      Extracting input for    |
  ////\    _____    |   self-replication process   |
 //////\  /_____\   \                             /
 ======= |[^_/\_]|   /----------------------------
  |   | _|___@@__|__
  +===+/  ///     \_\
   | |_\ /// HUBOT/\\
   |___/\//      /  \\
         \      /   +---+
          \____/    |   |
           | //|    +===+
            \//      |xx|

? Owner Hayashi　←自分の名前
? Bot name Ansible　←botの名前
? Description A simple helpful robot for your Company　←飛ばしてもいいです
? Bot adapter slack　←今回はslackって入力します
```

インストールが完了すると以下のようにファイルが作成されます。

```bash
   create bin/hubot
   create bin/hubot.cmd
   create Procfile
   create README.md
   create external-scripts.json
   create hubot-scripts.json
   create .gitignore
   create package.json
   create scripts/example.coffee
   create .editorconfig
                     _____________________________
 _____              /                             \
 \    \             |   Self-replication process   |
 |    |    _____    |          complete...         |
 |__\\|   /_____\   \     Good luck with that.    /
   |//+  |[^_/\_]|   /----------------------------
  |   | _|___@@__|__
  +===+/  ///     \_\
   | |_\ /// HUBOT/\\
   |___/\//      /  \\
         \      /   +---+
          \____/    |   |
           | //|    +===+
            \//      |xx|
```

デフォルト設定だと、ターミナルを終了させると **Hubot** も一緒に終了してしまうので、 **forever** でデーモン化させます。
⑧ **forever** をインストールします。

```bash:
$ sudo npm install -g forever
```

⑨ `$ vi bin/hubot`で編集を行い、 **Hubot** を **forever** のプロセスとして実行させるようにします。
Slack側の設定で控えたAPIトークンは、ここに記載します。

```vim:bin/hubot
#!/bin/sh

set -e

npm install
export PATH="node_modules/.bin:node_modules/hubot/node_modules/.bin:$PATH"
export HUBOT_SLACK_TOKEN="ここに先ほど控えたAPIトークンを入力します"

forever start -c coffee node_modules/.bin/hubot --adapter slack
```

⑩ scriptsディレクトリに **CoffeeScript** を作成します。(今回は、ansible.coffeeとしています。)

下記のサンプルは、slackで
・「version」と入力すると、Ansibleのバージョンが返ってくる。
・「ansible {インベントリファイル} {実行するplaybook}」と入力すると、指定したplaybookを実行する。
例です。

```coffee-script:scripts/ansible.coffee
module.exports = (robot) ->
  robot.respond /version/i, (msg) ->
    @exec = require('child_process').exec
    command = "ansible --version"
    @exec command, (error, stdout, stderr) ->
      resp = "```"
      resp += error if error?
      resp += stdout if stdout?
      resp += stderr if stderr?
      resp += "```"
      msg.send "#{resp}"

  robot.respond /ansible (.*) (.*)/i, (msg) ->
    @exec = require('child_process').exec
    command = "ansible-playbook -i #{msg.match[1]} #{msg.match[2]}"
    msg.send "Ansible実行中"
    @exec command, (error, stdout, stderr) ->
      resp = "```"
      resp += error if error?
      resp += stdout if stdout?
      resp += stderr if stderr?
      resp += "```"
      msg.send "#{resp}"
      msg.send "結果にコミットしました"
```

少し解説すると、
`robot.respond /{この部分}/i, (msg) ->`を変更してあげると、Slackでその文字を入力した時にボットが反応します。
ただし、チャンネルでボットを使う場合は、`robot.respond`の場合は、ボットに対して@(メンション)が必要です。(付けたくない場合は、`robot.hear`を使います。)
`@exec command, (error, stdout, stderr) ->`でコマンドを実行させ、`msg.send`でボットから任意のメッセージをSlackに送ることが出来ます。

# Hubotの実行
`bin/hubot` で **Hubot** を実行します。

```bash:
$ bin/hubot
warn:    --minUptime not set. Defaulting to: 1000ms
warn:    --spinSleepTime not set. Your script will exit if it does not stay up for at least 1000ms
info:    Forever processing file: node_modules/.bin/hubot
```

`forever list`を実行すると、現在実行しているプロセスが表示されます。

```bash:
$ forever list
info:    Forever processes running
data:        uid  command script                                  forever pid  id logfile                         uptime
data:    [0] _5QN coffee  node_modules/.bin/hubot --adapter slack 1590    1596    /home/ansible/.forever/_5QN.log 26:19:11:30.614000000059605
```

`Hubot`を停止させたい場合は、`forever stop {script}`で停止させることが出来ます。

```bash:
$ forever stop node_modules/.bin/hubot
info:    Forever stopped process:
    uid  command script                                  forever pid  id logfile                         uptime
[0] _5QN coffee  node_modules/.bin/hubot --adapter slack 1590    1596    /home/ansible/.forever/_5QN.log 26:19:13:45.36500000022352
```

# AnsibleをSlackから実行
**Ansible** を **Slack** から実行させてみます。

## バージョンの表示
先ずは、Ansibleのバージョンを表示させてみます。
ボットにメンションを付けて、`version`と入力します。
![screen_088.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386905/630de6d3-96b1-a512-54b8-0f1f229c20ca.jpeg)

ボットがバージョンを返してくれていますね！！

## Playbookの実行
では、Playbookを実行させてみます。
ボットにメンションを付けて、`ansible {インベントリファイル} {実行するplaybook}`を入力します。
![screen_089.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386905/114b289c-31ea-ac86-81c7-329b6117f94c.jpeg)

結果にコミットしてくれましたね！！
これで、いつでもSlackからAnsibleが実行出来そうです。

# 参考になったありがたい記事のご紹介
[centos7-にhubotをインストールした時のメモ-foreverで自動起動](https://dq310.com/nm/centos7-にhubotをインストールした時のメモ-foreverで自動起動/)
[CentOS に Node.js をインストールして forever でデーモン化](https://kshigeru.blogspot.com/2011/10/nodejs-forever.html)
[HUBOTの構築（CentOS7）](https://qiita.com/silverskyvicto/items/afdd8158dd6961f414dd)