Ansible入門 その２ Playbook

この記事は[Ansible入門 その1 インストール〜コマンド実行](https://qiita.com/newnakashima/items/7d35086735944db9df5b)の続きです。

前回はansibleがリモートマシン（というかvagrant環境）に接続できるところまでやりました。

今回はPlaybookを使ってリモートマシン側で色々と自動的にインストールしてくれたりする部分をやっていきたいと思います。

##　Playbookの書き方

PlaybookはYAMLファイルです。YAMLについてよく知らないという方は、[こちらの記事](https://qiita.com/Yama-to/items/587544993fb62610528a)などをご覧になると良いと思います。XMLとかJSONみたいなやつです。

今回はyumでvimとgitをインストールしたいと思ったのでそのやり方を考えてみます。

### 1.vimとgitをインストールする

[こちらの記事](https://qiita.com/chroju/items/3738d2085fa90ab455e7)を参考にさせていただき以下のような``playbook.yml``ファイルを作成しました。

```yaml
- hosts: all
  become: yes
  user: vagrant
  tasks:
      - name: install via yum
        yum: name={{ item }} state=installed
        with_items:
            - vim
            - git
```

そして、``playbook.yml``ファイルのあるディレクトリで

```sh
$ ansible-playbook playbook.yml
```

とコマンドを打つとvimとgitがインストールされるはずです。

``ansible-playbook``コマンドが登場しましたが、ansibleコマンドとの違いは[こちらの記事](https://qiita.com/YumaInaura/items/43221f52ae7d7059cc21)にまとまっています。ansibleを使う場合はplaybookを使うことが多分ほとんどだと思います。

hostsにホスト名、becomeにsudoするかどうか、userにユーザー名を設定します。
tasksにはansibleでリモートマシンに実行させたいことを書いていきます。
tasks内のnameには好きな名前つけていいみたいです。

### 2.使用可能なオプションとか文法を確認する

さっきのplaybookの中に、``yum: name={{ item }} state=installed``という箇所がありました。
このnameやstateというオプションは何なのかというと、yumの場合は[ここ](http://docs.ansible.com/ansible/latest/yum_module.html)にまとまっています。

ここに出てくる``yum``とかの実行するコマンドに相当するやつはモジュールと呼ぶらしいのですが、どういうモジュールが用意されているかは[このページ](http://docs.ansible.com/ansible/latest/modules_by_category.html)に一覧があります。

``{{ item }}``という文法が気になりますが、これはその次の行の``with_items:``という配列の要素が突っ込まれるということみたいです。

``{{  }}``で囲んであるのは変数で、YAML内で宣言した値を使えるみたいです。

```yaml
- hosts: all
  become: yes
  user: vagrant
  vars: 
    hoge: !unsafe 'fuga'
  tasks:
    - name: debug test
      debug: msg="{{ hoge }}"
```

コマンドラインから変数を渡すこともできます。
```$ ansible-playbook playbook.yml --extra-vars "hoge=fuga"```

これの結果は以下のようになります。

```sh
PLAY [all] *******************************************************************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************************************************************
ok: [vagrant@192.168.33.10]

TASK [debug test] ************************************************************************************************************************************************************
ok: [vagrant@192.168.33.10] => {
    "msg": "fuga"
}

PLAY RECAP *******************************************************************************************************************************************************************
vagrant@192.168.33.10      : ok=2    changed=0    unreachable=0    failed=0
```

変数については[こちら](http://docs.ansible.com/ansible/latest/playbooks_variables.html)にドキュメントがあります。

``with_items: ``はループを扱える文法です。

```yaml
- hosts: all
  become: yes
  user: vagrant
  tasks:
    - name: debug test
      debug: msg={{ item }}
      with_items:
          - hoge
          - fuga
          - piyo
```

これの結果は以下のようになります。

```sh
$ ansible-playbook loop.yml

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

TASK [Gathering Facts] *******************************************************************************************************************************************************
ok: [vagrant@192.168.33.10]

TASK [debug test] ************************************************************************************************************************************************************
ok: [vagrant@192.168.33.10] => (item=hoge) => {
    "changed": false,
    "item": "hoge",
    "msg": "hoge"
}
ok: [vagrant@192.168.33.10] => (item=fuga) => {
    "changed": false,
    "item": "fuga",
    "msg": "fuga"
}
ok: [vagrant@192.168.33.10] => (item=piyo) => {
    "changed": false,
    "item": "piyo",
    "msg": "piyo"
}

PLAY RECAP *******************************************************************************************************************************************************************
vagrant@192.168.33.10      : ok=2    changed=0    unreachable=0    failed=0
```

連想配列も使えます。

```yaml
- hosts: all
  become: yes
  user: vagrant
  tasks:
    - name: debug test
      debug: "msg=hoge: {{ item.hoge }}, fuga: {{ item.fuga }}, piyo: {{ item.piyo }}"
      with_items:
          - { hoge: 'foo',    fuga: 'bar',    piyo: 'baz'   }
          - { hoge: 'qux',    fuga: 'quux',   piyo: 'corge' }
          - { hoge: 'grault', fuga: 'garply', piyo: 'waldo' }
```

結果

```sh
PLAY [all] ***********************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************
ok: [vagrant@192.168.33.10]

TASK [debug test] ****************************************************************************************************
ok: [vagrant@192.168.33.10] => (item={u'fuga': u'bar', u'piyo': u'baz', u'hoge': u'foo'}) => {
    "changed": false,
    "item": {
        "fuga": "bar",
        "hoge": "foo",
        "piyo": "baz"
    },
    "msg": "hoge:"
}
ok: [vagrant@192.168.33.10] => (item={u'fuga': u'quux', u'piyo': u'corge', u'hoge': u'qux'}) => {
    "changed": false,
    "item": {
        "fuga": "quux",
        "hoge": "qux",
        "piyo": "corge"
    },
    "msg": "hoge:"
}
ok: [vagrant@192.168.33.10] => (item={u'fuga': u'garply', u'piyo': u'waldo', u'hoge': u'grault'}) => {
    "changed": false,
    "item": {
        "fuga": "garply",
        "hoge": "grault",
        "piyo": "waldo"
    },
    "msg": "hoge:"
}

PLAY RECAP ***********************************************************************************************************
vagrant@192.168.33.10      : ok=2    changed=0    unreachable=0    failed=0
```

ついでなので条件分岐もみてみます。

例文

```yaml

- hosts: all
  become: yes
  user: vagrant
  tasks:
      - name: condition
        debug:
            msg: "{{ item.message }}"
        when: (item.print == 'true')
        with_items: 
            - { message: 'hello', print: 'true'  }
            - { message: 'world', print: 'false' }
```

結果

```sh

$ ansible-playbook condition.yml

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

TASK [Gathering Facts] **************************************************************************************************************************************
ok: [vagrant@192.168.33.10]

TASK [condition] ********************************************************************************************************************************************
ok: [vagrant@192.168.33.10] => (item={u'print': u'true', u'message': u'hello'}) => {
    "changed": false,
    "item": {
        "message": "hello",
        "print": "true"
    },
    "msg": "hello"
}
skipping: [vagrant@192.168.33.10] => (item={u'print': u'false', u'message': u'world'})

PLAY RECAP **************************************************************************************************************************************************
vagrant@192.168.33.10      : ok=2    changed=0    unreachable=0    failed=0
```

item.printが'true'のときだけメッセージが出力されているのがわかります。

つまり、taskの中のwhenの値がyesかnoかによって実行させるかさせないかを決めることができます。

サーバーの状態によってコマンドを実行したりしなかったりできそうです。

その３に続く。。はず。。