Ansibleちょっとしたメモ

Advent Calendar初参加です。よろしくお願いします。
Ansibleを使い始めてほんの2ヶ月程度ですが、その中で得たちょっとしたことを自分のメモも兼ねて並べていきます。


# with_itemsに配列の変数を渡す

```XML:01.yml
- hosts: test_server

  vars:
    items:
      - "hello world!"
      - "I love cats"
      - "I love dogs"

  tasks:
    - name: "echo list item"
      command: echo {{item}}
      with_items: items
```

varsで変数を定義する時に、リストで定義します。with_itemsでvarsで宣言した変数を{{}}なしで指定します。(なんでこの場合は{{}}なしなのか・・・)
　

# あるタスクだけユーザをスイッチする
[remote_user]を使用すると、任意のユーザにswitchできます

```XML:02.yml
- hosts: test_server
  user: cat

  tasks:
    - name: "who am i (cat)"
      command: whoami

    - name: "who am i (dog)"
      remote_user: dog
      command: whoami
```
実行すると、以下のように結果になります

```
TASK: [who am i (cat)] ******************************************************** 
changed: [133.242.xx.xxx] => {"changed": true, "cmd": ["whoami"], "delta": "0:00:00.002457", "end": "2013-11-29 14:40:02.163557", "rc": 0, "start": "2013-11-29 14:40:02.161100", "stderr": "", "stdout": "cat"}

TASK: [who am i (dog)] ******************************************************** 
changed: [133.242.xx.xxx] => {"changed": true, "cmd": ["whoami"], "delta": "0:00:00.001640", "end": "2013-11-29 14:40:02.941760", "rc": 0, "start": "2013-11-29 14:40:02.940120", "stderr": "", "stdout": "dog"}
```
"stdout": "dog"が出力されています
　

# 複数行を一括で置換する

lineinfileだと1行づつしか置換できません。(たぶん)
commandでsedを実行すれば一度に置換することができます。

```XML:03.yml
- hosts: test_server
  vars:
    - file: "/root/dogs.txt"

  tasks:
    - name: "before"
      command: cat {{file}}

    - name: "replace dog to cat"
      command: sed -i "s/dog/cat/g" {{file}}

    - name: "after"
      command: cat {{file}}
```

```実行前
1.dog
2.dog
3.dog
4.dog
5.dog
```

```実行後
1.cat
2.cat
3.cat
4.cat
5.cat
```
　

# [Y/n]を聞いてくるスクリプトを実行する

expectコマンドを使いましょう。(ansible関係ない・・・)
インストールされていない場合は、yum等でインストールします。

`yum install expect`

例えば、以下のようなY/nを入力させるスクリプトがあった場合

```Bash:question.sh
#!/bin/sh

while read -p "Do you like cat?[y/n] " yn ; do
    case $yn in
        [Yy]* ) {
            echo "good!"
            exit
        };;
        [Nn]* ) {
            echo "fuxk!"
            exit
        };;
        * ) exit;;
    esac
done
```

question.shをexpectを使用して自動で実行するスクリプトを書きます。

```Bash:question_warpper.sh
#!/usr/bin/expect

spawn ./question.sh

expect "Do you like cat?"
send "y\n"

interact
```

あとは、question_warpper.shを実行するcommandを書けばOKです

```XML:04.yml
- hosts: test_server

  tasks:
    - name: "exec question"
      command: /root/question_warpper.sh
```
実行すると以下のような結果になります

```
TASK: [exec question] ********************************************************* 
changed: [133.242.xx.xxx] => {"changed": true, "cmd": ["/root/question_warpper.sh"], "delta": "0:00:00.006229", "end": "2013-11-29 14:41:37.051538", "rc": 0, "start": "2013-11-29 14:41:37.045309", "stderr": "", "stdout": "spawn ./question.sh\r\nDo you like cat?[y/n] y\r\ngood!"}
```
　

# OSのバージョン依って実行するタスクを切換える

まずはOSのバージョンや"ansible_"で始まる変数を取得します
`ansible -i develop.list xxx.xxx.xxx.xxx -m setup > vars.txt`
コマンドで取得した中にOSのバージョン等の変数があります

```
"ansible_distribution": "CentOS", 
        "ansible_distribution_release": "Final", 
        "ansible_distribution_version": "6.4", 
```
あとは[when]を使用して、タスクの実行条件を設定すればOKです

```XML:05.yml
- hosts: test_server

  tasks:
    - name: "CentOS 5"
      when: >
        ansible_distribution == 'CentOS'
        and ansible_distribution_version.split('.')[0]|int == 5
      command: echo "This is CentOS 6"

    - name: "CentOS 6"
      when: >
        ansible_distribution == 'CentOS'
        and ansible_distribution_version.split('.')[0]|int == 6
      command: echo "This is CentOS 6"
```
　

# userモジュールで設定するパスワードを生成する

userモジュールでユーザを作成してパスワードを設定する場合、予め暗号かしたものをモジュールの引数に設定する必要があります。
その為のコマンドが以下になります

`python -c 'import crypt; print crypt.crypt("設定するパスワード", "salt")'`

コマンドで出力された文字列をpasswordに設定すればOKです
　
___
　
_少しでもAnsible初心者の皆様のお役に立つことができれば、幸せでございます_