Tokyo Otaku Mode の本番サーバにAnsibleによるインフラ構築を導入した話

Ansible
こんにちは。 Tokyo Otaku Mode (以下TOM)でエンジニアとして働いている bells17 です。
2015年10月に社内勉強会で otakumode.com の本番サーバに Ansible で Fluentd を使ったログの収集環境を構築した話をしました。

実はこの時 Ansible を使ったインフラ構築を初めて TOM に導入したので、今回は実際に動いているシステム上にどのようなフローで Ansible を使ったインフラ構築を導入したのかについてまとめてみたいと思います。


1. Vagrant を使ってローカルの仮想環境に環境構築を行う

まずはじめに Vagrant を使用してVMサーバをローカルに用意し、今回構築したい Fluentd によるログ収集環境のミニマム版を作成するところから始めました。

otakumode.com の環境は

  • ホスティング環境: Amazon EC2
  • OS: Amazon Linux
  • ロードバランサー: Nginx
  • 使用言語: JavaScript (Node.js)
  • WAF: Express
  • データベース: MongoDB, Redis

というものです。この中で今回収集したかったのはアプリケーションである Node.js のログとロードバランサーである Nginx のログなので、これらが出力するログと同様のログをログ収集サーバに転送するサンプルを作成してみました。
実際に作成してみた環境は以下のリポジトリになります。
https://github.com/bells17/vagrant-centos-fluentd-sample

Ansible では playbook を実行するサーバを指定するための Inventory file を作成しますが、今回 playbook を作成するにあたって以下のように使い分けようと考えました。

  • Inventory file は実行環境(ステージングサーバ・本番サーバなど)毎に分割する
  • Inventory file 内の group は実行対象のサーバの種類(アプリケーションサーバ・ログ収集サーバなど)を分割するのに使用する

サンプルのリポジトリでは実行環境がローカルだけだったので Inventory file 内の group をそれぞれ

  • ログを出力して、ログサーバに送るサーバ
  • ログを収集するサーバ

という役割に分割してみました。

実際に作成してみた Inventory file は以下のような感じです。
(IPアドレスは Vagrant で立ち上げるときに設定したものを適当に入れてます)

1
2
3
4
5
6
7
8
9
[all:vars]
td_agent_host_ip=192.168.73.11

[fluentd-host]
td-agent-host ansible_ssh_host=192.168.73.11 ansible_ssh_user=vagrant ansible_ssh_port=22 ansible_ssh_private_key_file=.vagrant/machines/td_agent_host/virtualbox/private_key

[fluentd-client]
app ansible_ssh_host=192.168.74.11 ansible_ssh_user=vagrant ansible_ssh_port=22 ansible_ssh_private_key_file=.vagrant/machines/app/virtualbox/private_key
nginx ansible_ssh_host=192.168.74.12 ansible_ssh_user=vagrant ansible_ssh_port=22 ansible_ssh_private_key_file=.vagrant/machines/nginx/virtualbox/private_key

このローカルの仮想環境で Node.js と Nginx のログ収集を試してみて、ログのパースなどの Fluentd のログ収集の設定を修正していきました。

2. EC2に本番サーバーに近いサーバー環境構築を行う

ローカルの仮想環境で必要な Fluentd のログ設定を確認できたので、次にサンプルの playbook をベースにして実際のTOMの環境で動かすための playbook の作成しました。

サンプルで試した playbook では Inventory file のファイル内のグループ分割は host と client というシンプルな分け方をしていたのですが、実際の環境だと

  • ログ収集サーバ
  • アプリケーションサーバ
  • ロードバランサー(Nginx)サーバ

に加えアプリケーションサーバでは特に

  • WEB用のサーバ
  • API用のサーバ

といった条件で微妙に設定を変えたい部分が出てきたり、本番サーバの一部では Flunetd ではなく、 Fluentd をラッピングしている Flydata の設定に上記の Fluentd の設定を適用したいケース等が出てきてしまいました。

そのため元々変数管理を Ansible のベストプラクティスに従って group_vars , host_vars に寄せていたのを、一部 vars というディレクトリを独自に作成して

1
2
3
4
5
6
7
---
- hosts: all
vars_files:
- 'vars/{{ stage }}.yml'

- include: app.yml
~
1
2
3
4
5
6
7
---
- hosts: app
vars:
group: app
vars_files:
- "vars/groups/{{ stage }}_{{ group }}.yml"
~

のようにして

  • 現在の実行環境(ステージングサーバ、本番サーバなど)用の変数ファイル
  • 現在の実行環境(ステージングサーバ、本番サーバなど) × 実行グループ(アプリケーションサーバなど)用の変数ファイル

を playbook のタスク実行前に読み込むようにすることで解決しました。

まとめ

ざっくりとした説明ですが、今回はこのような形でTOMの本番システムに Ansible の導入を行いましたが、

  • ローカルの仮想環境で Fluentd を動かすためのサンプルを作成
  • AWS 上のステージングサーバで実際の環境に近い形でのテストを行う

というフローを踏むことで大きなトラブルもなく Ansible を使った本番サーバへの Fluentd の導入ができたように思います。
この記事を読まれて Ansible に興味を持たれた方は是非導入を検討してみてください。