Chefがつらい人のためのAnsibleのはなし

Chef使おうとしてるけどChefいろいろつらい. 具体的には以下がつらい.

  • 独自概念多い
  • chefのクライアントを対象ホストに入れなければならない
  • knifeとか覚えないといけない外部ツールがある
  • 最初からディレクトリ構成がわいわい (rails newしたときのあのきもち)
  • 公式ドキュメントの量が多いかつわかりにくい

以前にmiyagawaさんのpodcast を聞いてたらnaoyaさんがAnsibleっていうシンプルなプロヴィショニングツールがあるっていう話をされていたので,使ってみた.

AnsibleWorks | Radically simple IT orchestration

Ansible

触ってて感じるイメージは,ChefがRailsでAnsibleがSinatraな感じ.

  • ディレクトリ構成がない (一応大規模運用を考えたディレクトリ構成のベストプラクティス Best Practices | AnsibleWorksがある)
  • クライアントがいらない.SSHで入ってコマンド叩くだけ
  • 冪等性あり
  • Pythonでかかれているけど,設定はINIとYAMLで,モジュールは言語の依存していない形で書くからPython覚えなくていい
  • knife soloみたいな形式で実行する.hosts.iniにはホスト情報が書かれていて,playbook.ymlにはChefでいうところのレシビが書かれている

    ansible-playbook playbook.yml -i hosts.ini

  • マルチプロセスで並列実行が可能
  • ドキュメントが読みやすい
  • Vagrantがサポートしてたりしてて,開発が結構盛んな印象

Example

NginxをソースからビルドするPlaybook. 適当に書いたからだいぶ粗があるけど,雰囲気はこんな感じ.

PuppetみたいなDSLだったり,ChefみたいなRubyだったりしないので,覚えることが少ない. このへん,さすがPythonプロダクトな感じはある.

- hosts: nginx-webservers
  sudo: yes
  vars:
    version: "nginx-1.5.3"
    nginx_url: "http://nginx.org/download/nginx-1.5.3.tar.gz"
    status_path: '/nginx_status'
    dir: '/home/vagrant'
    bin_path: '/usr/local/bin'
    src_binary: '/usr/local/bin/nginx'
    conf_dir: '/etc/default/nginx'
    init_dir: '/etc/init.d'
    pidfile: '/var/run/nginx.pid'
    log_dir: '/var/log/nginx'
  tasks:
    - name: "build-essential"
      apt: pkg=build-essential state=installed

    - name: "wget nginx src"
      command: wget -O $dir/$version.tar.gz $nginx_url creates=$dir/$version.tar.gz

    - name: "expand src"
      command: tar xvfz $dir/$version.tar.gz creates=$dir/$version

    - name: "mkdir confdir"
      file: dest=$conf_dir state=directory

    - name: "mkdir logdir"
      file: dest=$log_dir state=directory

    - name: "configure"
      command: ./configure --with-http_stub_status_module --without-http_rewrite_module --sbin-path=$bin_path --conf-path={{ conf_dir }}/nginx.conf chdir=$dir/$version

    - name: "make"
      command: make chdir=$dir/$version

    - name: "make install"
      command: make install chdir=$dir/$version

    - name: "expand nginx.init"
      template: src=templates/nginx.init.j2 dest={{ init_dir }}/nginx

    - name: "chmod nginx.init"
      file: path={{ init_dir }}/nginx mode=0744

    - name: "expand nginx.conf"
      template: src=templates/nginx.conf.j2 dest={{ conf_dir }}/nginx.conf
      notify:
        - restart nginx

    - name: be sure nginx is running and enabled
      service: name=nginx state=running enabled=yes

  handlers:
    - name: "restart nginx"
      service: name=nginx state=restarted enabled=yes

1つのファイルに書くのが辛くなったら分割することもできる. 分割の仕方も結構自由度が高い気がする. 自由度が高いということは,自分でファイル配置を考えないといけないという意味だけど,Chef使うにしても結局どこに何を書くのかのルールの共有はしないといけない感じがする.(Rails使っててもどこに何を書いたらいいのかわからなくなるのと同じ感じかな)

分割例.

ansible-repo/monitorel at master · y-uuki/ansible-repo · GitHub

Ansibleで多数のサーバを構成管理するには

仕事で使うとなると多数のサーバを管理しないといけなくなる. そういうときにノード情報をINIファイルのようなテキストファイルで管理するのは厳しい.

ChefにはChef Serverっていうのがあって,ノードとレシピの情報を一元管理してる. Ansibleにはこれに相当する機能はない.

入門 Chef Server #biglobetechtalk

ただ,サーバのノード管理って本来プロビジョニングツールがやることじゃなくて,サーバ管理ツール(Zabbix, Munin, Cactiなど)がやることな気がする. サーバ管理ツールがあれば,ノード情報はWeb APIとかSQLを叩いて引っ張れる. cronで定期的にサーバ管理ツールからノード情報を取得して,INIファイルを生成すればいいんじゃないかなとか最近考えてる.

参考