AnsibleでRuby2.1.2をソースコンパイルする

> 環境
Mac OSX 10.9.4
Ubuntu 12.04.4 LTS
Ansible 1.6.10

####今回すること
*ローカルのMacからAnsibleを利用して,
3台のUbuntuサーバーにRubyをソースコンパイルする。*

#####注意事項
Ansibleのインストール法や仕組みについては記しません。
あくまで今回の目的を達成できる必要最低限のレベルです。
※ 前提条件として3台のUbuntuサーバーにはssh接続できる状態です。

Ansibleの設定ファイル
---
必要なファイルは下記2つのみ

* *inventoryファイル* (ini形式の拡張版)  
今回は`/private/etc/ansible/hosts`
* *playbookファイル* (YAML形式)  
今回は`/private/etc/ansible/ruby_install.yml`

それぞれのファイルの内容
###hosts

<pre>
username@servername3
username@servername2
username@servername1
</pre>

###ruby_install.yml

<pre>
- hosts: all
  sudo: yes
  user: username
  vars:
    version: "ruby-2.1.2"
    ruby_url: "http://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.2.tar.gz"
    install_path: '/opt/rubies/2.1.2'
    src: '/opt/rubies'
  tasks:
    - name: build-essential install
      command: apt-get -y install build-essential automake git
    - name: pkg install
      apt: pkg={{ item }} state=installed
      with_items:
        - zlib1g-dev
        - libssl-dev
        - libreadline6-dev
        - libyaml-dev
        - libxml2-dev
        - libxslt-dev
        - libcurl4-openssl-dev
        - libmysqlclient-dev
        - rubygems
    - name: Ruby Download
      get_url: url={{ ruby_url }}
               dest={{ src }}/{{ version }}.tar.gz
    - name: Ruby File 解凍
      command: chdir={{ src }} tar xzf {{ version }}.tar.gz creates={{ src }}/{{ version }}
    - name: configure
      command: >
              ./configure
              --prefix={{ install_path }}
              chdir={{ src }}/{{ version }}
    - name: make
      command: make chdir={{ src }}/{{ version }}
    - name: make install
      command: make install chdir={{ src }}/{{ version }}
    - name: gem install rubygems-update
      command: bash -lc "{{ install_path }}/bin/gem install rubygems-update"
    - name: gem update --system
      command: bash -lc "{{ install_path }}/bin/gem update --system"
    - name: gem install bundler
      command: bash -lc "{{ install_path }}/bin/gem install bundler"
</pre>

実行コマンド
---

`% ansible-playbook -i /etc/ansible/hosts ruby_install.yml --ask-sudo-pass`

`--ask-sudo-pass`オプションでsudoのパスワード入力を求めるようにしている。
> ※Ubuntuでセッティングする場合は`/etc/ansible/hosts`を自動で読み込むらしい(未確認)のでinventoryファイルの指定は不要である。

成功した出力
---

<pre>
  1 sudo password:
  2 
  3 PLAY [all] ********************************************************************
  4 
  5 GATHERING FACTS ***************************************************************
  6 ok: [username@servername3]
  7 ok: [username@servername1]
  8 ok: [username@servername2]
  9 
 10 TASK: [build-essential install] ***********************************************
 11 changed: [username@servername2]
 12 changed: [username@servername3]
 13 changed: [username@servername1]
 14 
 15 TASK: [pkg install] ***********************************************************
 16 changed: [username@servername1] => (item=zlib1g-dev,libssl-dev,libreadline6-dev,libyaml-dev,libxml2-dev,libxslt-dev,libcurl4-openssl-dev,libmysqlclient-dev,rubygems)
 17 changed: [username@servername2] => (item=zlib1g-dev,libssl-dev,libreadline6-dev,libyaml-dev,libxml2-dev,libxslt-dev,libcurl4-openssl-dev,libmysqlclient-dev,rubygems)
 18 changed: [username@servername3] => (item=zlib1g-dev,libssl-dev,libreadline6-dev,libyaml-dev,libxml2-dev,libxslt-dev,libcurl4-openssl-dev,libmysqlclient-dev,rubygems)
 19 
 20 TASK: [Ruby Download] *********************************************************
 21 ok: [username@servername2]
 22 ok: [username@servername1]
 23 ok: [username@servername3]
 24 
 25 TASK: [Ruby File 解凍] **********************************************************
 26 skipping: [username@servername1]
 27 skipping: [username@servername2]
 28 skipping: [username@servername3]
 29 
 30 TASK: [configure] *************************************************************
 31 changed: [username@servername2]
 32 changed: [username@servername1]
 33 changed: [username@servername3]
 34 
 35 TASK: [make] ******************************************************************
 36 changed: [username@servername2]
 37 changed: [username@servername3]
 38 changed: [username@servername1]
 39 
 40 TASK: [make install] **********************************************************
 41 changed: [username@servername2]
 42 changed: [username@servername3]
 43 changed: [username@servername1]
 44 
 45 TASK: [gem install rubygems-update] *******************************************
 46 changed: [username@servername3]
 47 changed: [username@servername1]
 48 changed: [username@servername2]
 49 
 50 TASK: [gem update --system] ***************************************************
 51 changed: [username@servername3]
 52 changed: [username@servername1]
 53 changed: [username@servername2]
 54 
 55 TASK: [gem install bundler] ***************************************************
 56 changed: [username@servername1]
 57 changed: [username@servername2]
 58 changed: [username@servername3]
 59 
 60 PLAY RECAP ********************************************************************
 61 username@servername1                : ok=10   changed=8    unreachable=0    failed=0
 62 username@servername2                : ok=10   changed=8    unreachable=0    failed=0
 63 username@servername3                : ok=10   changed=8    unreachable=0    failed=0
</pre>

メモ
---
 Ansibleの冪等性はmoduleの単位で実現されている。冪等でないmoduleも存在するで注意が必要(mailとか)。  
 今回成功するまで、gemのインストールやアップデートでエラーが出ずAnsibleの実行が終了したときがあったのだが、実際にサーバーをみてみると行われていなかったので、どうやってエラーの表示をするのか、あるいはそれが判断できるように設計する必要がある。