LoginSignup
5
3

More than 3 years have passed since last update.

Pythonのslackbotライブラリでterraform plan実行してもらう

Last updated at Posted at 2018-09-17

6/18追記
色々と改良したものを、別記事で投稿しました。
https://qiita.com/andromeda/items/32a6ae52ca2cf50449e2

はじめに

前記事でpythonでterraform planを実行してslackへ通知するを投稿させて頂きました。
今回はslack botに実行してもらいます:grin:

事前準備

  1. slack botsを作成してAPI トークンを取得(トークンを使用するIP制限をかけられたりできます。)
  2. botをチャンネルへ招待する
  3. slack botライブラリのインストール
$ sudo pip install slackbot

環境準備(ディレクトリ/ファイル作成)

terraformer_by_python.pyファイルは前記事のscriptを使います。

├── slackbot                           # botのプログラムファイルをまとめるディレクトリ
│   ├── models                         # botの機能(応答とか処理とか)をまとめるパッケージのディレクトリ
│   │   ├── __init__.py                # パッケージとして示すためのファイル(空でよい)
│   │   ├── my_mention.py              # 機能を書くファイル
│   │   ├── terraformer_by_python.py   # terraform planを実行するscript
│   ├── run.py                         # このファイルを実行するとbotが起動する
│   ├── slackbot_settings.py           # botの設定ファイル

scriptファイル

run.pyファイル

run.py
# coding: utf-8

from slackbot.bot import Bot

def main():
    bot = Bot()
    bot.run()

if __name__ == "__main__":
    main()

slackbot_settings.pyファイル

slackbot_settings.py
# coding: utf-8

# 取得したAPIトークン
API_TOKEN = "XXXX-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXXXXXXXXXXXX"

# プラグインスクリプトを置いてあるサブディレクトリ
PLUGINS = ['models']

my_mention.pyファイル

my_mention.py

# coding: utf-8
from slackbot.bot import respond_to        # @botname宛てで反応するデコーダ
from slackbot.bot import listen_to         # チャンネル内の発言に反応するデコーダ
from slackbot.bot import default_reply     # 何れも該当しない場合に反応するデコーダ
import terraformer_by_python 
import json

prj_config = "/terraform/prj_config.json"

@default_reply()
def default_func(message):
    message.reply("```コマンド(メンション必要です)\n\
list                : terraformer管理project一覧\n\
plan                : 全projectのterraform plan実行\n\n\
私が落ちてたら以下のサーバで \n\
'nohup python /terraform/slackbot/run.py &' を実行して下さい\n\
botが稼働しているgceのリンク\n```")


@respond_to(r'^list.*')
def list_func(message):
    with open(prj_config, "r") as config_file:
        json_data = json.load(config_file)
        reply = json.dumps(json_data,indent=4)
    message.reply("```\n追加削除はこのファイルです ⇒ /terraform/prj_config.json\n{}```".format(reply))

@respond_to(r'^plan.*')
def plan_func(message):
    message.reply("ok! ちょっと待ってて!")
    terraformer_by_python.main()

一個ずつ見ていきます。

@default_reply

他のデコーダ(respond_to)に該当しない場合に反応します。
応答はmessage.replyでメンションを付けて応答し、message.send('string')でメンションなしで応答します。

# message.reply('string')   @発言者名: string でメッセージを送信
# message.send('string')    string を送信

@default_reply()
def default_func(message):
    message.reply("```コマンド(メンション必要です)\n\
list                : terraformer管理project一覧\n\
plan                : 全projectのterraform plan実行\n\n\
私が落ちてたら以下のサーバで \n\
'nohup python /terraform/slackbot/run.py &' を実行して下さい\n\
botが稼働しているgceのリンク\n```")

こんな感じで応答が返ってきます。
gcp上で常時稼働させているので、gceのリンクと落ちてた場合の起動コマンドを書いてます。
image.png

@respond_to

bot宛て(メンション付き)のメッセージを拾います。正規表現で指定が可能です。
今回はbot宛で、先頭にlistがあったら、terraformで管理してるプロジェクト一覧のファイルを返すようにしてます。

# @respond_to('string')     bot宛のメッセージ
#                           stringは正規表現が可能 「r'string'」
import json
prj_config = "/terraform/prj_config.json"

@respond_to(r'^list.*')
def list_func(message):
    with open(prj_config, "r") as config_file:
        json_data = json.load(config_file)
        reply = json.dumps(json_data,indent=4)
    message.reply("```\n追加削除はこのファイルです ⇒ /terraform/prj_config.json\n{}```".format(reply))

image.png

さて、メインですが、先頭にplanがあったら、前記事で書いたscriptを実行し terraform planの結果を返す様にしています。

import terraformer_by_python

@respond_to(r'^plan.*')
def plan_func(message):
    message.reply("ok! ちょっと待ってて!")
    terraformer_by_python.main()

image.png

最後に

初めてslackbotを扱いましたが色々出来ると思います!
なにか自動化出来るネタ探してチャレンジしてみたいと思います!:grin:

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3