LoginSignup
7
5

More than 5 years have passed since last update.

【ChatOps】golang + slack + ansibleで、プロビジョニングからデプロイまで。

Last updated at Posted at 2018-12-16

はじめに

デプロイツールとして、anisble-playbookを利用して
slackからデプロイできるようにした話です。

背景

  1. stg/prd環境のEC2 provisioning -> middleware install -> deployを全て、ansible-playbookで実施している。
  2. 開発チームの方々にもansible-playbookのコマンドを実行してもらっていた。
  3. 各種環境のデプロイはEC2上のサーバーから実施している。
  4. スプレッドシートにて、ansible-playbookの各種サーバー毎/task毎にコマンドを記載して、実行してもらっていた。
  5. 今までインフラとして、AWSやログ分析・監視基盤の構築をしていたので、自分自身が全くと言っていいレベルでプログラムのスキルがなかったので、勉強がてらgolangやりたかった。

課題・懸念

解決したい課題・懸念は、以下3点。

  1. 実行コマンドをコピペミスで、誤実行してしまうリスクがある。
  2. 「誰が」実行しているかわからない。
  3. サーバーにそもそも入らなければ、デプロイできない。

作ったもの

対象 URL
go-slack-ansible https://github.com/jkkitakita/go-slack-ansible

go-slack-ansible-trim.gif

前提

Mercariの @deeeet さんが書いた
GolangでSlack Interactive Messageを使ったBotを書く
の記事を参考にさせていただきながら、作成しました。

ディレクトリ構成

ansible
 ├ inventory
 │  ├ stg
 │  │ ├ group_vars
 │  │ └ host
 │  └ prd
 │   ├ group_vars
 │   └ host
go-slack-ansible
 ├ ansible
 │  ├ config
 │  │ └ config.go            // ansible-playbookのconfig関連
 │  ├ ansible_playbook.go     // ansible-playbookで、provisioningとdeploy実行
 │  ├ branch.go               // デプロイするブランチを指定
 │  ├ config.yaml             // hostとrepoの対応一覧 & ansibleのtagの一覧
 │  ├ const.go                // 定数
 │  ├ inventory_scanner.go    // ansibleのinventoryを読み取って、対象ホストを取得
 │  ├ tag.go                  // 指定するtagを取得する
 │  └ terminate.go            // ansible-playbookでサーバーのterminateを実行
 ├ cmd
 │  └ bot
 │   ├ handler.go            //
 │   ├ main.go               // Slack Interactive Messages
 │   └ slack.go              // 
 ├ config
 │   └ config.go             // logger等の設定
 ├ logger
 │  └ logger.go               // zapにて、logging
 ├ scripts
 │  └ restart.sh              // 再起動スクリプト
 ├ .env              // slack BotID Channel,GitHub token etc...
 ├ go.mod
 ├ go.sum
 └ Makefile

工夫したところ

前のメッセージの状況を残したい。

上記のgifを見てもらえればわかる通り
選択したhostやtagが選択後にメッセージに表示させています。
このように既存のメッセージの状態を上書きするためには
Slack Interactive Messageで、replace_originaltrueにする必要があリます。

Replacing the original message
https://api.slack.com/interactive-messages#building_workflows

これをしないと

go-slack-ansible-replace.gif

このようになり、無駄に投稿されてしまう。
また、前の投稿を再度編集、選択できてしまいます。
nlopes/slackを使った今回の場合は

originalMessage.ReplaceOriginal = true

https://github.com/jkkitakita/go-slack-ansible/blob/5a7f858e73/cmd/go-slack-ansible/handler.go#L109
として、replace_originaltrueに毎回上書きをすることで、できるようになりました。

zapのloggerにlogvel,caller,traceを追加する

botと全然関係ないけど(笑)
試しにloggerの勉強をしようと思って、zapを入れて見たものの
zapのドキュメントが少なく、loggerを仕込むにも一苦労したので、めも。
zap.New時に、↓のように渡してあげると、

return zap.New(
    zapcore.NewCore(enc, w, zapConfig.Level),
    zap.AddCaller(),
    zap.AddStacktrace(zapcore.WarnLevel),
)

ex. INFO
{"severity":"INFO","timestamp":"2018-12-14T22:24:08.972+0900","caller":"go-slack-ansible/main.go:58","message":"[INFO] Start slack event listening"}

ex. WARN
{"severity":"WARN","timestamp":"2018-12-14T22:26:27.968+0900","caller":"go-slack-ansible/slack.go:71","message":"[WARN] Invalid bot: Jun Kitamura [10:22 PM]","trace":"main.(*SlackListener).handleMessageEvent\n\t/Users/jun.kitamura/go/src/go-slack-ansible/cmd/go-slack-ansible/slack.go:71\nmain.(*SlackListener).ListenAndResponse\n\t/Users/jun.kitamura/go/src/go-slack-ansible/cmd/go-slack-ansible/slack.go:37"}

今後の課題

  1. そもそもtest書いてない。。すいません。。
  2. methodを使って書きたかったが、全て普通の関数funcになってしまった。。
  3. 構造体、interfaceまだ勉強中です。。

さいごに

golang初挑戦でした。
色々な参考書や記事をツギハギでやりました。

コードも、記事の構成もツッコミどころ満載で、どこから突っ込んだらいいかわからないとは思いますが
「ここは違うだろ!」「ここはこうした方がいいよ!」
とかあれば、いつでも、コメントください。非常に喜びます。

7
5
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
7
5