yutaponのブログ

javascript界隈の興味あるネタを備忘録的に残しておく場所

Ansible使ってVagrant上のCentOSにHubot入れる

GithubKaigiでHubotが結構フィーチャーされてたので触ってみました。

f:id:sskyu:20140602235518p:plain

https://hubot.github.com/
https://github.com/github/hubot

Hubotでヒューボットと読むらしいです。
(Human + Botとか)

最近思うのですが、何かの環境構築するならAnsibleでPlaybook書いておくと後からやる時にいろいろと助かるので、Hubot動かすまでのPlaybook作りました。

Hubotをインストールするにあたり、こちらの記事を参考に進めました。
かなり助かりました。
開発のお手伝いボット Hubot で定期処理を自動化しよう! | KRAY

Hubotとは

Hubotの代表的な使い方はHipChatとかSkypeのユーザーとしてログインさせて、Hubotに話しかけてJenkinsのジョブを実行させる、といった感じです。

チャットルーム上で人間のように振る舞ってくれるってのが良くて、中身はBotなんですが親しみを覚えてしまいます。

魔改造することで人格を持つようになるんじゃないでしょうか(?)

インストール方法

Hubotを動かすためには

があればいいようです。

これらの環境が整ったら、

$ npm install -g hubot  # hubotをグローバルに入れる

npmでhubotを入れて、

$ cd path/to/workspace  # 作業ディレクトリに移動して
$ hubot --create mybot  # hubot --createでひな形作成
$ cd mybot
$ npm install  # 依存パッケージインスール
$ ./bin/hubot  # hubot起動

といった感じで起動できます。

AnsibleのPlaybookに手順を落とす

前に書いたAnsibleの記事を参考に作ってます。
sshの設定とかは前の記事を読んでもらえればと。

Ansible使ってVagrantのゲストOSの構成管理する【Playbook: jenkins, node.js】

まずフォルダの構成はこんな感じなってます。

$ tree
.
├── Vagrantfile
├── local_hosts
├── roles
│   └── common
│       └── tasks
│           ├── epelrepo.yaml
│           ├── hubot.yaml
│           ├── nodejs.yaml
│           └── redis.yaml
└── site.yaml

前回は一つのPlaybookにまとめてしまったので、今回はとりあえず設定を散らせるようにしてみた。

本当はもっと細かく分けたほうが良いんですが、まずは動くものを作るってことで後々フォルダ構成をリファクタしていきます。

Ansible流のフォルダ構成を参考にするときはこちらを見ました。
Ansible Tutorial, 6.1. 各ディレクトリ、ファイルの役割・意味

site.yaml

site.yamlってのがPlaybookの起点になるらしい。
ansibleコマンドを実行するときも、このファイルを渡せばいいことになる。

# @file site.yaml
---
- hosts: servers
  user: vagrant
  tasks:
    - include: roles/common/tasks/epelrepo.yaml
    - name: 'install git'
      yum: name=git state=latest
    - include: roles/common/tasks/redis.yaml
    - include: roles/common/tasks/nodejs.yaml
      vars:
        node_version: '0.10.28'
        nodebrew_path: '.nodebrew/current/bin'
    - include: roles/common/tasks/hubot.yaml
      vars:
        nodebrew_path: '.nodebrew/current/bin'
        project_dir: "/home/vagrant/beatbot"

tasks以下が順次実行されていきます。
大まかにいうと、

  • epelリポジトリ入れる
  • Git入れる
  • Redis入れる
  • Node.js入れる
  • Hubot入れる

って手順を踏みます。

local_hosts

ただ単にサーバーをグルーピングしてIPを書いたファイルです。
現状ローカル環境でしか使わないのでlocal_hostsという名前になってます。
dev_hostsとかstg_hostsとか用意してもいいかもしれません。

$ cat local_hosts
[servers]
192.168.33.10  # Vagrant上のCentosのIP

roles

この下に実際に何やかんやするタスクファイルを置きました。
roles/common以下に現状全てのタスクを置いてますが、これはよろしくないので参考にしないでください。
上で貼ったAnsible Tutorial読むと詳しいこと書いてます。

epelrepo.yaml

# @file epelrepo.yaml
- name: get epel repo
  get_url: url="http://ftp-srv2.kddilabs.jp/Linux/distributions/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm" dest=/var/tmp/epel-release-6-8.noarch.rpm
  sudo: yes

- name: set epel repo
  yum: name=/var/tmp/epel-release-6-8.noarch.rpm state=present
  sudo: yes

vagrantユーザーで実行してるので、基本的にyumを使うときはsudo: yesを指定します。

RPM落としてきて$ rpm -ivhでインストールすると、2回め以降エラーが出てしまいました。
いろいろ調べたらyumモジュール使ってRPM入れるといいとのことだったので、yumモジュールでインストールしてます。

redis.yaml

# @file redis.yaml
- name: install redis
  yum: name=redis state=latest enablerepo=epel
  sudo: yes

- name: start redis service
  service: name=redis state=started
  sudo: yes

redisをインストールして、サービス起動してます。

nodejs.yaml

# @file nodejs.yaml
- name: install perl
  yum: name=perl
  sudo: yes

- name: download nodebrew
  get_url: url="http://git.io/nodebrew" dest=/var/tmp/nodebrew

- name: install nodebrew
  command: perl /var/tmp/nodebrew setup

- name: rewrite .bashrc for export path
  shell: echo export PATH=/home/vagrant/.nodebrew/current/bin:$PATH > /home/vagrant/.bashrc

- name: install nodejs ver{{ node_version }}
  shell: nodebrew install-binary v{{ node_version }}
  ignore_errors: yes
  environment:
    PATH: "/home/vagrant/{{ nodebrew_path }}:{{ ansible_env.PATH }}"

- name: use nodejs
  shell: nodebrew use {{ node_version }}
  environment:
    PATH: "/home/vagrant/{{ nodebrew_path }}:{{ ansible_env.PATH }}"

- name: append use nodejs to .bashrc
  command: echo use {{ node_version }} >> ~.bashrc

- name: show version of node.js
  command: node --version
  environment:
    PATH: "/home/vagrant/{{ nodebrew_path }}:{{ ansible_env.PATH }}"

Node.jsのインストールは前に書いたPlaybookをほぼそのまま使ってます。

ちょっとはまった部分としては、各タスクにsudo: yesを付けるとユーザーの環境変数がrootになってしまうこと。
vagrantユーザーの.bashrcを上書きしてたと思ったら、rootユーザの.bashrcを上書きしてたりしました。。

また、yaml内の変数はsite.yamlから受け取っています。
(本来はroles/common/vars内に記述するべき)

※ .bashrcを上書きする箇所があるので、参考にする場合は注意して下さい。

hubot.yaml

# @file hubot.yaml
- name: install coffee-script
  command: npm install -g coffee-script
  environment:
    PATH: "/home/vagrant/{{ nodebrew_path }}:{{ ansible_env.PATH }}"

- name: install hubot
  command: npm install -g hubot
  environment:
    PATH: "/home/vagrant/{{ nodebrew_path }}:{{ ansible_env.PATH }}"

- name: install libicu-devel
  yum: name=libicu-devel state=latest
  sudo: yes

- name: install application
  git: repo=git@github.com:sskyu/my-beat-bot.git dest={{ project_dir }} accept_hostkey=True

- name: setup application
  command: npm install --prefix {{ project_dir }}
  environment:
    PATH: "/home/vagrant/{{ nodebrew_path }}:{{ ansible_env.PATH }}"

ところどころenvironmentと記述してるのは、Ansibleでタスク実行中はこれ書かないとコマンドのパスを解決してくれなかったからです。
上位の部分で書くとか、もっといい方法があるはず。

最後から2つ目のタスクで、GithubからHubotプロジェクトを落としてきています。

(これからHubotを賢くしていくので、HubotプロジェクトだけをGithubに上げています。 Playbookで$ hubot --create botしてもいいのですが、それだとデプロイするとき困りますよね)

- name: install application
  git: repo=git@github.com:sskyu/my-beat-bot.git dest={{ project_dir }} accept_hostkey=True

GithubからsshでCloneしてくるには実行ユーザのホームディレクトリに秘密鍵がないといけないのですが、ホスト側のsshVagrantの設定を少し変えて対応しました。

こちらを参考にしました。
VagrantゲストOSからのGitHubソース取得をAnsibleで自動化する方法について | Safx

  # @file Vagrantfile

  # If true, then any SSH connections made will enable agent forwarding.
  # Default value: false
  config.ssh.forward_agent = true  # ←コメントアウト外す

最後のタスクでは、指定したディレクトリ配下のpackage.jsonに対して$ npm initしたいので、npmのオプションに--prefixつけて対応してます。

Playbookを実行する

$ ansible-playbook -i local_hosts site.yaml

PLAY [servers] ****************************************************************

GATHERING FACTS ***************************************************************
ok: [192.168.33.10]

TASK: [get epel repo] *********************************************************
ok: [192.168.33.10]

... # 途中省略

TASK: [setup application] *****************************************************
changed: [192.168.33.10]

PLAY RECAP ********************************************************************
192.168.33.10              : ok=19   changed=9    unreachable=0    failed=0

できました!

$ vagrant sshして確認してみると

-bash-4.1$ cd beatbot/  # Hubotプロジェクトに移動して
-bash-4.1$ ./bin/hubot
Hubot> [Tue Jun 03 2014 00:18:15 GMT+0900 (JST)] WARNING The HUBOT_AUTH_ADMIN environment variable not set
[Tue Jun 03 2014 00:18:16 GMT+0900 (JST)] INFO Initializing new data for brain

Hubot>  # 起動できた

おわりに

Hubotの環境構築が終わったので次からはスクリプトを書いて賢くしていく予定。

ビート君(Bot)のキャラ設定も考えないと。