ansibleってそれおいしいの？

# chefより敷居が低いProvisioningツール
Shellshockやらやらここのとこ話題が多い脆弱性こまるわ。で、vmを沢山立ち上げているのはいいのだけど脆弱性チェックやupdateするとか面倒なんですよね（自動updateするほど終日運用じゃないので）。
そんなわけで、chef使うのも面倒だし手軽にProvisioningできると話題のansibleをインストールし使ってみたので忘れないうちにメモ。 

## サーバ側の設定
Python 入っていればokです。あと ansible は、EPEL からインストールします。
最新版をインストールしたい場合は、[ここを参照](http://yteraoka.github.io/ansible-tutorial/)にするのがよいと思います。

```
# EPEL 有効化
$ sudo rpm -ivh http://ftp.riken.jp/Linux/fedora/epel/6/i386/epel-release-6-8.noarch.rpm

# Ansible インストール
$ sudo yum install ansible
```

## クライアント側の設定…Python 入っていればok
クライアント側に Python 入っていればokです、お手軽でしょ。
ただ ansibleサーバからsshでログインできるように[設定して](http://qiita.com/HamaTech/items/21bb9761f326c4d4aa65)おきます。

とりあえずsshコマンド使って疎通確認しておく
$ ssh vagrant@192.168.11.106 -i /home/vagrant/.ssh/id_rsa

# 若干はまった点
基本的にはすでに上記の設定でansibleを使うことができるのですがその前にハマった点をば

## No hosts matched
接続するホスト(ipだけでも可能）のファイルを指定していないため。

```
$ ansible 192.168.11.102 -m ping
No hosts matched
```

## FAILED: ssh
このエラーで2日も悩みました。vagrant環境が悪いのか？と。ssh のパスフェイズを指定していないだけというオチでした。'-k' オプションをつけるだけでok。
ちなみに '-vvv' オプションつければ細かい動作状況がわかる。

```
$ ansible -i hosts 192.168.11.102 -m ping -vvv
<192.168.11.102> ESTABLISH CONNECTION FOR USER: vagrant on PORT 22 TO 192.168.11.102
192.168.11.102 | FAILED => FAILED: ssh vagrant@192.168.11.102:22 : Private key file is encrypted
To connect as a different user, use -u <username>.
```

## ssh鍵ペアの秘密鍵を明示的に指定する場合

```
$ cat hosts
192.168.11.102 ansible_ssh_private_key_file=/home/vagrant/.ssh/ansible102 ansible_ssh_user=vagrant
192.168.11.104 ansible_ssh_private_key_file=/home/vagrant/.ssh/ansible104 ansible_ssh_user=vagrant
```

## root権限必要なコマンドを実行して怒られるとき
[rootである必要がある](http://www.1x1.jp/blog/2014/09/yum-update-with-ansible.html)とな。'--sudo' オプションをつけるだけでok。

```
$ ansible -i hosts 192.168.11.106 -i hosts -m shell -a "yum -y update" -k
192.168.11.106 | FAILED | rc=1 >>
Loaded plugins: fastestmirror, versionlockYou need to be root to perform this command.
```

# とりあえず
コマンドラインから何でもできます。これがansibleのいいとこですね。

## bashのバージョンを確認
CentOSのみ、それ以外は "rpm -qa bash"でいけると思う。

```
$ ansible -i hosts 192.168.11.106 -i hosts --sudo -m shell -a "cat /etc/redhat-release" -k
SSH password: 
192.168.11.106 | success | rc=0 >>
CentOS release 6.6 (Final)
```

## yum update

```
$ ansible -i hosts 192.168.11.106 -i hosts --sudo -m shell -a "yum -y update" -k
```

# より高度な使用方法
chef で言うとこのレシピと同じように Playbook という yml(YAML)に動作を書くことができます。

## Playbook
意外と親しみやすい構文だと思います。まあテンプレは沢山ありますが私が適当に作ったPlaybookを実行してみます。単にクライアント側の /tmp に自分のipアドレスのファイルをtouchして作るだけの簡単レシピｗ

```
$ cat test.yml
- hosts: all
  user: vagrant
  gather_facts: yes
  vars:
    user_name: vagrant
    dest_home_path: /home/{{user_name}}
  tasks:
    - name: run command and ignore the result
      command: /bin/echo {{ ansible_eth0["ipv4"]["address"] }}
      register: hello
      command: /bin/touch /tmp/{{ ansible_eth0["ipv4"]["address"] }}
    - debug: var=hello.stdout
      ignore_errors: True
```

実行してみる。
WARNING は、気にしないｗ

```
$ ansible-playbook -i hosts test.yml -k
 [WARNING]: The version of gmp you have installed has a known issue regarding
timing vulnerabilities when used with pycrypto. If possible, you should update
it (ie. yum update gmp).

SSH password: 

PLAY [all] ******************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [192.168.11.104]
ok: [192.168.11.106]
ok: [192.168.11.102]

TASK: [run command and ignore the result] ************************************* 
changed: [192.168.11.104]
changed: [192.168.11.102]
changed: [192.168.11.106]

TASK: [debug var=hello.stdout] ************************************************ 
ok: [192.168.11.106] => {
    "hello.stdout": ""
}
ok: [192.168.11.104] => {
    "hello.stdout": ""
}
ok: [192.168.11.102] => {
    "hello.stdout": ""
}

PLAY RECAP ******************************************************************** 
192.168.11.102             : ok=3    changed=1    unreachable=0    failed=0   
192.168.11.104             : ok=3    changed=1    unreachable=0    failed=0   
192.168.11.106             : ok=3    changed=1    unreachable=0    failed=0   
```

クライアント側の /tmpに ファイルができてればok。簡単でしょう？

# 参考になるサイト様

Ansible インストールとかとか
> [エージェントレスでシンプルな構成管理ツール「Ansible」入門](http://knowledge.sakura.ad.jp/tech/3124/)
> [Ansible覚え書き](http://qiita.com/ftakao2007/items/ea82a8c9405bf2f3a3d2)
> [Ansible Note](https://github.com/yteraoka/ansible-tutorial/wiki/ansible-note)
> [はじめてAnsibleを使う人が知っておきたい7つのモジュール](http://www.infiniteloop.co.jp/blog/2013/08/ansible/)
> [yteraoka/ansible-tutorial](https://github.com/yteraoka/ansible-tutorial)

tips
> [こんなときにはansible](http://qiita.com/akiko-pusu/items/b09c719ed188cadd09f5)
> [All Modules](http://docs.ansible.com/list_of_all_modules.html)
> [Ansible使ってVagrantのゲストOSの構成管理する【Playbook: jenkins, node.js】](http://yutapon.hatenablog.com/entry/2014/04/08/102836)