Ansible でファイルは撒きたい、でもサービスは開始したくない

Ansible で設定ファイルの配置は行いたいけれども、でもまだサービスは開始したくない、というとき。

- Ansible 2.1.1.0

## だめだった例

ロールにタグを指定し設定ファイルをコピーするタスクに別のタグを付けるだけで大丈夫だと考えました。

**local.yml**

```yaml
- hosts: localhost
  gather_facts: no
  roles:
    - { role: hoge, tags: hoge } # hoge ロールに hoge タグを付ける
```

**roles/hoge/tasks/main.yml**

```yaml
- name: hoge.conf
  copy: src=hoge.conf dest=/tmp
  notify: hoge restart
  tags: hoge_config # copy のタスクに hoge_config タグを付ける

- name: hoge started and enabled
  service: name=hoge state=started enabled=yes
```

**roles/hoge/handlers/main.yml**

```yaml
- name: hoge restart
  service: name=hoge state=restarted
```

`hoge` タグを指定して実行すれば全部実行されます。

```sh
ansible-playbook local.yml -t hoge
```

```
PLAY [localhost] ***************************************************************

TASK [hoge : hoge.conf] ********************************************************
changed: [localhost]

TASK [hoge : hoge started and enabled] *****************************************
changed: [localhost]

RUNNING HANDLER [hoge : hoge restart] ******************************************
changed: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=3    changed=3    unreachable=0    failed=0   
```

`hoge_config` タグを指定して実行すると・・・サービスの開始と有効化のタスクはスルーされましたが、リスタートのタスクが実行されてしまいました。

```sh
ansible-playbook local.yml -t hoge_config
```

```
PLAY [localhost] ***************************************************************

TASK [hoge : hoge.conf] ********************************************************
changed: [localhost]

RUNNING HANDLER [hoge : hoge restart] ******************************************
changed: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=2    unreachable=0    failed=0   
```

リスタートのタスクにもロールで指定している `hoge` タグが暗黙についていると思ったのでコピーのタスクから notify されてもスルーされると思ってたんですけどそんなことありませんでした。

次のように明示的にタグを指定して `--skip-tags=hoge_restart` しても効果ないようでした。

```yaml
- name: hoge restart
  service: name=hoge state=restarted
  tags: hoge_restart
```

どうやら handler にはタグは聞かないようです。

## うまくいった例

handler に when なら効くので、次のようにしました。

**roles/hoge/tasks/main.yml**

```yaml
- name: hoge.conf
  copy: src=hoge.conf dest=/tmp
  notify: hoge restart
  tags: hoge_config # copy のタスクに hoge_config タグを付ける

- name: hoge started and enabled
  service: name=hoge state=started enabled=yes
  register: hoge_service # service のタスクの結果を hoge_service に入れる
```

**roles/hoge/handlers/main.yml**

```yaml
- name: hoge restart
  service: name=hoge state=restarted
  when: hoge_service is defined  # hoge_service を条件にする
```

`hoge_config` タグを指定して実行するとコピーのタスクだけ実行され、サービスの開始のタスクはスルーされるので `hoge_service` は未定義になります。ので、リスタートの handler はスキップされます。

```sh
ansible-playbook local.yml -t hoge_config
```

```
PLAY [localhost] ***************************************************************

TASK [hoge : hoge.conf] ********************************************************
changed: [localhost]

RUNNING HANDLER [hoge : hoge restart] ******************************************
skipping: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=1    changed=1    unreachable=0    failed=0   
```