Ansibleのtemplateモジュールでtd-agent.confを作成してプライベートも充実

2016.04.28

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

コンニチハ、千葉です。

Ansible使ってますか!今日は、templateモジュールを使った効率的な設定ファイルの作成に関するお話です。

同じような設定(パラメータ)が書いてある設定ファイルってありますよね。これをを全て手で作成していると日が暮れる可能性があります。 例えば、このような設定ファイルです。(今回は、例としてtd-agent.confを扱いますが、httpd.conf等でも応用できます)

## for web-1.log
<source>
  type tail
  format none
  path /var/log/web/web-1.log
  pos_file /var/log/web/web-1.log.pos
  tag web-1.log
</source>

## for web-2.log
<source>
  type tail
  format none
  path /var/log/web/web-2.log
  pos_file /var/log/web/web-2.log.pos
  tag web-2.log
</source>

## for web-3.log
<source>
  type tail
  format none
  path /var/log/web/web-3.log
  pos_file /var/log/web/web-3.log.pos
  tag web-3.log
</source>

・
・
・
(web-30まであるとする)
・
・
・

<match web** >
  type forward
  host xx.xx.xx.xx
  port 24224
  expire_dns_cache 0
  flush_interval 60s
</match>

webが30種類あるとします。ログファイルの種類が沢山あります。これを手で書くとすると、間違いを起こす可能性も大いにあります。 だたよく見るとこのファイルは、ログ名とタグが違うだけでフォーマットは同じです。 実際にtd-agent.confを利用する場合も、ログ名、パス、タグが違うだけで、同じような記載する場合が多いと思います。

ここでAnsibleのtemplateモジュールの登場です。templateモジュールではJinja2というテンプレートエンジンが利用でき、ログが100あってもそれほど苦労せずにconfファイルを作成することができます。しかも、タイポの可能性を激減することが可能です。

ということで、みなさんも明るいうちに?帰りたいと思いますのでご紹介したいと思います!

Ansibleの設定ファイル

ファイルはこんな感じで配置しました。

local$ tree
.
├── hosts
├── td-agent.yml
└── template
    └── td-agent.conf.j2

hosts

docker-1 ansible_connection=docker

dockerで試したので、ansible_connection=dockerを指定していますが、sshを利用するのであれば不要です。 ssh利用の場合は、ansible.cnfでssh_configを設定するを参考に。

td-agent.yml

---
- hosts: docker
  vars:
    td_agent_server: 192.168.0.1
    td_agent_lognames:
      - { log_tag: web.web-1.log, log_path: /var/log/web/web-1.log }
      - { log_tag: web.web-2.log, log_path: /var/log/web/web-2.log }
      - { log_tag: web.web-3.log, log_path: /var/log/web/web-3.log }
      - { log_tag: web.web-4.log, log_path: /var/log/web/web-4.log }
      - { log_tag: web.web-5.log, log_path: /var/log/web/web-5.log }

  tasks:
    - name: replace td-agent.conf
      template: src=template/td-agent.conf.j2 dest=/etc/td-agent/td-agent.conf owner=root group=root mode=0644
      notify: restart td-agent service

  handlers:
    - name: restart td-agent service
      service: name=td-agent state=restarted

変数で「td_agent_server」、「td_agent_lognames」を定義しています。こちらは、td-agent.confへ渡す値になります。 tasksとして、templateモジュールによるtd-agent.confの置き換えと、handlersにてtd-agent.confに変更があった場合、td-agentを再起動するように指定しています。

td-agent.conf.j2

{% for logname in td_agent_lognames %}

## for {{logname.log_tag}}

<source>
  type tail
  format none
  path /var/log/web/{{logname.log_path}}
  pos_file /var/log/web/{{logname.log_tag}}.pos
  tag {{logname.log_tag}}
</source>

{% endfor %}

<match web** >
  type forward
  host {{td_agent_server}}
  port 24224
  expire_dns_cache 0
  flush_interval 60s
</match>

forでループさせ、td_agent_lognamesの値でtd-agent.confを作成します。 ログが増減したり、名前の変更があった場合でもtd-agent.confに指定している変数を変更することで対応できます。 フォーマットが一緒なので、confファイル作成時の間違いも減らすことができます。何より楽ができます。

実行してみる

それでは実行してみます。

local$ ansible-playbook -i hosts td-agent.yml

PLAY ***************************************************************************

TASK [setup] *******************************************************************
ok: [docker-1]

TASK [replace td-agent.conf] ***************************************************
changed: [docker-1]

RUNNING HANDLER [restart td-agent service] *************************************
changed: [docker-1]

PLAY RECAP *********************************************************************
docker-1                   : ok=3    changed=2    unreachable=0    failed=0

実際の、td-agent.confを見ると

## for web.web-1.log

<source>
  type tail
  format none
  path /var/log/web/web-1.log
  pos_file /var/log/web/web.web-1.log.pos
  tag web.web-1.log
</source>


## for web.web-2.log

<source>
  type tail
  format none
  path /var/log/web/web-2.log
  pos_file /var/log/web/web.web-2.log.pos
  tag web.web-2.log
</source>

・
・省略
・

<match web** >
  type forward
  host 192.168.0.1
  port 24224
  expire_dns_cache 0
  flush_interval 60s
</match>

問題なさそうです!

まとめ

Ansibleのtemplateモジュールで効率化できました。 効率化しまくって、早く帰ってファミリータイムも充実です。