Ansibleで複数ホストのファイル収集

Ansibleにて複数ホストのファイルを収集するPlaybookを作成します。
環境はCentOS6.5/ansible 1.6.2です。

ansible1.6.2及び最新のansible1.6.6のfetchモジュールではディレクトリやファイルのワイルドカード指定のfetchが行えません。
ドキュメントに"Recursive fetching may be supported in a later release.”と記載されているため、予定はされているようです。

それ以外にrsyncモジュールを使えばディレクトリ指定でファイルのPULLも可能ですが、取得先サーバにrsyncの設定が必要となります。

そのため、初めにファイルリストを取得した上で、それぞれのファイルをfetchする手段でファイル収集用のplaybookを作成します。

ファイルをただ集めるだけであれば単純なscpのスクリプトクラスタsshのclusterit/parallel sshの並列版scpで十分です。。
ansible-playbookを利用すれば、構成変更時にインベントリファイルの修正に合わせてplaybookの変更不要でうまくやってくれ、並列数(-F、--forksオプション)も簡単に変更できたりします。

Ansible導入

epel導入してansibleのインストール。

$ sudo rpm -ivh http://ftp.riken.jp/Linux/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
$ sudo yum install -y ansible

ホストの設定と接続確認

3台のマシンから収集するとして、インベントリファイルへ3台のマシンのグルーピングを設定。pingモジュールでserversグループへの疎通確認を行います。

$ echo -e "[servers]\nmhost[01:03]\n" | sudo tee -a /etc/ansible/hosts
$ tail -3 /etc/ansible/hosts
[servers]
mhost[01:03]
$ ansible servers -m ping -o
mhost03 | success >> {"changed": false, "ping": "pong"}
mhost02 | success >> {"changed": false, "ping": "pong"}
mhost01 | success >> {"changed": false, "ping": "pong”}

playbookの作成

varsoutputdirに出力先のディレクトリを指定します。
logsにはファイルパス、ワイルドカード付きのファイルパス、ディレクトリパス(配下が全て対象)などを列挙します。
1つ目のshellモジュールのtaskでfindコマンドでlogsに指定した条件に当てはまるファイル群を取得してfile_listに格納されます。
2つ目のfetchモジュールのtaskでoutputdirにインベントリホスト名(mhost01など)のディレクトリを作成し、その下にホスト毎にfile_listのファイルを収集します。
flat=yesのため、ホスト毎の全ファイルは1階層に置かれます。flat=noの場合、 /var/tmp/mhost01/var/log/messagesの様なfetch元のディレクトリ階層でファイルが配置されます。

$ vi collect.yaml
---
- name: collect files for each hosts
  hosts: servers
  sudo: yes
  gather_facts: false
  vars:
    outputdir: /var/tmp
    logs:
       - /var/log/messages*
       - /var/log/secure*
       - /var/log/audit/
  tasks:
    - shell: find {{logs | join(' ')}} -type f
      register: file_list
      ignore_errors: true

    - fetch: src={{item}} dest={{outputdir}}/{{inventory_hostname}}/ flat=yes
      with_items: file_list.stdout_lines

playbookの実行

playbookを実行します。今回は3ホストのため、3並列(-f)で実施します。デフォルトは5です。 もし、outputdirをコマンドで指定したい場合などは、ansible-playbook collect.yaml -e "outputdir=/tmp/“にて、コマンドオプションのEXTRA_VARSに指定する方法もあります。

$ ansible-playbook collect.yaml -f 3
PLAY [collect files for each hosts] *******************************************

TASK: [shell find /var/log/messages* /var/log/secure* /var/log/audit/ -type f] ***
changed: [mhost03]
changed: [mhost02]
changed: [mhost01]

TASK: [fetch src={{item}} dest={{outputdir}}/{{inventory_hostname}}/ flat=yes] ***
changed: [mhost02] => (item=/var/log/messages)
changed: [mhost03] => (item=/var/log/messages)
changed: [mhost01] => (item=/var/log/messages)
changed: [mhost03] => (item=/var/log/messages-20140713)
changed: [mhost01] => (item=/var/log/secure)
changed: [mhost03] => (item=/var/log/secure)
changed: [mhost03] => (item=/var/log/secure-20140713)
changed: [mhost02] => (item=/var/log/messages-20140713)
changed: [mhost02] => (item=/var/log/secure)
changed: [mhost02] => (item=/var/log/secure-20140713)
changed: [mhost01] => (item=/var/log/audit/audit.log)
changed: [mhost03] => (item=/var/log/audit/audit.log)
changed: [mhost02] => (item=/var/log/audit/audit.log)

PLAY RECAP ********************************************************************
mhost01                    : ok=2    changed=2    unreachable=0    failed=0
mhost02                    : ok=2    changed=2    unreachable=0    failed=0
mhost03                    : ok=2    changed=2    unreachable=0    failed=0

収集ファイルの確認

outputdirのホストディレクトリ配下に各ファイルが収集されていることが確認できます。

$ ls -l /var/tmp/mhost0*
/var/tmp/mhost01:
total 636
-rw-rw-r-- 1 vagrant vagrant 520298 Jul 16 15:48 audit.log
-rw-rw-r-- 1 vagrant vagrant  84432 Jul 16 15:46 messages
-rw-rw-r-- 1 vagrant vagrant  38196 Jul 16 15:46 secure

/var/tmp/mhost02:
total 876
-rw-rw-r-- 1 vagrant vagrant 719102 Jul 16 15:48 audit.log
-rw-rw-r-- 1 vagrant vagrant  33079 Jul 16 16:01 messages
-rw-rw-r-- 1 vagrant vagrant  87116 Jul 16 15:47 messages-20140713
-rw-rw-r-- 1 vagrant vagrant  44907 Jul 16 15:47 secure
-rw-rw-r-- 1 vagrant vagrant   3246 Jul 16 15:47 secure-20140713

/var/tmp/mhost03:
total 828
-rw-rw-r-- 1 vagrant vagrant 706276 Jul 16 15:48 audit.log
-rw-rw-r-- 1 vagrant vagrant  29142 Jul 16 16:01 messages
-rw-rw-r-- 1 vagrant vagrant  56887 Jul 16 15:46 messages-20140713
-rw-rw-r-- 1 vagrant vagrant  43836 Jul 16 15:46 secure
-rw-rw-r-- 1 vagrant vagrant   3049 Jul 16 15:46 secure-20140713