vagrant-aws + vagrant-configspecでEC2をプロビジョニングする
はじめに
先日のJAWS DAYS 2014での宮下 剛輔氏のセッション「Immutable Infrastructure時代の構成管理ツール基盤SpecInfra」を拝聴して、「おお、このSpecInfra、勉強してみたい!」と思ったのですが。
まずはその前に試しては壊し試しては壊し出来る、Immutableな環境を作ろう....とアレコレ調べていた結果、まずは「手もとのMac OS Xからvagrant-awsとvagrant-configspecを使ってさくっとEC2をプロビジョニングしてみよう」という結論に至ったので、やってみました!
各種インストール
Vagrant
公式サイトのDownloadページから最新のパッケージファイルをダウンロードして実行します。 現在最新のVagrantのバージョンは1.5.1です。
$ vagrant -v Vagrant 1.5.1
configspec
configspecはgemでサクっとインストールします。
$ gem install configspec
Vagrant Plugin
まず、デフォルトでインストールされているVagrant Pluginを確認します。
$ vagrant plugin list Vagrant is upgrading some internal state for the latest version. Please do not quit Vagrant at this time. While upgrading, Vagrant will need to copy all your boxes, so it will use a considerable amount of disk space. After it is done upgrading, the temporary disk space will be freed. vagrant-login (1.0.1, system) vagrant-share (1.0.1, system)
次に、vagrant-awsとvagrant-configspecをインストールします。
$ vagrant plugin install vagrant-aws Installing the 'vagrant-aws' plugin. This can take a few minutes... Installed the plugin 'vagrant-aws (0.4.1)'! $ vagrant plugin install vagrant-configspec Installing the 'vagrant-configspec' plugin. This can take a few minutes... Installed the plugin 'vagrant-configspec (0.0.1)'!
Vagrantfileの作成
Vagrant boxを立ち上げるためのVagrantfileを作成します。ポイントはvagrant-awsを使っているので自分のAWS環境に併せて設定しているところと、provisionでconfigspecを使っているところです。
$ mkdir ~/vagrant $ vi ~/vagrant/Vagrantfile VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "ec2" config.vm.box_url = "https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box" config.vm.synced_folder ".", "/vagrant", disabled: true config.vm.provider :aws do |aws, override| aws.access_key_id = "<YOUR_ACCESS_KEY>" aws.secret_access_key = "<YOUR_SECRET_KEY>" aws.keypair_name = "<YOUR_KEYPAIR_NAME>" aws.region = "ap-northeast-1" aws.subnet_id = "<YOUR_SUBNET_ID>" aws.ami = "ami-0d13700c" aws.instance_type = "t1.micro" aws.security_groups = "<YOUR_SECURITYGRUOP_ID>" aws.user_data = "#!/bin/bash\nyum -y update" override.ssh.username = "ec2-user" override.ssh.private_key_path = "~/.ssh/<YOUR_KEYPAIR_FILENAME>" end config.vm.provision :configspec do |spec| spec.pattern = 'configspec/*_spec.rb' end end
configspecファイルの作成
アプリケーションをプロビジョニングするためのconfigspecファイルを作成します。今回はお試しなのでnginxをインストールしてみました。
$ mkidr ~/vagrant/configspec $ vi ~/vagrant/configspec/spec_helper.rb require 'configspec' require 'pathname' require 'net/ssh' include SpecInfra::Helper::Ssh include SpecInfra::Helper::DetectOS $ vi ~/configspec/nginx_spec.rb require_relative "spec_helper.rb" describe package('nginx') do it { should be_installed } end
実行してみる
これまでの作業の結果、ファイル構成としてはこんな感じになります。
vagrant/ ├── Vagrantfile ├── configspec ├── nginx_spec.rb └── spec_helper.rb
では起動!(※一部出力結果を省略しています)
$ vagrant up --provider=aws ==> default: Box 'ec2' could not be found. Attempting to find and install... default: Box Provider: aws default: Box Version: >= 0 ==> default: Adding box 'ec2' (v0) for provider: aws default: Downloading: https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box ==> default: Successfully added box 'ec2' (v0) for 'aws'! ==> default: Launching an instance with the following settings... ==> default: yum -y update ==> default: Waiting for instance to become "ready"... ==> default: Waiting for SSH to become available... ==> default: Machine is booted and ready for use! ==> default: Running provisioner: configspec... . Finished in 2 minutes 27.2 seconds 1 example, 0 failures
お、0 failuresになりましたね!
確認してみる
vagrant sshでVagrant boxとしてlaunchされたEC2にSSHログインし、ちゃんとnginxがインストールされているか確認してみましょう。
$ vagrant ssh __| __|_ ) _| ( / Amazon Linux AMI ___|\___|___| https://aws.amazon.com/amazon-linux-ami/2013.09-release-notes/ $ rpm -q nginx nginx-1.4.3-1.14.amzn1.x86_64
ちゃんとnginxがインストールされていますね!
Vagrant boxを削除する
Vagrant boxの削除はコマンド一発です。実行するとEC2がTerminateされます。
$ vagrant destroy ==> default: Terminating the instance... ==> default: Running cleanup tasks for 'configspec' provisioner...
まとめ
実は、vagrant-configspecでプロビジョニング後にvagrant-serverspecでテストをする、というストーリーを考えていたのですが、Vagrantfileに
config.vm.provision :configspec do |spec| spec.pattern = 'configspec/*_spec.rb' end config.vm.provision :serverspec do |spec| spec.pattern = 'serverspec/*_spec.rb' end
のような記述をするとエラーが出てしまいました。それぞれ別々に実行する分には問題無く動作したので、何か競合することがあるのかも知れません。ソースも見てみたのですが僕の拙いRuby力では太刀打ち出来ませんでした...
ここまでやった上でアレなんですが、実は最初Dockerを使ったImmutableな構成をやろうとしていたのに、脱線してこういう構成になりました(笑)なので次はDocker + configspecにチャレンジしたいと思います!