#はじめに
先日【drone.ioを使ってCI環境を構築したので、色々整理してみた___<基本編>】を書きました。タイトルは揃っていませんが、今回はそれの続編で、Slackからデプロイコマンドを打って、droneがおとなしく指示通りにやってくれる方法について書きます、。
SlackでのChatOps
(AWS寄りになってしまいますが)Slackを使って、ChatOpsをする時に、下記API Gatewayを使うパータンがよくあるのではないかと思います。もちろん、SlackからHubotを呼ぶのもあります。
ちなみに、Slack → API Gateway → Lambdaにご興味がある方は、下記、昨年私が書いた記事を見て頂ければと思います。
【Slack de AWS CLI】SlackのChannelからAWS CLIを実行できるようにしてみました!
元々、自分もAPI Gatewayを使うと考えていました...が、つい先日(夜眠れない日)に、「なんか面白いツールないかな」とSlackのインテグレーションを漁っていて、偶然に見つかったのはOpsidianというツールです。正確的にはOpsidian.aiという名で、aiが付いています...よ。Opsidian.aiにご興味がある方は、是非Opsidian.aiの公式ページを見てください。面白いことをいっぱい書いてあります。
※ 私はあまりにも感動しすぎて、めちゃくちゃの英語でこのツールの親であるewadwornikowskaさんにメッセージを送りました。
話を戻りますと、最終的にAPI Gatewayを辞めて、こんな感じにしました。
一見、API GatewayのかわりにOpsidianを使っているだけじゃんというツッコミもありますが、個人的にはOpsidianのほうが結構楽だと思います。 API Gatewayもそれなりの使い方がありますので、ChatOpsをやる時に、選択肢が1つ増えたという捉え方のほうがいいと思っています。API GatewayとOpsidianを簡単に比べてみますと、
1. API Gatewayの設定より、Opsidianのほいうが楽
2. API Gatewayを利用する場合、認証とか入れないと、エンドポイントがバレたら、だれでも叩けるようになる。一方、OpsidianはSlackに設定したアクセスキーでLambdaをinvokeするので、安全(?)かも
3. だれがLambdaを呼べるかの処理は、Opsidian側で制御可能。
4. Opsidianって、ただLambdaをinvokeするだけではなく、AWSリソースのモニタリングもできる。
※ 私個人的な意見にはなりますが、OpsidianってChatOpsの神ツールだと思っています。
SlackからAWS ECRにイメージプッシュまでやってみる
流れ的には、こんな感じになります。
Slack → Opsidian → Lambda → GitHub → drone → AWS ECR
何をやっているかとざっくり説明しますと、
1: Slackからデプロイの指示を出します
2: Opsidianはその指示通りにLambdaをinvokeします。
3: invokeされたLamndaはGitHubへdeploy APICallします。
4: GitHubはdeployのWebhookをdroneに送信します。
5: droneは受信したWebhookからソースを取得し、ビルドを実行し、AWS ECRへイメージをpushします。
細かい設定とかは割愛します。今後時間がありましたら、書くかもしれません。...と言っても、簡単に何を設定しているかを書きます。
1: SlackからOpsidianを呼べるようにしました。
- Opsidianのインストールはこちら
- Opsidianの設定はこちら
2: OpsidianがinvokeするLambdaを作りました。
- OpsidianのDashboardにて、Slackから呼べるLambdaのコマンドdeployを設定しました。
- 下記、超雑なLambdaサンプルコード
※ Opsidianのコマンドから渡された引数を使って、GitHubへdeploy APICall
※ GithubのPersonal access tokenはlambdaの環境変数GIT_KEYに設定しています。
import boto3
import json
import os
import http.client
def lambda_handler(event, context):
conn = http.client.HTTPSConnection("api.github.com")
print(event)
args = event["args"].split(" ")
repo = args[0]
branch = args[1]
env = args[2]
payload = {
"ref": branch,
"auto_merge": False,
"environment": env,
"description": "Deploy to "+ env,
"required_contexts": []
}
headers = {
'authorization': "token " + os.environ['GIT_KEY'],
'User-Agent': "Awesome-Octocat-App"
}
conn.request("POST", "/repos/"+ repo +"/deployments", json.dumps(payload).encode("utf-8"), headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
return json.dumps({'message': 'Hello world!'})
3: Github
- 下記2つのファイル(あくまでもサンプル)が対象のリポジトリの配下に格納しました。
# masterブランチに対して、
# GitHubのevnetがdeploymentかつenvironmentがproductionと指定された場合
# ビルドを実行
pipeline:
ecr:
image: plugins/ecr
region: ap-northeast-1
repo: 284****1948.dkr.ecr.ap-northeast-1.amazonaws.com/ecr
tags: [ latest,drone-test ]
secrets: [ ECR_ACCESS_KEY,ECR_SECRET_KEY ]
when:
branch: master
event: deployment
environment: production
FROM centos:6
RUN set -x && \
yum install -y httpd
4: drone
- AWS ECRへpushできるdroneのプラグインplugins/drone-ecrを利用しています
※ ソースコードはこちら
- 対象ブランチを有効化しました。
- droneにecrへpushできる権限のキーを設定しました。
※ plugins/drone-ecr利用時、設定する環境変数はECR_ACCESS_KEYとECR_SECRET_KEYになります。
- 今回はGitHubのdeploymentの場合ですので、「Settings」の**「Deploy Hook」**を有効にしました。
5: ECR
- droneがビルドしたdockerイメージのpush先を予め用意しました。
Slackからやってみる
1: Slackから /ops run deploy [repository] [branch] [environment]
を打ってみます。
2: Opsidianから返信が来ました. やっはり Hello worldにすべきじゃなかったかもしれません。微妙に違和感が感じますが、一旦よしとします。
5: 終了
最後
Opsidianとdroneで、SlackからAWS ECRへイメージをpushするまでについて整理しました。繰り返しにはなってしまいますが、Opsidianが結構便利なツールなので、ChatOpsだけではなく、モニタリングとかにも活用したいと思っています。
今日はとりあえずここまでにします。