[ChatOps]Slackを利用して、ChatOps on Alibaba Cloudをやってみました !

## はじめに

本投稿は [SBCloud Engineers' Blog](https://www.sbcloud.co.jp/archive/category/techblog) にも投稿しています。SBCloud Engineers' Blogには日中間接続をはじめ、Alibaba Cloud関連のソリューションや技術ネタを記載していますので、よかったら是非一度アクセスみてください。


ChatOpsでECSインスタンスの起動や停止をすこし楽にしたいので、SlackからSlash CommandsでECSインスタンスを操作できるようにしてみました。

## アーキテクチャとフロー
![image.png](https://qiita-image-store.s3.amazonaws.com/0/117156/34739e73-c886-9e3f-4590-a78aa85fcacd.png)

#### 利用する主なサービス

- Slack / [Slash Commands](https://api.slack.com/slash-commands)
- [Function Compute(FC)](https://jp.alibabacloud.com/product/function-compute)
- その他
  - [Resource Access Management(RAM)](https://jp.alibabacloud.com/product/ram)
  - [Elastic Compute Service（ECS）](https://jp.alibabacloud.com/product/ecs)


#### 利用フロー

1. ユーザーは指定されたSlackとSlackのチャンネルにて、`/ecs start <instance-id>` のようなSlash Commandを実行します。

2. Slackはユーザーが発行したSlash Commandを指定されたURL(FCのHTTPトリガー)に送信します。
3. Front FCがSlackから送信された情報を受け取り、正当性確認を行います。確認した後、Slash Commandの情報を設定し、Execution FCを起動します。
4. Execution FCはFront FCから渡された情報を元に、指定されたECSインスタンスに対して操作し、その操作結果をSlackに送信します。

#### デモ

YouTubeの動画 [ChatOps on Alibaba Cloud](https://www.youtube.com/watch?v=_ABarVLD9kU) (1分18秒)にて、ご確認ください。


## アーキテクチャの解説

細かい設定作業は割愛しますが、重要なところだけ説明させていただきます。

### Slack

- **Slash CommandsのTimeout時間は3000ms**
一連の処理(特にFCの実行)が少し時間がかかりますので、Slash CommandsがTimeoutしないように、<Font color="red">Front FC</font> で一旦Slackからの情報を受け取り、Slackに返信すると同時に、受け取った情報を<Font color="red">Execution FC</font> に渡すようにしています。これが２つのFCを利用している理由です。

- **Slackから送信される情報**
以下のような情報がSlackからFCに送られます。
 1. **text**の内容にspaceが入っている場合,**space** は **+** に置き換えられます
 1. **response_url**はエンコードされますので、FCでデコードする必要があります 

```
token=3mVXdAC5EFNbsXYGNk0sah3M
team_id=T0001
team_domain=example
channel_id=C2147483705
channel_name=test
user_id=U2147483697
user_name=Steve
command=/weather
text=94070
response_url=https://hooks.slack.com/commands/1234/5678
```

### Function Compute

FCには [HTTPトリガー](https://jp.alibabacloud.com/help/doc-detail/74768.htm) という便利な機能があります。
HTTPトリガーを利用して、発行されたhttpsのURLにリクエストを送れば、FCが起動します。

Slackのタイムアウト時間は3sですので、今回下記2つのFunction Computeを作成しました。

- Front FC
   - 主な役割としては、Slackからの情報の確認とECSインスタンスを操作するExecution FCの起動です。
   - HTTPトリガーを設定しています。
   - 非同期方式(Async)でExecution FCを呼び出します。
- Execution FC
    - Front FCにてチェックされたコマンド情報を受け取り、ECSインスタンスを操作してから、その操作結果をSlackの特定のチャンネルに返します。

#### ソースコードについて
FCのソースコードはGitHubのレポジトリ [chatops_on_alibaba_cloud](https://github.com/jobbin/chatops_on_alibaba_cloud) においてあります。<font color="red">あくまでもサンプルコードで、実運用の際にはエラー処理とかも必要</font>ですので、ご注意ください。

- Front FC
    - ソースコードは front_fc.py になります。
    - 下記Front FCの変数に必要な情報を設定して、FC Functionに渡しています。
        - FUNCTION_COMPUTE_ENDPOINT  
        Execution FCを呼び出す際に利用します。Function Computeの管理画面に記載されていて、Internet Endpoint / Intranet Endpoint があります。Intranet Endpointの利用を推奨します。
        - INVOKE_FC  
        Execution FCの名前になります。
        - SLACK_CHANNEL  
        **文字列形式**で、正当性確認用の情報で、指定されたSlack ChannelからのみSlash Commandのみ対応します。
        - SLACK_TOKEN  
        **文字列形式**で、正当性確認用の情報で、指定されたSlackからのみSlash Commandのみ対応します。
        - ECS_CMD_CODE  
        **配列形式**で、正当性確認用の情報で、指定されたSlash Commandのみ対応します。

- Execution FC
    - ソースコードは execution_fc.py になります。
    - 下記、認証情報を変数に設定して、FCに渡しています。  
        - ACCESS_KEY_ID
        - ACCESS_KEY_SECRET

### RAM

FCはAlibaba Cloudのリソースを操作する権限が必要ですので、FCを作成する際に、予めその権限をFCに付与します。

今回はRoleとAccessKeyを利用します。

- RAM Role
 - プロダクト単位で設定します。
 - FCが実行される際には、設定されたRAM Roleから一時的な認証情報を取得して利用しています。

- AccessKey
 - Execution FCが利用するものです。  
   元々設定されているRAM Roleからの一時的は認証情報を利用したかったですが、一時的な認証情報を利用したECS clientの作成方法がわからなかったので、一旦AccessKey利用の方式にしました。ちなみに利用しているPythonSDK は [aliyun-python-sdk-core](https://github.com/aliyun/aliyun-openapi-python-sdk/blob/master/aliyun-python-sdk-core/aliyunsdkcore/client.py)です。

## その他

FCを開発する際には、[fcli](https://jp.alibabacloud.com/help/doc-detail/52995.htm) や [fun](https://jp.alibabacloud.com/help/doc-detail/64204.htm) というツールもありますので、ご興味ある方は是非一度触ってみてください。

## 最後

今回はAlibaba CLoud上でのChatOpsについて簡単にご紹介させていただきました。ご覧の通り、多少コーディングと利用ルールの整備が必要ですが、SlackとFCを利用すればAlibaba CloudのChatOpsも簡単にできてしまいます。皆さんの開発に少し役に立てると幸いです。