Vagrant + Ansible で簡単に開発環境を provision する
開発環境構築自動化の動機
ちっちゃなwebシステムを受託でやることもちょこちょこあるんだけど、以下のような理由から、開発環境の自動化をすることにした。
- 使うフレームワークは大体同じ(CakePHP, Ruby on Rails, Play! framework のいずれか)なのに、毎回同じような環境構築をやるのも面倒くさい
- 経験の浅いメンバーは、環境構築で詰まりがちなので、その辺は飛ばしていきなり実装に入れるようにしたい
使う技術
最近、メインでやっているプロジェクトで Ansible を使ってデプロイとかをするようにして、ある程度慣れてきたので、今回は Ansible を使うことにした。
開発環境用の仮想環境(VM)作成は、みんな大好き vagrant を使う。
やることの概要
- Ansible のプレイブックを書く
- 開発環境と本番環境のprovisionを簡単に切り替えられるようにする
- vagrant up 時に、Ansible が実行されて環境設定されるようにする
Ansible のプレイブックを書く
これに関しては、色んなサイトとかドキュメントがあるので、Ansible の使い方に関してはそうしたのを参照。
ディレクトリ・ファイル構成
最初は少し面倒くさいけど、Best Practices に従っておくと、後々便利だった。こういうドキュメントがあるのは素晴らしいと思った。
Best Practices に従うと、Ansible 関連ファイルを入れるディレクトリの直下には以下のようなファイルを作ることになる。
- site.yml → 大元の playbook
- webservers.yml, dbservers.yml → site.yml から include される
- production, stage, development → ホスト名を定義したファイル(inventory ファイル?)
ホスト名の設定
例えば production ファイルには、以下のように記載する。
# file: production [dbservers] db.example.com [webservers] www.example.com
development に関しては、詳細は後述するが、 Vagrant がその辺を面倒みてくれるので、作る必要はないが、Ansible 単体でテストしたい場合もあるので作っておいた。
役割毎のplaybookを作成
webservers.yml と dbservers.yml に、それぞれ web サーバーとDB サーバーのタスクを記載する。
webservers.yml は以下のようになる。
--- # file: webservers.yml - hosts: webservers sudo: yes roles: - common - webtier
開発環境にしか入れないソフトとか設定が結構あるので、自分の場合は devservers.yml というのも作成した。
--- # file: devservers.yml - hosts: devservers sudo: yes roles: - common - development
ロールの設定
上述の Best Practices に従い、roles ディレクトリの下に以下のロールを定義する。
- common
- webtier
- dbtier
- development (Best Practices には存在しない)
タスクの設定
Ansible 自体の使い方なので省略。
動作確認
ここまで終われば、以下のように使うことができる。
ansible-playbook -i development site.yml
Vagrant の設定
Vagrant には Ansible Provisioner というのがあるらしい。その名の通り、vagrant box 起動後、 Ansible で provision を行うというもの。
自分の場合、 Vagrantfile にこんな風に書いた。
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| # config.vm.hostname, config.vm.network 等を直接変更しても良いが、 # その場合は、下の方で "default" という名前を使うことになるっぽい。 config.vm.define "cakephp3-sample" do |l| l.vm.hostname = "cakephp3-sample" l.vm.network "private_network", ip: "192.168.33.10" l.vm.provider "virtualbox" do |vb| vb.customize ["modifyvm", :id, "--memory", "1024"] end end # Ansible Provisioner の設定 config.vm.provision "ansible" do |ansible| ansible.playbook = "ansible-playbooks/site.yml" # ここでは、上の config.vm.define で設定した名前を指定しないと、 # 生成された inventory ファイルにホスト名が含まれなくなるらしい ansible.groups = { "webservers" => ["cakephp3-sample"], "dbservers" => ["cakephp3-sample"], "devservers" => ["cakephp3-sample"], "all_groups:children" => ["webservers", "dbservers", "devservers"] } end end
注意点は、inventory ファイルのところ。以下、ドキュメントより。
Unmanaged machines and undefined groups are not added to the inventory, to avoid useless Ansible errors (e.g. unreachable host or undefined child group)
生成された inventory ファイルは以下のようになる。
# Generated by Vagrant cakephp3-sample ansible_ssh_host=127.0.0.1 ansible_ssh_port=2222 [webservers] cakephp3-sample [dbservers] cakephp3-sample [devservers] cakephp3-sample [all_groups:children] webservers dbservers devservers
まとめ
Vagrant と Ansible を組み合わせると、便利に自分たちの使いやすい開発環境が作れるよ、と。