phpカンファレンスでAnsible良さそうって聞いたので調べてみた

phpカンファレンスに参加した際に「Ansible ではじめるサーバ作業の自動化」を見た友人からAnsible良さそうって聞いたので調べてみた。

Ansibleについて

  • 構成管理ツールの一種
  • 他にchef,Puppetがある
  • Pythonで書かれている
  • だからといってPythonの知識は必要ない
  • 対象にAnsibleをインストールする必要がない
  • sshで命令しているため

分類

  • サーバ<-クライアント構成(クライアントからサーバに問い合わせるPull方式)
  • Chef, Puppetなど
  • サーバ->クライアント構成(サーバからクライアントに命令するPush方式)
  • Ansible,Func,Fabric,Capistranoなど

導入のしやすさ

  • ドキュメントが短いため習得が簡単
  • どの言語でもモジュールが書ける

用語

  • モジュール
  • ソフトウェアのインストール、サービスの起動などのクライアント内での動きを定義
  • Python以外の言語で書くことも可能。決められた出力形式であればおけ
  • Play book
  • =レシピ
  • YAML形式で記述
  • inventory file
  • 対象のサーバを管理するファイル
  • グループの指定も可能

導入

ここから実際にAnsibleを使います。 Mac->Vagrant(CentOS 6.5)構成でやります。

環境

  • Mac OS X(10.9.5)
  • Ansible(1.7.2)
  • Homebrew(0.9.5)
  • Virtual Box(4.3.18)
  • Vagrant(1.3.5)

インストール

$ brew install ansible
$ ansible --version
ansible 1.7.2

Vagrantの用意

インストール済み前提に話しを進めます

$ vagrant init
$ vim Vagrantfile
# boxの指定に加え、下記を追記
config.vm.network :private_network, ip: "192.168.33.10"
config.ssh.forward_agent = true
$ vagrant up
$ vagrant ssh-config --host node >> ~/.ssh/config # sshの設定を追記

疎通確認

  • 失敗1
$ ansible 192.168.33.10 -m ping
ERROR: Unable to find an inventory file, specify one with -i ?

接続先を記述したインベントリファイルを用意しないとダメです。

ファイル名はhostsとします。

$ echo 192.168.33.10 > hosts
$ ansible -i hosts 192.168.33.10 -m ping
192.168.33.10 | FAILED => SSH encountered an unknown error during the connection. We recommend you re-run the command using -vvvv, which will enable SSH debugging output to help diagnose the issue

そして失敗・・・

  • 失敗2
$ ansible -i hosts 192.168.33.10 -m ping
192.168.33.10 | FAILED => SSH encountered an unknown error during the connection. We recommend you re-run the command using -vvvv, which will enable SSH debugging output to help diagnose the issue

鍵周りかなーと思いつつ、`~/.ssh/configのHostをnodeから192.168.33.10に書き換えます。

$ ansible -i hosts 192.168.33.10 -m ping
192.168.33.10 | success >> {
    "changed": false,
    "ping": "pong"
}

これで成功しました。ansibleはssh経由で対象サーバにアクセスしているため、アクセス時のホスト名で

Play bookを使う

まずはPlay bookを作成します。Play bookは複数のモジュールを定義したファイルです。今回はApacheを試しに入れてみます。

yumserviceモジュールにあたる部分です。

他のモジュールは公式ドキュメントのModule Indexを参照

---
- hosts: 192.168.33.10
  sudo: yes
  tasks:
    - name: be sure httpd is installed
      yum: name=httpd state=installed

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

記述後は構文に問題がないか確認します。

ここからは先ほどと変わってansible-playbookコマンドを使っていきます。

$ ansible-playbook -i hosts simple.yml --syntax-check

playbook: simple.yml

問題があれば何かしらエラーを出力します。

では、ansibleを使ってApacheをインストールします。

本来ならインストールする前に--checkオプションを指定してdry-runしておいた方が安全です。今回は省略します。

$ ansible-playbook -i hosts simple.yml
PLAY [test-server] ************************************************************

GATHERING FACTS ***************************************************************
ok: [192.168.33.10]

TASK: [be sure httpd is installed] ********************************************
changed: [192.168.33.10]

TASK: [be sure httpd is runnning and enabled] *********************************
changed: [192.168.33.10]

PLAY RECAP ********************************************************************
192.168.33.10              : ok=3    changed=2    unreachable=0    failed=0

192.168.33.10にアクセスするとApacheのテストページを閲覧することができました。

これでPlay bookを利用してソフトウェアのインストールが出来ました。

tips

  • インベントリファイルの指定を省略する

毎回インベントリファイルを指定するのが面倒な場合はansibleの設定ファイルに記述すると省略できます。

ansible.cfgを用意して、そこにhostsを指定します。

$ vim ansible.cfg
[defaults]
hostsfile = ./hosts
  • インストール時にターミナルから入力させる

追加するユーザ名を入力させるときは以下のようになる。

vars_promptでユーザーに入力させ、入力された値はusernameに格納される仕組み

またusernameが変数となっており、こちらを利用する場合は{{}}の中に変数名を記述する

vars_prompt:
  username="Enter username"
  tasks:
  - name: add User
    user: name={{username}}

単純に変数を利用する場合は以下のとおり、

vars:
  username: mofumofu3n
  tasks:
   - name: add User
     user: name={{username}}
  • yamlファイルで繰り返しを利用する

例えばphpをインストールする場合、phpだけでなく紐づくソフトウェア(php-mysql)もインストールすることがあります。

そんなときは繰り返しを使うことで複数のソフトウェアを入れることが出来ます。

- name: install php package
  yum: name={{item}} state=latest
  with_items:
    - php
    - php-devel
    - php-mbstring
    - php-mysql

with_itemsで指定したソフトウェアが順次itemに展開され、インストールされていきます。

まとめ

以前、chefを使っていましたが対象サーバにchefを入れる必要があるため、時間がかなり掛かっておりここがネックだなーと思っていました。

Ansibleであればsshで実行しているため、より気軽に開発サーバを作ったり壊したり出来そうです。

また特定言語の知識が必要ないのも嬉しいところです。(といってもYAMLの構文を覚える必要はありますが。。)

YAMLの構文はこちらでまとめられていたので大変参考になります。 * ansible使いのためのYAML入門 - @znz blog

なんにせよ簡単に導入できたのでchefから乗り換えてみようと思います。

参考になりそうなページ