LoginSignup
6
6

More than 5 years have passed since last update.

Ansible の synchronize でローカルで削除したファイルを削除

Posted at

Apache の /etc/httpd/conf.d/*.conf のような、所定の形式の名前でファイルを置いておけば読まれるようになる設定ファイルを対象サーバにコピーしたい場合、copy モジュールでのディレクトリコピーや with_fileglob との組み合わせが便利です。

例えば次のようなディレクトリ構成で、

ansible.cfg
hosts
httpd.yml
files/
  etc/
    httpd/
      conf.d/
        aaa.conf
        bbb.conf

次の Playbook を、

---
- hosts: all
  sudo: yes
  tasks:
    - copy: src={{ item }} dest=/etc/httpd/conf.d/
      with_fileglob:
        - files/etc/httpd/conf.d/*.conf
      notify:
        - httpd check
        - httpd reload

  handlers:
    - name: httpd check
      shell: httpd -t

    - name: httpd reload
      service: name=httpd state=reloaded

実行すると、

$ ansible-playbook httpd.yml

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

TASK: [copy src={{ item }} dest=/etc/httpd/conf.d/] ***************************
changed: [192.0.2.123] => (item=/path/to/ansible/files/etc/httpd/conf.d/aaa.conf)
changed: [192.0.2.123] => (item=/path/to/ansible/files/etc/httpd/conf.d/bbb.conf)

NOTIFIED: [httpd check] *******************************************************
changed: [192.0.2.123]

NOTIFIED: [httpd reload] ******************************************************
changed: [192.0.2.123]

PLAY RECAP ********************************************************************
192.0.2.123              : ok=3    changed=3    unreachable=0    failed=0

対象サーバに conf.d の中身がコピーされます。

$ ls /etc/httpd/conf.d/
aaa.conf  bbb.conf

with_fileglob を使わなくても src でディレクトリを指定すれば大体同じことができます。

---
- hosts: all
  sudo: yes
  tasks:
    - copy: src=files/etc/httpd/conf.d/ dest=/etc/httpd/conf.d/
      notify:
        - httpd check
        - httpd reload

  handlers:
    - name: httpd check
      shell: httpd -t

    - name: httpd reload
      service: name=httpd state=reloaded

ただ、この方法だとどのファイルに変更があったかがわからないのであまり使いません。

$ ansible-playbook httpd.yml

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

TASK: [copy src=files/etc/httpd/conf.d/ dest=/etc/httpd/conf.d/] ******************
changed: [192.0.2.123]

NOTIFIED: [httpd check] *******************************************************
changed: [192.0.2.123]

NOTIFIED: [httpd reload] ******************************************************
changed: [192.0.2.123]

PLAY RECAP ********************************************************************
192.0.2.123              : ok=3    changed=3    unreachable=0    failed=0

とても便利な copy モジュールですが、ローカルで削除したファイルを対象サーバでも自動的に削除したりすることはできません。

例えば、bbb.conf を削除したとして、

ansible.cfg
hosts
httpd.yml
files/
  etc/
    httpd/
      conf.d/
        aaa.conf

Playbook を実行しても削除はされません。

$ ansible-playbook httpd.yml

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

TASK: [copy src={{ item }} dest=/etc/httpd/conf.d/] ***************************
ok: [192.0.2.123] => (item=/path/to/ansible/files/etc/httpd/conf.d/aaa.conf)

PLAY RECAP ********************************************************************
192.0.2.123              : ok=1    changed=0    unreachable=0    failed=0

この状況で bbb.conf を対象サーバから削除したければ file モジュールで明示的に指定する必要があります。

---
- hosts: all
  sudo: yes
  tasks:
    - copy: src={{ item }} dest=/etc/httpd/conf.d/
      with_fileglob:
        - files/etc/httpd/conf.d/*.conf
      notify:
        - httpd check
        - httpd reload

    - file: path={{ item }} state=absent
      with_items:
        - /etc/httpd/conf.d/bbb.conf
      notify:
        - httpd check
        - httpd reload

  handlers:
    - name: httpd check
      shell: httpd -t

    - name: httpd reload
      service: name=httpd state=reloaded
$ ansible-playbook httpd.yml

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

TASK: [copy src={{ item }} dest=/etc/httpd/conf.d/] ***************************
ok: [192.0.2.123] => (item=/path/to/ansible/files/etc/httpd/conf.d/aaa.conf)

TASK: [file path={{ item }} state=absent] *************************************
changed: [192.0.2.123] => (item=/etc/httpd/conf.d/bbb.conf)

NOTIFIED: [httpd check] *******************************************************
changed: [192.0.2.123]

NOTIFIED: [httpd reload] ******************************************************
changed: [192.0.2.123]

PLAY RECAP ********************************************************************
192.0.2.123              : ok=4    changed=3    unreachable=0    failed=0

さすがにこれだとめんどくさいしモレもありそうなので、synchronize モジュールを使ってローカルから削除されたファイルは対象サーバでも自動的に削除されるようにしました。

synchronize でやりたいことはファイルの削除だけなので、余計なことが行われないように archive: norsync_opts: [ --ignore-existing ] を指定しています。

---
- hosts: all
  sudo: yes
  tasks:
    - copy: src={{ item }} dest=/etc/httpd/conf.d/
      with_fileglob:
        - files/etc/httpd/conf.d/*.conf
      notify:
        - httpd check
        - httpd reload

    - synchronize:
        src: files/etc/httpd/conf.d/
        dest: /etc/httpd/conf.d/
        archive: no
        delete: yes
        dirs: yes
        rsync_opts: [ --ignore-existing ]
      notify:
        - httpd check
        - httpd reload

  handlers:
    - name: httpd check
      shell: httpd -t

    - name: httpd reload
      service: name=httpd state=reloaded
$ ansible-playbook httpd.yml

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

TASK: [copy src={{ item }} dest=/etc/httpd/conf.d/] ***************************
ok: [192.0.2.123] => (item=/path/to/ansible/files/etc/httpd/conf.d/aaa.conf)

TASK: [synchronize ] **********************************************************
changed: [192.0.2.123 -> 127.0.0.1]

NOTIFIED: [httpd check] *******************************************************
changed: [192.0.2.123]

NOTIFIED: [httpd reload] ******************************************************
changed: [192.0.2.123]

PLAY RECAP ********************************************************************
192.0.2.123              : ok=4    changed=3    unreachable=0    failed=0

対象サーバで確認してみると、bbb.conf が削除されていることがわかります。

$ ls /etc/httpd/conf.d/
aaa.conf

copy と synchronize を併用する理由

copy を使わずに synchronize だけで設定ファイルをコピー&削除することも可能です。

が、それだと、

  • どのファイルに変更があったか
  • --check --diff で差分の事前確認

ができないので、併用するようにしてみました(対象サーバの台数が多くなるとそんなのいちいち見ていられないのでしょうけど)。

6
6
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6