Ansibleのmakeモジュールやunarchiveモジュールを使ってGitをソースからインストールしてみる

## ■ はじめに
+ **Ansibleとは**
    Ansibleについて簡単に紹介しておきます。
    - エージェントレスでサーバ構築を自動化してくれるツールです。
    - sshdが動作しているマシンにSSHで接続し環境を構築してくれます。
    - 設定ファイルはYAMLで書きます。プログラムの知識（Ruby、Python、etc.）は不要です。
    - 数台～数十台規模のサーバ構築だったらchef, puppetよりも簡単です。
    
    　  
+ **makeモジュール**
makeモジュールは、Ansible ver.2.1から追加された新機能です。
　[make - Run targets in a Makefile](https://docs.ansible.com/ansible/make_module.html)
    　  
+ **環境の準備**
以前の記事を参照してください。
　[Ansible 最初の一歩](http://qiita.com/olympic2020/items/9c21d53066c9c6e5357f)
Gitを手動でソースからインストールする方法は下記の記事を参照してください。
　[最新のGit（ver.2.9）をソースからインストールする](http://qiita.com/olympic2020/items/97c28dfd3a3806f2bc0d)

# ■ GitをソースからインストールするPlayBook
+ バージョンを指定できるようにしました。
+ インストールする場所を指定できるようにしました。
+ 既に同じバージョンのGitがインストールされている場合はタスクをスキップします。
+ Ansible ver.2.1の新機能、makeモジュールを利用してみました。

```playbook.yml
---
- hosts: all
  remote_user: ec2-user
  become: true
  vars:
    version: 2.9.0
    prefix_dir: /usr/local
    src_dir: "{{ prefix_dir }}/src"
    bin_dir: "{{ prefix_dir }}/bin"
  tasks:
    - name: original git exist check
      stat: path={{ bin_dir }}/git
      register: exist_git

    - debug: msg="git not installed."
      when: exist_git.stat.exists == false

    - name: original git version check
      command: "{{ bin_dir }}/git --version warn=false"
      register: org_version
      changed_when: false
      when: exist_git.stat.exists == true

    - name: install dependences
      yum: name={{ item }}
      with_items:
        - curl-devel
        - expat-devel
        - gettext-devel
        - openssl-devel
        - zlib-devel
        - gcc
        - perl-ExtUtils-MakeMaker
      when: (exist_git.stat.exists == false) or
            (exist_git.stat.exists == true and org_version.stdout != "git version {{ version }}")

    - name: make download dir
      file: path={{ src_dir }} state=directory owner=root group=root mode=755
      when: (exist_git.stat.exists == false) or
            (exist_git.stat.exists == true and org_version.stdout != "git version {{ version }}")

    - name: download git version {{ version }}
      unarchive:
        src: https://www.kernel.org/pub/software/scm/git/git-{{ version }}.tar.gz
        dest: "{{ src_dir }}"
        copy: no
      when: (exist_git.stat.exists == false) or
            (exist_git.stat.exists == true and org_version.stdout != "git version {{ version }}")

    - name: make all
      make:
        chdir: "{{ src_dir }}/git-{{ version }}"
        target: all
        params:
          prefix: "{{ prefix_dir }}"
      when: (exist_git.stat.exists == false) or
            (exist_git.stat.exists == true and org_version.stdout != "git version {{ version }}")

    - name: make install
      make:
        chdir: "{{ src_dir }}/git-{{ version }}"
        target: install
        params:
          prefix: "{{ prefix_dir }}"
      when: (exist_git.stat.exists == false) or
            (exist_git.stat.exists == true and org_version.stdout != "git version {{ version }}")
```

実行は以下になります。

```bash
$ ansible-playbook playbook.yml
```

### 備考
+ `command`モジュールで`git --version`していますが、Ansibleのデフォルトの動作では、`git`モジュールを利用するように警告されます。Ansibleの`git`モジュールには、executableのバージョンを取得するパラメータがありません。そこで、今のところは`command`モジュールを利用してバージョンを取得し、`warn=false`を指定して`git`モジュールの利用を促す警告を消しています。
Source Control Modules - git（[リンク](http://docs.ansible.com/ansible/git_module.html)）

+ `when`の同じ条件判断の繰り返し部分は、`set_fact`モジュールを使って変数に格納すればよりスマートです。

+ `become`とPATHの取り扱いについては、以下の記事を参考にしてください。
　[Ansibleのenvironmentを利用して「sudo su -」相当のPATHを設定する](http://qiita.com/olympic2020/items/a373372cb49d808c5237)


# ■ makeモジュールとchanged について
Ansibleのmakeモジュールは、そのまま実行すると毎回`chenged`になってしまいます。
PlayBookを最初に実行したときは`changed`になってほしいですが、同じPlayBookを再実行したときは`changed`ではなく`ok`になってほしいところです。
とはいえ、`changed_when: False`を指定しまうと、初回実行時に変更が加わっているのに`ok`になってしまうので`changed_when: False`の指定も避けたいところです。
そこで、今回は、`register`と`when`を組み合わせたバージョンチェック機能を入れてみました。

# ■ unarchiveモジュールとhttpsの組み合わせについて
`unarchive`と`https`の組み合わせが曲者でした。
Amazon Linuxでは問題なく動作していましたが、プロキシが認証する環境ではプロキシを設定しても動作しませんでした。おそらく、原因はSSL証明書を無効にする指定をしていないから。
`unarchive`モジュールには、`validate_certs`オプションがあり、`validate_crets=no`を指定すればOKなのですが、このオプションは、Ansible ver.2.2以降でないとサポートされていません。
Ansible ver.2.1以前の環境では、`get_url`と`https`と`validate_crets=no`の組み合わせでダウンロードする必要がありました。

# ■ おわりに
今回は、Gitをソースからインストールしてみましたが、rpmで公開されていないパッケージをソースからインストールする場合は、このPlayBookを応用できそうです。

それでは。