オンプレミスでChatOps！ Mattermost と Gitlab と Jenkins を 連携する

# ChatOps run on on-premises.
## 0.　はじめに
SlackのCloneプロジェクトと言われている Mattermost を使って
オンプレミス環境でChatOps的なことをやってみました。
今回Hubotなどを間に入れずにMattermost,Gitlab,Jenkinsのみで構成しています。

なお、十分な検証が行えているわけではありませんので検証環境等でのデモ、素振り用などに限定してお使いください。

また、Gitlab及びMattermost、Jenkinsはすでにインストールされている前提です。
時間に余裕があるときに、環境構築部分については別記事として掲載しようと思います。

---
2016/9/26追記：以下に環境構築の記事を掲載しました。
http://qiita.com/tbuchi888/items/66763a9af2e15fa74a3c
また、Jenkins2については以下も参照して頂ければと思います。
http://qiita.com/tbuchi888/items/3c65cb4757225b09f08f

---

## 1.　連携概要
以下のようなイメージで　Mattermost と Gitlab と Jenkins を 連携させます。
<img width="860" alt="chatops_main01.png" src="https://qiita-image-store.s3.amazonaws.com/0/117986/d20f75c4-4a3d-b595-ebfd-53c772bbd6e3.png">

1.　デベロッパーがGitabへ`git push`をするとMattermostの対象チャンネル（以降Chat）にGitLabからpushの情報が通知がされます。
　　-　GitlabのSlackサービス　と　MattermostのIncoming　Webhookで連携
2.　オペレータがChatでgit pushの内容をchatのlinkから確認して問題なければ、"Build!!"（任意の予め登録した文字列）と入力することでJenkinsへビルドの指示を出します。
　　-　MattermostのOutGoing Webhook と Jenkinsの Build Triggersで連携
3.　JenkinsがGitlabから対象のソースコードを取得してビルドを開始します。
　　-　JenkinsのSouce Code Mangement（gitlab-plugin）で連携
4.　Jenkinsがビルド結果をChatに通知します。
　　-　JenkinsのPost-build ActionsとMattermostのIncoming Webhookで連携
5.　オペレータがChatで結果を確認します。

以下はChat部分を拡大したもの
<img width="361" alt="chat 2016-09-01 10.58.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/117986/e596e705-099a-f450-91e8-7bac2ec034e5.png">

## 2. 使いどころ
今回試したのは、シンプルにJenkinsのビルドを行うまでですが、
アプリケーションのデプロイだけではなく、他ツール（Digdag,[terraform](http://qiita.com/tbuchi888/items/ce904bc9f4c2f7e5de09),Vagrant（vsphere-plugin）やAnsible,Serverspecなどなど）をJenkinsより実行する部分もシェル等でコード化し連携することで、`git　push`と、Chatからの指示のみで例えばテスト済みのWebサーバをまるっと自動でスクラップアンドビルドするなど、オンプレミスでも面白いことができると思います。

## 3. 環境
VirtualBox on OSX YosemiteのVMとしてGitlab/MattermostサーバとJekinsサーバの2台構成で検証しました。
なお、両サーバで名前解決可能なように`Jenkinssv`及び`mygitlabsv`のIPアドレスはホスト（OSX）のhostsファイルに記載しています。

|OS Ver.|OSS Ver.|memo|
|:-:|:-:|:-:|
|CentOS6.8|GitlabCE ver.8.11.2||
|-|Mattermost ver.3.30 |on GitlabCE|
|CentOS6.8|Jenkins ver.2.19||
|-|-|Gitlab Plagin ver.1.3.0|
|-|-|Mattermost Plugin ver.2.0.2|

## 4. 事前準備概要
1. Mattermost　で
    1. 今回用のチャンネルを作成します。
    2. Gitlab　及び　Jenkinsと連携するためにIncommin/Outgoing Webhookを設定します。
2. Gitlabで
    1. 今回用のプロジェクトを作成し
    2. サービス-Slack　で　MattermostのIncoming　Webhookを設定します。
3. Jenkins　で　
    1. プラグイン（gitlab及びmattermost）をインストールします。
    2. 今回用のプロジェクトを作成し
        3. Build TriggersでMattermostのOutGoing Webhookを設定します。
        4. Post-build ActionsでMattermostのIncoming Webhookを設定します。
        5. Souce Code Mangement（gitlab-plugin）でGitlabのリポジトリを設定します。
 
### 4.1 Mattermostの設定
<img width="270" alt="chatops_mattermost01.png" src="https://qiita-image-store.s3.amazonaws.com/0/117986/841b18ad-2c32-d3f4-ed21-e1e63c3c870e.png">
1. 今回用のチャンネルを作成します。（今回の例ではjenkinsという名前で作成）
2. Gitlab及びJenkinsと外部連携するためにIncommin/Outgoing Webhookを設定します。
3. 初期状態ではWebhookが利用できないのでSysytemコンソールからCustom Integrationsの設定を有効（true）にしてsaveしてから、画面左上メニューのSwitch to チーム名より、Sysytemコンソールを抜けます。なお、設定は必要に応じて変更してください。

<img width="245" alt="mattermost_syscon02016-09-01 11.38.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/117986/4ddca651-0106-ac8e-bcf4-6e951a5ec1e0.png"><img width="536" alt="mattemost_syscon1_2016-09-01 11.43.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/117986/57238606-4613-6025-be12-89287f4a2593.png">
4. IntegrationsメニューからWebhookを設定します。

<img width="212" alt="mattermost_menu_integrations_2016-09-01 11.49.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/117986/b8bff5e4-d0ab-9cd8-fa57-c07c1364ba1d.png">　<img width="498" alt="mattermost_int_02016-09-01 11.59.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/117986/70967120-6f7f-66c2-661d-88e54a920155.png">

5.　Gitlab 及び Jenkinsと連携するためにIncoming Webhookをそれぞれ設定します。またチャンネルは、さきほど作成したjenkinsを指定します。

以下Gitlab向け
<img width="494" alt="mattermost_Incoming 2016-09-01 15.24.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/117986/c7d41cbc-ea35-023c-4369-4bb2f503a335.png">

以下Jenkins向け
<img width="501" alt="mattermost_Incoming2016-09-01 15.23.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/117986/7f9bb897-d16d-3b71-35e7-8f51cf8ee2a0.png">

なお、設定内容（URL）はあとで利用するので控えておきます。
<img width="498" alt="Mattermos_Incoming_r2016-09-01 15.36.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/117986/36156dee-36be-e149-2a22-43987f3a75da.png">

6.　Jenkinsと連携するためにOutgoing Webhookを設定します。
チャンネルは、さきほど作成したjenkinsを指定します。
Triiger Words(One Per Line)にてBuildの指示を出す言葉（今回の例ではBuild!!）を設定します。
CallBack URLs(One Per Line)へJenkinsの対象プロジェクトを`JENKINSのURL/job/プロジェクト名/build?`という形で設定します。（今回の例では`http://myjenkinssv:8080/job/mattermost/build?`）

<img width="505" alt="mattermot_outgoing_0_2016-09-01 16.00.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/117986/64c25d00-ce0c-0427-a704-7ccf46605429.png">

なお、設定内容(token)はあとで利用するので控えておきます。
<img width="505" alt="mattermot_outgoing_1_2016-09-01 15.59.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/117986/0ea0d8e1-6f3b-33d2-da40-8aa0f9d67475.png">

### 4.2 Gitlabの設定
<img width="246" alt="chatops_gitlab01.png" src="https://qiita-image-store.s3.amazonaws.com/0/117986/a11d7219-5956-15be-73e3-91f3b340374d.png">

1. 今回用のプロジェクトを作成します。また後の動作確認のため、何かしらのコードを登録してコミットをしておいてください。
2. プロジェクトの設定-サービスよりSlack　を有効にして　MattermostのIncoming　WebhookのURL（４．１．５で作成したもの）を設定します。

<img width="433" alt="gitlabmenu2016-09-01 16.18.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/117986/d702aad3-09b8-9c9d-bed0-2072b25afd2e.png">

※以下は画面取りのタイミングの関係で既にSlackが有効なためアイコンがグリーンになっていますが、設定前はグレーとなります。

<img width="432" alt="gitlab_service2016-09-01 16.19.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/117986/43820da8-1126-d437-2443-acbdabd0d069.png">

ActiveにチェックをつけてSlackサービスを有効にします。
Webhookへ　MattermostのIncoming　WebhookのURL（４．１．５で作成したもの）を設定します。Usernameを設定します。（今回の例ではgitlab）
`Save Change`後に`Test　setting` ボタンよりテストのリクエスト送信が正常に終了すること及びChat側にテストのpush通知が送られることを確認します。
<img width="427" alt="gitlab_service_slack2016-09-01 16.19.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/117986/4ebc2332-d669-d1b5-a637-f1c5d81c999a.png">

### 4.3 Jenkinsの設定
<img width="340" alt="スクリーンショット 2016-09-01 18.11.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/117986/1cb05d9f-674f-9291-63e9-2df5d8483e9a.png">

1. 管理機能よりプラグイン（gitlab及びmattermost）をインストールします。
<img width="774" alt="2016-08-31 13.57.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/117986/d5adcf97-3efc-f7a6-0a37-4ba8b54c1ed1.png">
<img width="770" alt="2016-08-31 13.55.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/117986/f8e19728-f37a-aac5-e68d-3a36f7d4c91e.png">
2. 今回用のプロジェクトを作成します。
今回の例ではプロジェクト名はmattermostで設定
![2016-09-01 16.52.30.png](https://qiita-image-store.s3.amazonaws.com/0/117986/2565bb51-aa92-b774-6bda-d44cf8e5b0ef.png)

`Souce Code Mangement`タブでGitlabのリポジトリを設定します。

![2016-09-01 16.54.04.png](https://qiita-image-store.s3.amazonaws.com/0/117986/bea08987-3117-a4c5-f582-dbef67331713.png)

`Build Triggers`タブでMattermostのOutGoing Webhookのtoken（４．１．６で作成したもの）を設定します。
![スクリーンショット 2016-09-01 16.54.25.png](https://qiita-image-store.s3.amazonaws.com/0/117986/68e58561-a767-1d94-ad98-abc061eb110f.png)

`Post-build Actions`タブのMattermost NotificationsのAdvanced設定で
EndpointへMattermostでのIncoming WebhookのURL（４．１．５で作成したもの）を、Project Channelへjenkinsを設定します。

![スクリーンショット 2016-09-01 16.55.20.png](https://qiita-image-store.s3.amazonaws.com/0/117986/73ba3052-ab4a-0328-bd0f-19ed2c1618e3.png)

----
**なお、Gitlabの認証に失敗する場合は以下を実施します。**

#### Jenkins側　設定　　　
#####　Jenkinsアカウントの設定　bash有効化
rootアカウントかsudoでJenkinsサーバへCLIでログインし、`vi /etc/passwd`等でjenkins行の最後を`false`から`bash`に変えます。

変更前例
`jenkins:x:498:498:Jenkins Continuous Integration Server:/var/lib/jenkins:/bin/false`
変更後例
`jenkins:x:498:498:Jenkins Continuous Integration Server:/var/lib/jenkins:/bin/bash`

#####　Jenkinsアカウントの設定　SSH keyの作成
jenkinsアカウントでSSH keyを作成します。

```
#su jenkins
bash-4.1$ mkdir .ssh
bash-4.1$ chmod 700 .ssh/
bash-4.1$ cd .ssh/
bash-4.1$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/var/lib/jenkins/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /var/lib/jenkins/.ssh/id_rsa.
Your public key has been saved in /var/lib/jenkins/.ssh/id_rsa.pub.
The key fingerprint is:
～～～～～～～～～～～～～～～～
～～～～～～～～～～～～～～～～
bash-4.1$ cat id_rsa.pub
ssh-rsa 
～～～～～～～～～～～～～～～～ jenkins@JENKINS_SERVER
# この中身をgitlabのjenkinsユーザのsshkeyとして登録する
```

~/.ssh/configファイルを作成
これがないとSSHがパスワード認証となりPermission deniedエラーとなります。
また、userをgitアカウントとするところがポイントです。

```
bash-4.1$ vi ~/.ssh/config

＃　パーミッションの変更も忘れずにする
bash-4.1$ chmod 644 config
```

``` 
bash-4.1$ cat　~/.ssh/config
host GITLABSERVER
  HostName GITLABSERVER
  User git
  Port 22
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /var/lib/jenkins/.ssh/id_rsa
  IdentitiesOnly yes
  LogLevel FATAL
```

GUI画面からJenkinsの対象プロジェクトの`Souce Code Mangement`タブのCredentialsで以下を設定します。

-　スコープグローバル
-　ユーザー名 jenkins
-　秘密鍵　Jenkinsマスター上のファイルからを選択して`/var/lib/jenkins/.ssh/id_rsa`を入力
-　パスフレーズ：鍵生成の時にしていしたもの。なしの場合は初期表示を消す。

#### Gitlab 側
Jenkinsからアクセスするための専用ユーザーをGitlabに作成し、jenkinsサーバのjenkinsユーザーのid_rsa.pubをsshkeyとして登録します。

----

## 5.実行例
以下Chatの実行例（再掲）
<img width="361" alt="chat 2016-09-01 10.58.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/117986/e596e705-099a-f450-91e8-7bac2ec034e5.png">

## 6.その他ハマりどころなど
Mattermostの日本語の事例がまだ少ないようで、特にGitlabとの連携部分について
調べるのにgitlab謹製のためキーワードが重複してしまうため
Gitlab側の設定でWebhookではなく、サービスのSlackを使うというところに
気づくまでがはまりどころで、自分としては盲点でした。
Mattermostは　Slack Cloneをうたっているので当たり前といえば当たり前なのかもしれませんが。

それ以外は、特にはまりどころも少なかったので、既にGitlabとJenkinsをオンプレミスで利用されている環境であれば、検証レベルですがMattermostをハブとしてChatOpsライクなことを実施するハードルはかなり低いと感じました。

なお、今回ためしていませんがHubotを間に挟むと、メッセージや条件など、もう少し柔軟に設定できそうです。

## 7.参考

今回の検証にあたって以下を参考にさせていただきました。

 - http://qiita.com/terukizm/items/4524249dd7f1298fdc06
 - https://docs.mattermost.com/developer/webhooks-incoming.html
 - https://docs.mattermost.com/developer/webhooks-outgoing.html

以上です。