Shin x Blog

PHPをメインにWebシステムを開発してます。Webシステム開発チームの技術サポートも行っています。

Vagrant + Ansible で開発環境を作るなら ansible_local プロビジョナがいい!

Vagrant 1.8 で、ansible_local という新しいプロビジョナが追加されました。

f:id:shin1x1:20160120181043p:plain

これは、Ansible をゲスト(VM)側にインストールして、ローカルコネクションで VM 内で実行するものです。これは、まさに待ち望んでいた機能ので紹介します。

Vagrant + Ansible で気を付けること

f:id:shin1x1:20160120150104p:plain:w500

以前から、Vagrant + Ansible の組み合わせでローカルの開発環境を作るなら、ホスト側に Ansible を入れるのではなく、ゲスト(VM)側に Ansible を入れる方が良いと考えていました。勉強会などでも良く話していたのでお聞きになった方もいるかと思います :)

ホスト側に Ansible を入れない理由は、3 つあります。

まず、ホストに Ansible をインストールする手間が増える点です。VagrantVirtualbox のインストール(あとコードのチェックアウト)以外は、vagrant upのみで環境構築は完結したいところです。専用のシェルスクリプトを用意して、Ansible のインストールを含めて自動化する方法もありますが、専用のスクリプトを覚えるより、vagrant upというどのプロジェクトでも同じ手順で構築出来る方が楽でしょう。

もう一つの方が、今後は重要になります。それは、それぞれのホストで Ansible のバージョンが異なるために問題が起こる可能性がある点です。こうした環境による違いを同じ構成の VM を使うことで吸収できるのが Vagrant の大きな利点なのに、 Ansible がホストにあると、こちらで動くがあちらで動かないというケースが出てきます。Ansible 2 がリリースされたことで、今後はこの問題がより起こりやすいと思います。

最後は、Windows 環境です。Ansible は、Windows をプロビジョニングはできるのですが、Ansible 自体は実行できません。つまり開発機が Windows の場合、Ansible は VM に入れるしかありません(別の Linux 機から Windows 機をプロビジョニングすることは可能です)。

こうした問題を防ぐために、VM 側に Ansible をインストールしてプロビジョニングを行っていました。

shell プロビジョナによる Ansible プロビジョニング

これまで、VM に Ansible をインストールして ansible-playbook を実行するのは、shell プロビジョナを利用していました。

例えば、下記のように、Ansible のインストールとローカルコネクションによる Playbook の実行をスクリプトとして記述していました。

  config.vm.provision "shell", inline: <<-SHELL
    yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
    yum -y install ansible
    cd /vagrant/provision; ansible-playbook -i localhost vagrant.yml
  SHELL

この動きを Vagrant の機能として実装したのが、ansible_local です。

ansible_local プロビジョナ

ansible_local プロビジョナは、Ansible のインストール(インストールされていなければ)、ansible-playbook コマンドによる Playbook の実行を行います。

上記の shell プロビジョナの例を ansible_local に書き直すと記のようになります。Playbook のパスを指定するだけなのでシンプルですね。

  config.vm.provision "ansible_local" do |ansible|
    ansible.playbook = "provision/vagrant.yml"
  end

Ansible のインストール方法は、VM の OS によって異なります。例えば、RedHat系なら yum(EPEL) で、Debian 系なら apt-get でインストールされます。

現時点では、Ansible のバージョンを指定してインストールすることはできない(RedHat系ならyum install ansible --eablerepo=epelでインストールされるバージョンのみ)ので、もしその必要があれば従来どおり shell プロビジョナを使って、pip などでインストールすることになります。

このプロビジョナには、いくつかオプションが指定できます。必須は、ansible.playbook のみです。

オプション 内容
ansible.playbook string 必須。VM 上での Playbook のパスを指定。下記、provisioning_pathからの相対パスでも、絶対パスでも可。
ansible.install boolean Ansible を自動インストールするかどうか。デフォルトは、true。
ansible.provisioning_path string ansible-playbookコマンドを実行するパス。デフォルトは、/vagrant
ansible.tmp_path string プロビジョナが利用する一時ファイルの置き場。デフォルトは、/tmp/vagrant-ansible。|ansible.version|string|想定している Ansible バージョン。デフォルトは、バージョンチェックしない。
ansible.inventory string インベントリパス。
ansible.verbose string or false ansible-playbook 実行時に詳細出力するかどうか。vの数が多ければ、より詳細出力になる。(ansible-playbook -v相当)
ansible.limit string ansible-playbook を実行するホストやグループ指定(ansible-playbook --limit相当)

ansibleプロビジョナと共通のオプションも多くあるので、詳細は公式ドキュメントもしくはコードを見て下さい。

shell プロビジョナと ansible_local プロビジョナの違い

2つのプロビジョナを実行してみて分かる大きな違いが、実行中の画面への出力です。

shell プロビジョナでは、ansible-playbook コマンドからの出力はバッファリングされて、コマンド完了後に一度に出力されていました。また、実行結果の色表示などもありません。

f:id:shin1x1:20160120144108g:plain

ansible_local プロビジョナでは、通常 ansible-playbook コマンドを実行したのと同等にタスク実行時に逐次出力が行われます。また、実行結果も色付けされています。

f:id:shin1x1:20160120144118g:plain

これだけでも、ansible_local を使うメリットがありますね。

さいごに

ansible_local は、 Vagrant + Ansible で開発環境を構築するなら決定版ともいえるプロビジョナです。

しばらく Ansible 1.x と 2.x が混在することになるので、ansible_local を使って同一バージョンの Ansible でプロビジョニングするようにしましょう。

Vagrant入門ガイド

Vagrant入門ガイド