AnsibleをBest Practicesのディレクトリ構成にする

## ディレクトリを作成

ディレクトリ構成は[Best Practices](http://docs.ansible.com/playbooks_best_practices.html)をそのまま利用。
今回は分かりやすく、全体でNTPdを、webサーバーでNginxをセットアップする。

```
playbooks
├── development
├── others.yml
├── production
├── roles
│   ├── common
│   │   ├── handlers
│   │   │   └── main.yml
│   │   ├── tasks
│   │   │   └── main.yml
│   │   └── templates
│   │       └── ntp.conf.j2
│   └── nginx
│       ├── handlers
│       │   └── main.yml
│       ├── tasks
│       │   └── main.yml
│       └── templates
│           └── default.j2
├── site.yml
├── staging
└── webservers.yml
```


## Vagrantfileの設定

実行するサーバーは楽なのでVagrantで用意。
boxなどの設定は省略。

```ruby:Vagrantfile
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

  # ...

  config.vm.define "host1" do |m|
    # ...
  end

  config.vm.define "host2" do |m|
    # ...
  end

  config.vm.provision "ansible" do |ansible|
    ansible.playbook = "playbooks/site.yml"
    ansible.groups = {
      "webservers" => ["host1"]
      "others" => ["host2"]
    }
  end

end
```


## グループ毎のPlaybookの設定

```ruby:site.yml
- include: webservers.yml
- include: others.yml
```

```ruby:webservers.yml
- hosts: webservers
  sudo: yes
  roles:
    - common
    - nginx
```

```ruby:others.yml
- hosts: others
  sudo: yes
  roles:
    - common
```

site.ymlを読ませるだけで、webserversグループとothersグループとで処理を分けてくれるようになる。

## 全体用のタスク

全体へのタスクは_roles/common/tasks/main.yml_に書く。

```ruby:roles/common/tasks/main.yml
- name: Install NTP
  apt: name=ntp state=latest
- name: Configure NTP
  template: src=ntp.conf.j2 dest/etc/ntp.conf
  notify:
    - restart ntpd
- name: Be sure NTPd is running and enabled
  service: name=ntp state=started enabled=yes
```

このタスクで利用されるhandlerやtemplateは同階層の_handlers_と_templates_に置く。

```roles/common/templates/ntp.conf.j2
driftfile /var/lib/ntp/ntp.drift

statistics loopstats peerstats clockstats
filegen loopstats file loopsstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable

server ntp.nict.jp

restrict -4 default kod notrap nomodify nopeer noquery
restrict -6 default kod notrap nomodify nopeer noquery

restrict 127.0.0.1
restrict ::1
```

```ruby:roles/common/handlers/main.yml
- name: restart ntpd
  service: name=ntp state=restarted
```


## webserversへのタスク

webserversではcommonロールとnginxロールが与えられているので、全体用のタスク+nginxタスクを実行することになる。

```ruby:roles/nginx/tasks/main.yml
- name: Install nginx
  apt: name=nginx state=latest
- name: Enable default configuration
  file: src=/etc/nginx/sites-available/default dest=/etc/nginx/sites-enabled/default state=link
- name: Configure nginx
  template: src=default.j2 dest=/etc/nginx/sites-available/default
  notify:
    - restart nginx
```

```roles/nginx/templates/default.j2
server {
    listen 80 default_server;
    server_name local.localdomain;

    root /usr/share/nginx/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}
```

```ruby:roles/nginx/handlers/main.yml
- name: restart nginx
  service: name=nginx state=restarted
```


## 実行

### Vagrantの場合

Vagrantでの個人開発環境の場合は、vagrantコマンドにprovisionコマンドが用意されているので、それを使う。

```bash
vagrant provision
```

### ansible-playbookの場合

本番サーバーやテストサーバーではこちらを用いることになる。

```bash
ansible-playbook -u USER --private-key=/path/to/key -i production playbooks/site.yml
```

インベントリファイルは適用したい環境を選択する。
上記の例では本番環境用。