LoginSignup
45

More than 5 years have passed since last update.

Slackと連携するHubotをDocker in AWSで構築

Last updated at Posted at 2015-05-17

やりたいこと

  • Slackと連携できるHubotを立てる
  • デプロイ方法は、Github -> CircleCI -> AWSとする
  • slackへのAccess Tokenなどは環境変数で渡す(誰でも利用しやすいように)
  • scriptsは誰でも追加しやすいように、localレポジトリのをDockerへ持っていくようにする

まずはHubotに必要なものを揃える

  • node.js
  • npm

Mac環境ならどちらもbrew installで簡単に用意できる

YeomanとYeomanのgenerator-hubotを用意する。
-gをつけずにbundle的なのりでローカルにインストールしたかったが、実行にあたってのパス設定が面倒そうなので諦めた。

% npm install -g yo generator-hubot
% yo hubot
% bin/hubot

これでhubotとの対話インターフェースが立ち上がる。

  • scriptsディレクトリ以下にスクリプトを置くと、機能追加ができる。
  • hubot-scriptsディレクトリ以下には、hubot-scripts.jsonに定義したscriptsがインストールされる。利用できるscriptsはこちら
  • package.jsonに利用したいthird-party npm packageを追記すると、external-scripts.jsonに値が追加される。
  • ERROR hubot-heroku-alive included, but missing HUBOT_HEROKU_KEEPALIVE_URLというメッセージが表示されてしまうので、external-scripts.jsonからheroku packageを削除。

Dockerの用意

  • Dockerfileを書く
  • hubotの実行にnode.jsが必要なので、Docker registryからnode:latestを持ってくる。-> https://registry.hub.docker.com/u/library/node/
  • あとは、ローカル側に用意したhubotの構成をDockerインスタンス上に移設して起動する設定をDockerfileに書く。

Dockerを起動してみる

まずはbuild

% docker build -t hubot .

そうすると、イメージが作成される。

% docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
hubot               latest              663c24a4b22a        54 seconds ago      717.4 MB

作成されたイメージ上で、hubotを起動してみる

% docker run -it hubot bin/hubot
hubot> hubot ping
PONG

Slackの用意

Integration Settings

  • Hubotを有効に。
    • API Tokenを得られる
    • Iconのカスタマイズ、Nameのカスタマイズもできる

Dockerの起動

% docker run -e HUBOT_SLACK_TOKEN=${HUBOT_SLACK_TOKEN} -e HUBOT_SLACK_TEAM=${HUBOT_SLACK_TEAM} -e PORT=${PORT} -d -p 9999:9999 -v "$(pwd)":/hubot hubot

これでチームにhubotが参加してくる。

CircleCIの用意

circle.yml
machine:
  services:
    - docker
dependencies:
  cache_directories:
    - "~/docker"
  pre:
    - if [[ -e ~/docker/hubot.tar ]]; then docker load --input ~/docker/hubot.tar; fi
    - docker build -t hubot .
    - mkdir -p ~/docker
    - docker save hubot > ~/docker/hubot.tar
test:
  override:
    - docker run -p 9999:9999 -v "$(pwd)":/hubot hubot
  • circleCI上でDockerコンテナを起動するときは、services: dockerが必要
  • dependenciesのところは、dockerのイメージを毎回registryからダウンロードしなくてよいようにキャッシュしている

Hubotへスクリプトの追加

stamp.coffee
# Description:
#   A way to interact with the Stamp URI.
#
# Commands:
#   hubot stamp me <keyword> - The Original. Queries Stamp Images for <keyword> and returns a stamp image.
#   hubot stamp list         - Show a list of keywords.

stamps = JSON.parse(process.env.HUBOT_STAMPS)

module.exports = (robot) ->
  robot.respond /stamp me (.*)/i, (msg) ->
    keyword = msg.match[1]
    msg.send stamps[keyword] ? "No stamp for #{keyword}"

  robot.respond /stamp list/i, (msg) ->
    keys = for key, value of stamps
             key
    msg.send keys.join('\n')

scripts以下に配置するとhubotの起動時に読み込んでくれる。
決められたフォーマットでコメントを書いておくと、hubot helpしたときにコマンドの説明を表示してくれる。このscriptでは環境変数HUBOT_STAMPSにJSONを登録しておくと、keyに紐付いたimageのURLを返してくれる。

AWSへAnsibleを使ってデプロイする

hubot.yml
- hosts: aws
  user: ec2-user
  vars_files:
    - vars/env.yml
    - vars/private.yml
  tasks:
    - git: repo=https://github.com/osamunmun/hubot.git dest=/home/ec2-user/hubot accept_hostkey=yes
    - file: path=/home/ec2-user/cache state=directory
    - shell: cd /home/ec2-user/hubot; sudo ./docker-build.sh
    - shell: sudo docker stop $(sudo docker ps -a -q)
    - shell: cd /home/ec2-user/hubot; sudo docker run -e HUBOT_STAMPS={{ HUBOT_STAMPS }} -e HUBOT_SLACK_TOKEN={{ HUBOT_SLACK_TOKEN }} -e HUBOT_SLACK_TEAM={{ HUBOT_SLACK_TEAM }} -e PORT={{ PORT }} -p 9999:9999 -d -v $(pwd):/hubot hubot/slack

CircleCIからデプロイする

  • circleCIの環境変数に以下の値を登録しておく
    • ANSIBLE_VAULT
    • AWS_ACCESS_KEY_ID
    • AWS_DEFAULT_REGION
    • AWS_SECRET_ACCESS_KEY
    • AWS_SECURITY_GROUP_ID
    • HUBOT_SLACK_TEAM
    • HUBOT_SLACK_TOKEN
  • circleCIのSSH Permissionsにデプロイ先のEC2インスタンスへアクセスできる秘密鍵を登録しておく
circle.yml
machine:
  services:
    - docker
dependencies:
  cache_directories:
    - "~/cache"
  pre:
    - ./docker-build.sh
    - npm install
    - sudo pip install awscli
    - sudo pip install ansible
    - echo "${ANSIBLE_VAULT}" > ~/vault.txt
test:
  override:
    - ./node_modules/.bin/gulp mocha
    - docker run -e HUBOT_SLACK_TOKEN=${HUBOT_SLACK_TOKEN} -e HUBOT_SLACK_TEAM=${HUBOT_SLACK_TEAM} -e PORT=${PORT} -d -p 9999:9999 -v "$(pwd)":/hubot hubot/slack
deployment:
  production:
    branch: master
    commands:
      - sh ./deploy.sh
deploy.sh
#!/bin/sh
set -ex

IP=`curl -s ifconfig.me`

trap "aws ec2 revoke-security-group-ingress --group-id ${AWS_SECURITY_GROUP_ID} --protocol tcp --port 22 --cidr ${IP}/32" 0 1 2 3 15
aws ec2 authorize-security-group-ingress --group-id ${AWS_SECURITY_GROUP_ID} --protocol tcp --port 22 --cidr ${IP}/32
cd ansible; ansible-playbook -i hosts hubot.yml --vault-password-file ~/vault.txt
ansible/hubot.yml
- hosts: aws
  user: ec2-user
  vars_files:
    - vars/env.yml
    - vars/private.yml
  tasks:
    - git: repo=https://github.com/osamunmun/hubot.git dest=/home/ec2-user/hubot accept_hostkey=yes
    - file: path=/home/ec2-user/cache state=directory
    - shell: cd /home/ec2-user/hubot; sudo ./docker-build.sh
    - shell: sudo docker stop $(sudo docker ps -a -q)
    - shell: cd /home/ec2-user/hubot; sudo docker run -e HUBOT_STAMPS={{ HUBOT_STAMPS }} -e HUBOT_SLACK_TOKEN={{ HUBOT_SLACK_TOKEN }} -e HUBOT_SLACK_TEAM={{ HUBOT_SLACK_TEAM }} -d -v $(pwd):/hubot hubot/slack

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
45