
[2014-01-09-1]
からmasutaka.netのCIを開始したが、残念ながら
masutaka.netに直接serverspecする、なんちゃってCIだった。
masutaka.netにcookしてからPRを出して、WerckerにCIさせていた。
WerckerとAWSを連携させて、テストのたびにサーバをまっさらな状態から
作り、終わったら破棄することが可能になったので、ここに記録しておく。
去年くらいに話題になったこの辺の話。
Vagrant + Chef Solo + serverspec + Jenkins でサーバー構築を CI - naoyaのはてなダイアリー
naoya/circleci-serverspec
なんで今までやらなかったかというと、cookが一発で通らないレシピになっ
ていたから。。気づいてはいたんだけど、本番サーバのテストが通りさえ
すればよかったし。。。
こちらの記事でいうところの、Orchestrationの仕事までChefにやらせてい
たのが敗因。GitHubのprivateリポジトリにおいてあるdotfilesや、
growthforecast、tiarra、mobircまでもChefにインストールさせていた。
ユーザmasutakaに依存しないレシピに変更して、手元の
Vagrant+VirtualBoxで一発でspecが通るまでがステップ1。
次に手元のVagrant+AWSで同じことが出来るまでがステップ2。
これをWercker上で実行できるようにwercker.ymlを書き換えたのがステッ
プ3。
最終的なVagrantfileとwercker.ymlは以下のとおり。
# -*- mode: ruby -*- | |
# vi: set ft=ruby : | |
# 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.define :local do |local| | |
local.vm.box = "ubuntu/trusty64" | |
local.vm.network "private_network", ip: "192.168.50.13" | |
local.ssh.forward_agent = true | |
local.vm.provider "virtualbox" do |vb| | |
vb.customize ["modifyvm", :id, "--memory", "2048"] | |
end | |
end | |
config.vm.define :ec2 do |ec2| | |
ec2.vm.box = 'dummy' | |
ec2.vm.box_url = 'https://raw.githubusercontent.com/mitchellh/vagrant-aws/master/dummy.box' | |
ec2.vm.provider :aws do |aws, override| | |
aws.access_key_id = ENV['AWS_ACCESS_KEY_ID'] | |
aws.secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] | |
aws.region = 'ap-northeast-1' | |
aws.instance_type = 't2.micro' | |
aws.ami = 'ami-a1124fa0' | |
aws.security_groups = ['default'] | |
aws.keypair_name = 'ec2' | |
aws.tags = { 'Name' => 'vagrant' } | |
override.ssh.username = 'ubuntu' | |
override.ssh.private_key_path = '~/.ssh/ec2.pem' | |
end | |
end | |
end |
box: wercker/rvm | |
# Build definition | |
# See the Ruby section on the wercker devcenter: | |
# http://devcenter.wercker.com/articles/languages/ruby.html | |
build: | |
# The steps that will be executed on build | |
steps: | |
- rvm-use: | |
version: ruby-2.1.2 | |
# A step that executes `bundle install` command | |
- bundle-install | |
# A custom script step, name value is used in the UI | |
# and the code value contains the command that get executed | |
- script: | |
name: echo ruby information | |
code: | | |
echo "ruby version $(ruby --version) running" | |
echo "from location $(which ruby)" | |
echo -p "gem list: $(gem list)" | |
# Add more steps here: | |
- script: | |
name: create ~/.ssh | |
code: install -d -m 755 ~/.ssh | |
- create-file: | |
name: create ~/.ssh/ec2.pem | |
filename: $HOME/.ssh/ec2.pem | |
overwrite: true | |
hide-from-log: true | |
content: $EC2_SSH_KEY_PRIVATE | |
- script: | |
name: set permission for ~/.ssh/ec2.pem | |
code: chmod 400 $HOME/.ssh/ec2.pem | |
- script: | |
name: install vagrant | |
code: | | |
wget https://dl.bintray.com/mitchellh/vagrant/vagrant_1.6.5_x86_64.deb | |
sudo dpkg -i vagrant_1.6.5_x86_64.deb | |
which vagrant | |
vagrant -v | |
vagrant plugin install vagrant-aws unf | |
- script: | |
name: vagrant up | |
code: vagrant up ec2 --provider=aws | |
- script: | |
name: create ~/.ssh/config | |
code: | | |
vagrant ssh-config --host=ec2 ec2 > ~/.ssh/config | |
chmod 644 ~/.ssh/config | |
- script: | |
name: cook | |
code: bundle exec knife solo bootstrap ec2 | |
- script: | |
name: serverspec | |
code: bundle exec rake spec:ec2 | |
- script: | |
name: vagrant destroy | |
code: vagrant destroy -f ec2 |
いくつかハマったけど、凡ミスだったので特には触れない。上の設定に従
えば同じことは出来るはず。(CircleCIだと各インスタンスにssh出来るの
で、調査は早かったんだろうと夢想。)
でも一点だけad hocな対応をしていて、plenvやrbenvを使ったPerl/Rubyの
インストールはビルド済みのtar ballを展開するだけに変更した。
Werckerはビルドが5分間止まると失敗だと見なすから。ビルド全体の時間
は25分までOK。
そもそもImmutable Infrastructure的にplenvやrbenvを使うのはどうなの?
という節もあって、そこは今後変えるかもしれない。
wercker.ymlも毎回Vagrantをインストールして、vagrant upするという無
駄なことをしているので、Docker使って時短させるかもしれない。
とりあえずCI出来るようになったので、今回はこれで良しとする。