注目の記事

vagrant-aws + vagrant-configspecでEC2をプロビジョニングする

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

先日のJAWS DAYS 2014での宮下 剛輔氏のセッション「Immutable Infrastructure時代の構成管理ツール基盤SpecInfra」を拝聴して、「おお、このSpecInfra、勉強してみたい!」と思ったのですが。

まずはその前に試しては壊し試しては壊し出来る、Immutableな環境を作ろう....とアレコレ調べていた結果、まずは「手もとのMac OS Xからvagrant-awsとvagrant-configspecを使ってさくっとEC2をプロビジョニングしてみよう」という結論に至ったので、やってみました!

各種インストール

Vagrant

公式サイトのDownloadページから最新のパッケージファイルをダウンロードして実行します。 vg1現在最新の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-awsvagrant-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にチャレンジしたいと思います!