Ansible 素人の私が期日までにどれだけ使えるようになったか


# 概要
自分がまだ触ったことないツール類の Advent Calendar を探していたら偶然にも Ansible Advent Calendar 2014 を見つけました。
インフラエンジニアとして触っておきたいと思いながら放置していたのでいい機会だと思って触ってみます。

# Ansible とは
* Ansible とは Python で記述された構成管理ツール
* chef, puppet 等と同じ

ふむふむ。イメージ湧いた。

# Ansible の特徴
色んな記事を読んで皆様の声を集めてきました。

* シンプルなセットアップ
* 特に何もしなくても早くて並列処理可能
* sshd だけあれば動く
* モジュールの作成に言語の縛りはない
* api がある
* 一般ユーザでも使える
* 設定管理が簡単

などなど調べていたら [ansible - github] (https://github.com/ansible/ansible) に特徴が書いてありました。

そしてさらに Ansible Advent Calendar 2014 の初日の記事に丁寧な説明が！

* [今年1年間でAnsible界隈ではどのような変化が起こったのか。] (http://qiita.com/volanja/items/2ffa1599fc9a1fae39a1)
	* 歓喜！

ともあれ、大体わかった。

# Ansible の基本用語
大きく分けて2つの用語があることがわかった。
## モジュール
処理の最小単位で ansible コマンドや Playbook のタスクで指定されたモジュールがサーバに転送されてサーバ上で、実行される。

## Playbook
Playbook は Ansible のモジュールを使用した処理の組合せにより対象サーバの構成を記述したもの。

把握しました。

# Ansible インストール
## Mac
どうやら Mac だと brew で提供されているみたい。

```
$ brew install ansible
$ ansible --version
ansible 1.8.2
```
よし、良さそうだ。

## CentOS6.5
そもそも python2.7 が入っていなかった。

```
$ sudo yum install bzip2-devel sqlite-devel
$ cd /var/tmp
$ git clone https://github.com/tagomoris/xbuild.git
$ sudo xbuild/python-install 2.7.6 /opt/python-2.7
$ sudo /opt/python-2.7/bin/pip install ansible
$ echo 'PATH=/opt/python-2.7/bin:$PATH' >> ~/.bashrc
```

ansible 1.8.2 が入りました。

# Ansible を使ってみる
さて、使ってみると言っても何からはじめてみよう。
おや、偶然にも開発環境に2台のマシンがあるじゃないか。
まずは2台のマシンの同時オペレーションをやってみよう。

## network 環境
踏み台を経由しているとかはない。

```
Local Mac <--> 開発環境マシン 
```

という構成。


## Ansible 動かすよ！
えーと。わからない。調べよう。
やりたいことは2台同時オペレーション。
```cat /etc/redhat-release``` でも叩ければ良しとしよう。

### モジュール編

とりあえず調べてみた。ping モジュールってのがあるらしい。
使ってみよう。

\* ユーザ名をそのまま貼るとアレなんで全部　root で書かせてもらいます。あしからず。汗。

まず hosts ファイルを作成します。操作したいサーバの一覧表です。

```hosts
[servers]
10.29.1.111
10.29.1.128
```
こんな感じ。[servers] は何でも大丈夫のようなので管理しやすい名前が良いと思います。
では、まずこの中の1台に対して操作してみよう。

```
$ ansible -u root -i hosts 10.29.1.111 -m ping --ask-pass
SSH password:
10.29.1.111 | success >> {
    "changed": false,
    "ping": "pong"
}
```
pong って返ってきたし良さそう。とりあえず動かすという目的は達成した。
鍵認証だったらもっと楽なんだろうなぁという印象。 

じゃあ次は2台ともにやってみよう。

```
$ ansible -u root -i hosts servers -m ping --ask-pass
SSH password:
10.29.1.128 | success >> {
    "changed": false,
    "ping": "pong"
}

10.29.1.111 | success >> {
    "changed": false,
    "ping": "pong"
}
```
[servers] と指定してやればそこに書かれているホスト全てが対象になるみたい。楽だねー。

では、目標である ```cat /etc/redhat-release``` を叩こう。

shell を実行させて結果を得たい場合は ```-m shell -a "hogehoge"``` で出来るみたい。
やってみよう。

```
$ ansible -u root -i hosts servers -m shell -a "cat /etc/redhat-release" --ask-pass
SSH password:
10.29.1.128 | success | rc=0 >>
CentOS Linux release 7.0.1406 (Core)

10.29.1.111 | success | rc=0 >>
CentOS Linux release 7.0.1406 (Core)
```
できた。あれ、目的達成してしまった。どうしよう。
とりあえずモジュールについては下記を参考にしておけば良さそうです。

* [About Modules] (http://docs.ansible.com/modules.html)
* [Module Index] (http://docs.ansible.com/modules_by_category.html)

### Playbook編
さすがにこれだけでは味気ないので Playbook も触ってみたいと思います。

free -m を叩いてまわる Playbook を作ってみます。

```
ansible -u root -i hosts servers -m shell -a "free -m" --ask-pass
```

で達成できるじゃんとか言わない。

あえて Playbook を使うのです。覚えるために。

・・・。

できた。

```playbook.yml
$ cat playbook.yml
- hosts: servers
  user: root
  gather_facts: no
  tasks:
    - shell: free -m
      register: output
    - debug: var=output.stdout_lines
```

結果は↓

```
$ ansible-playbook playbook.yml -i hosts --ask-pass
SSH password:

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

TASK: [shell free -m] *********************************************************
changed: [10.29.1.111]
changed: [10.29.1.128]

TASK: [debug var=output.stdout_lines] *****************************************
ok: [10.29.1.128] => {
    "output.stdout_lines": [
        "             total       used       free     shared    buffers     cached",
        "Mem:         32006       1186      30820        344          0        268",
        "-/+ buffers/cache:        917      31089",
        "Swap:         8191          0       8191"
    ]
}
ok: [10.29.1.111] => {
    "output.stdout_lines": [
        "             total       used       free     shared    buffers     cached",
        "Mem:         15879       6487       9392         48          0       2217",
        "-/+ buffers/cache:       4269      11610",
        "Swap:         8191          0       8191"
    ]
}

PLAY RECAP ********************************************************************
10.29.1.111                : ok=2    changed=1    unreachable=0    failed=0
10.29.1.128                : ok=2    changed=1    unreachable=0    failed=0
```

```- debug: var=output.stdout_lines``` これを書いとかないといい感じに出力してくれないみたいですね。

ということで、Playbook も使うことができた。これで終わり。でいいのかな。
いいよね。うん。いいよ。いいはずだ。

僕は疲れたよパトラッシュ。

下記ページはとりあえずさらっと目を通しておくと役に立つかも。

* [Playbooks] (http://docs.ansible.com/playbooks.html)


# さいごに
結局触ったのは初歩の初歩まででした。動いた時点である程度の満足感を得てしまったのがよくなかったです。Playbook を使えばかなり色んなことができるなぁという印象を受けました。それに伴い学習コスト上がってくるのでそこは天秤って感じですかね。この手のツールは1つは使えるようになっておくといいかも。というのが個人的な見解です。

もう1つは Ansible 以前より思っていたことですが自動化に落としこむ箇所を間違えたら逆に事故の元だなということですね。楽だぜ！というところに盲目的になりすぎてしまっては本末転倒だなぁと。

簡単なオペレーションやセットアップには十分簡単に使えるのでこれからいくつかのお仕事を効率化していけたらなぁという感じ。

Ansible アドベントカレンダーの皆様、本当にありがとうございました。
情報が多かった分とてもやりやすかったです！

(ほんと触っただけでしたね...)
(実働4~5時間...サボり過ぎとか言わない)