vagrant + ansible + digitalocean で最強テスト環境を構築
表題の件、最近のお気に入りです。
しかも安い。早い。うまい。と3拍子そろっています。
DigitalOceanのデータセンターはシンガポール(2014年9月現在)、ディスクは、SSD 20GB のため国内サーバとパフォーマンスは遜色ないです。今回紹介する構築手順をためすのに1ドルほどしかかかってません。
唯一の弱点はドロップレットと呼ばれるAWSでいうEC2インスタンスが一つしか作成できないこと。
(いちおう理由を申請すれば複数のドロップレットを起動できるようにしてもらえるらしいが、デジタルじゃないおぉ。)
あと、いまのところsnapshotが無料です。
最近ガシガシ開発することはないんだけど、カリカリのプログラマさんだけでなく、
デザイナーさんやディレクターさんなど、エンジニア以外の人にとってもこれは便利なんじゃないかと思います。
というわけで、vagrant経由でansibleを使ってprovisioningを行い、Virtual Host を使った主要CMSの開発環境を
作成してみましたので、かいつまんで説明します。
CentOS 6.5に
CMS: wordpress, movabletype, drupal
をインストールするというシナリオです。
また、おまけで Varnish もインストールします。
作業はMBPで行っています。
1. Vagrant + DigitalOceanの環境をセットアップ
このあたりを参照すれば問題なくいけるでしょう。
http://blog.glidenote.com/blog/2013/12/05/digital-ocean-with-vagrant/
http://qiita.com/msykiino/items/d45cab7f520a3288862a
ただ、DigitalOceanのAPIが新しくなって少しはまったところだけここに貼付けておきます。
少し前は、api_key をつかっていたのが、tokenを使うようになっています。
$cat Vagrantfile
# -*- mode: ruby -*- # vi: set ft=ruby : Dotenv.load # change default provider to digital_ocean ENV['VAGRANT_DEFAULT_PROVIDER'] = "digital_ocean" # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.provider :digital_ocean do |provider, override| override.vm.hostname = "vagrant-do" override.vm.box = "digital_ocean" override.vm.box_url = "https://github.com/smdahlen/vagrant-digitalocean/raw/master/box/digital_ocean.box" override.ssh.username = ENV['DO_SSH_USERNAME'] override.ssh.private_key_path = ENV['DO_SSH_KEY'] provider.token = ENV['DO_API_TOKEN'] provider.region = "sgp1" provider.image = "CentOS 6.5 x64" provider.size = "512MB" # 512MB | 1GB | 2GB | 4GB | 8GB | 16GB provider.private_networking = true provider.ca_path = "/usr/local/share/ca-bundle.crt" provider.setup = true provider.ssh_key_name = ENV['DO_SSH_KEYNAME'] # disable synced_folder: rsync is not installed on DigitalOcean's base image override.vm.synced_folder "./", "/vagrant", disabled: true end config.vm.provision "ansible" do |ansible| ansible.sudo = true ansible.playbook = "./provision/vagrant.yml" end config.ssh.forward_agent = true end
ちなみにvagrant のディレクトリ構成は下記のような感じです。
はじめはansibleのお作法をちゃんと勉強するのが面倒で単一のplaybook.ymlに書いていましたが、
vagrantで複数のplaybookを実行するために、お作法にのっとってフォルダ分けしました。
こっちのほうが、整理できててよいですね。
├── README.md
├── Vagrantfile
├── ansible.cfg
└── provision
├── common
│ ├── handlers
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ │ ├── common.conf.j2
│ │ ├── htaccess.j2
│ │ └── simpleweb.conf.j2
│ └── vars
│ └── main.yml
├── drupal
│ ├── handlers
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ │ └── drupal.conf.j2
│ └── vars
│ └── main.yml
├── mt
│ ├── handlers
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ │ ├── mt-readme.html.j2
│ │ └── mt.conf.j2
│ └── vars
│ └── main.yml
├── vagrant.yml
├── varnish
│ ├── handlers
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ │ ├── default.vcl
│ │ └── etc-sysconfig-varnish
│ └── vars
│ └── main.yml
└── wordpress
├── handlers
│ └── main.yml
├── tasks
│ └── main.yml
├── templates
│ ├── wordpress.conf.j2
│ └── wp-config.php.j2
└── vars
└── main.yml
2. ansibleのplaybookを書いていきます。
$ cat provision/vagrant.yml
- hosts: all roles: - common - wordpress - drupal - mt - varnish
簡単に説明しておくと、
common, wordpress, drupal, mt , varnish の順にplaybookを実行することを定義しています。
ちなみに commonではhttpdなど共通ミドルなどをインストールしていますが、
各playbookが単体でも動くように、冗長に記述しました。
commonのplaybookを抜粋すると、
- yumのパッケージをすべてアップデート
- epelのレポジトリを設定
- htpasswd ファイルを作成するために、python-passlibをインストール
- httpd をインストール
- ドキュメントルートを作成
- vhostの設定を反映
といったことをしています。
- name: upgrade all yum packages yum: name=* state=latest - name: get epel-repo rpm RHEL6 get_url: dest=/tmp/epel-release.rpm url=http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm - name: install epel-repo rpm yum: pkg=/tmp/epel-release.rpm state=installed - name: be sure python libraries are installed yum: name={{item}} state=installed with_items: - python-passlib - name: be sure httpd is installed yum: name=httpd state=latest - name: create document root file: dest={{ work_dir }} state=directory owner=apache group=apache mode=0755 - name: be sure httpd is configured template: src=common.conf.j2 dest=/etc/httpd/conf.d/common.conf
何となくみていると、どういうことができるのかパッとわかるのではないでしょうか。
サーバセットアップに必要な大概のことはansibleのコマンドで実現可能ですので、
独自にスクリプトを組んだりといった必要がありません(なんて透明性なんでしょう!)。
MovableTypeのようにたくさんのCPAN モジュールに依存している場合は
セットアップ手順などをちまちま作るのはとても面倒です。
プレイブックとして記述しておけると手順書として納品物としてしまっても良い気が個人的にはしています。
template コマンドが中でも便利で、vars/main.yml に定義された変数をsrcファイルに適用したうえで、dest で指定されたパスに反映してくれます。ステキ。
その後、wordpressなどのCMSインストールを実行します。
昨今のOSSはたいていgitレポジトリにあるので、そちらをcloneしてビルドするのが簡単で、必要に応じて、タグを指定して希望のバージョンを自由にインストールことも可能です。
また、wordpressでは、下記のようにgit clone でいっぱつインストールできます。
- name: download wordpress package git : repo=https://github.com/WordPress/WordPress.git dest="{{docroot}}" version={{version}}
楽ちんですね!
3. プレイブックが書けたら、vagrant upします。
$ vagrant up --provider=digital_ocean --provision
さらに、これをJenkinsから行えるようにすれば、クリップ一発で好きな環境を
立ち上げることができます。
便利な世の中になったものです。ホント。
今回作成したplaybookは整理できたらgithubにでもアップしようかと思います。
4. いざサイトにアクセス
私の場合、MBPのhostsに
128.199.xxx.xx default-do default-do 128.199.xxx.xx mt-do mt-do 128.199.xxx.xx drupal-do drupal-do 128.199.xxx.xx wordpress-do wordpress-do
に書いて、アクセスできるようにしています。
Ansible is usable!
Enjoy!