Ansible使ってVagrant上のCentOSにHubot入れる
GithubKaigiでHubotが結構フィーチャーされてたので触ってみました。
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を動かすためには
- Node.js
- Redis
- CoffeeScriptコンパイラ
があればいいようです。
これらの環境が整ったら、
$ 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してくるには実行ユーザのホームディレクトリに秘密鍵がないといけないのですが、ホスト側のsshとVagrantの設定を少し変えて対応しました。
こちらを参考にしました。
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)のキャラ設定も考えないと。