SlackワークフロービルダーでAWS Chatbotのコマンドをテンプレ化する

この記事は[Speee Advent Calendar 2019](https://qiita.com/advent-calendar/2019/speee) 2日目の記事です。

## あらすじ

2019/11/25に[AWS ChatbotでSlack上からAWSコマンドを実行できる機能](https://aws.amazon.com/about-aws/whats-new/2019/11/aws-chatbot-supports-running-commands-from-slack-beta/)がbeta版としてリリースされました。

Slack上でAWSコマンドが簡単に実行できて結果が共有できるというのは魅力的ですが、AWSコマンドは一つ実行するにしても沢山のオプションを埋めて実行する必要があるので、適切に実行するのはなかなか難しいです。

そこで、Slackワークフロービルダーと組み合わせたら、Slackの優れたインターフェースからよく使うコマンドの実行をテンプレ化できて便利なのではと閃き、色々試してみましたので結果を共有します。

なおAWS Chatbotのセットアップやワークフロービルダーそのものの説明は本筋ではないので割愛します。

## 使用例その1:describe-instancesを実行する

まずは簡単な例としてec2の[describe-instances](https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-instances.html)を特定リージョン、特定のタグのインスタンスに対して実行したいケースを考えてみます。

例えば `us-east-2` の `Role:app` のタグが付いているインスタンスの状態を見たいとします。
その場合必要なコマンドは以下のようになります。

```console
aws ec2 describe-instances --filters Name=tag:Role,Values=app --region us-east-2
```

比較的記述量が少ないコマンドではありますが、それでもパッとこのコマンド記憶して実行するのは難しいです。

### ワークフローの作成

ではワークフロービルダー化していきます。
ワークフロービルダーの画面からアクションメニューとしてワークフローを作ります。

まずはフォームのステップを作成します。どのregionで実行するかの質問を`一覧から選択`で作ります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87808/6342f95e-99a9-0830-c4e2-a79a05972618.png" width=50%>

同様にどのTagのインスタンスをフィルタするかの質問を`一覧から選択`で作ります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87808/b5b2f9eb-6b9c-0b00-7b31-353c99f3e9d9.png" width=50%>

フォームの全体としてはこんな感じです。保存するを選択します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87808/4e5b88c5-2f4c-0f4b-5773-946f0e894e4e.png" width=50%>

次にメッセージを送信するステップを作成します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87808/e1a1716d-ada5-2792-2227-732531307657.png" width=50%>

`変数を挿入する` を使うとフォームの入力項目を変数として組み込めるのでそれを元にAWSコマンドを組み立てます。

これでワークフローは完成です！

### ワークフローの実行

実際に動かしてみます。ワークフローを作ったチャネルの右上にボタンがあるので作ったワークフローを選択します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87808/59e23c8f-13e7-6b2a-12ee-3f96e53b210a.png" width=50%>

フォームが出てくるので値を埋めて実行します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87808/98b5fe05-b5c9-3e8f-6e2a-9f08498e79ad.png" width=50%>

無事ワークフロー経由でAWSコマンドが実行できました :tada: :tada:

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87808/04324767-5491-944e-2d02-bfb918ec6ab4.png" width=80%>

このように、複雑なコマンドでもワークフローを介することで使いやすいフォームのインターフェースから実行することができます。

## 使用例その2:Lamndaを実行する

ChatBotはAWS Lambdaを起動する[invoke lamndaコマンド](https://docs.aws.amazon.com/cli/latest/reference/lambda/invoke.html)も実行できます。
次の例としてLambdaをワークフロービルダーを介して実行するケースを紹介します。

まずは適当なLambda関数をデプロイします。適当に入力をechoするLambda関数です。

```python
import os
import json

def lambda_handler(event, context):
    print(json.dumps(event))

    return json.dumps(event)
```

例えばechoするテキストを何らか変えたいとします。なので実行するコマンドは以下のようします。

```console
aws lambda invoke --function-name testChatOps --log-type Tail --region us-east-2 --payload '{"text": "何か任意の文字列"}'
```

Payloadのtextカラムの値をパラメータ化したワークフローを作成します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87808/e7c5b2b2-d264-9679-c0b7-fa983a97d48c.png" width=50%>

ここでハマりどころが一つあって、macOSではスマートクォートの機能を切っておかないと勝手にダブルクォートが`“”`みたいな左右の向き付きのダブルクォートに変換されてJSONのPayloadがうまくパースされなくなる問題が発生します。macOSの場合はシステム環境設定のキーボードからスマートクォートを無効化できるので切ってSlackを再起動しましょう。

ではワークフローを実行してみます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87808/7a277f5e-e151-f696-0cf2-c84b14eae0e2.png" width=50%>

Lambda invokeの場合は実際に実行するコマンドを表示して実行するか訪ねてきます。
Yesを押すと先に進んで結果が表示されます :tada: 

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87808/28a94ee4-8f3e-fc2e-f93a-54b01e35e78d.png" width=80%>

ここで一つ残念なポイントとして`lambda invoke`は結果をbase64でencodingして返してくるのでSlack上で結果だけをぱっと見てもよくわかりません。

一応LogResultをデコードしてみると以下のような結果となり正しく実行できていることがわかります。

```console
START RequestId: fd9e85af-4ee5-435f-ba08-4682dfe7926a Version: $LATEST
{"text": "Hello from workflow!!"}
END RequestId: fd9e85af-4ee5-435f-ba08-4682dfe7926a
REPORT RequestId: fd9e85af-4ee5-435f-ba08-4682dfe7926a	Duration: 18.80 ms	Billed Duration: 100 ms	Memory Size: 128 MB	Max Memory Used: 57 MB
```

この辺はChatbotがGAするまでに何らか見やすい手段を提供して欲しいですが、さしあたって欲しい情報はwebhookで通知するなどすれば回避できます。

## 終わりに

以上SlackのワークフローとAWS Chatbotの組み合わせの紹介でした。

Slackの使いやすいフォームからAWSコマンドを発行できるようになるので、例えば運用上たまに手動実行したいジョブをワークフローとして実行するなどの利用方法が考えられます。ワークフローはパラメータを選択式にできるのが良いですね！とても使いやすく入力の手間も省けるしパラメータをタイポしてうまく動かない...みたいな問題も回避できます。

また、現在は参照系以外のコマンドとしてlambda invokeコマンドしかサポートされていないのですが、codebuildのstart-buildとかssmのsend-commandなんかもサポートされたら夢が広がります。（一応、今でもLambda経由で実行はできはします）

もちろんガチで使う場合は権限設計をちゃんとしたいので、GAまでにその辺もう少し制御しやすい仕組みが導入されるといいなぁと思ってます。