ブログ

ryuzeeによるブログ記事。不定期更新

Packer + Serverspecでテスト済み仮想マシンイメージを自動で生成する

みなさんこんにちは。@ryuzeeです。

Packerを使うと、VagrantやVMware、Amazon EC2用のAMIなどなどのさまざまな仮想マシンのテンプレートを簡単に作成することができるのはご存知の通りです。

一方で作成した仮想マシンのテンプレートが必要な要件を満たしているかどうかは、仮想マシンのテンプレートを作るたびに検査しなければなりません。

ここでは、PackerとServerspecを組み合わせて、仮想マシンのテンプレートを作成する際に、テストも併せておこなう方法について解説します。

前提

今回仮想マシンのテンプレートを作成するにあたっては以下の方式で行ないます。

  • Packer 0.7.2
  • Packerでの仮想マシンの設定ではChef-SoloのProvisionerを利用
  • CookbookはBerkshelfを使って管理する
  • 作るテンプレートはDocker用のもの(但し他のものでもほとんど変わりません)

また、方式としては、仮想マシンが起動されて、各種セットアップや設定が終わったあとに、その仮想マシン内でServerspecを動作させます。つまり、Packerで仮想マシン内にテスト用のSpecファイルを転送したり、仮想マシン内でServerspecが動作するように設定する必要がある、ということになります。

処理の流れ

ここまでの方式を処理の流れにすると以下のようになります。

  • 予めBerksfileを用意しておき、導入したいCookbookを準備する
  • テンプレート生成の土台となる仮想マシンを起動する
  • Chef-Soloがインストールされていない場合はインストール
  • run_listに記載した内容にしたがってクックブックを適用する
  • 別で用意しておいたテスト用のSpecファイルを転送する
  • 仮想マシン内でServerspecが動作する環境を用意する
  • 仮想マシン内でServerspecを実行する
  • これらが正常に終わったら仮想マシンからテンプレートを生成し、仮想マシンを破棄する

Berksfileの準備

BerksfileとはChefのCookbookを管理するBerkshelf用の設定ファイルです。 以下のような内容になります。

ここでは、導入するCookbookのバージョンやタグを細かく設定しています。これは仮想マシンのテンプレートを後から追跡するときに、どのバージョンのCookbookを利用したのかを把握できるようにしておいた方が良いためです。

source "https://supermarket.getchef.com"

cookbook 'yum', '3.5.1'
cookbook 'apache2-simple', :git => 'git://github.com/ryuzee-cookbooks/apache2-simple.git', ref:"c47d08933d16020f002fdf802ee32a8681c4db66"
cookbook 'memcached', :git => 'git://github.com/ryuzee-cookbooks/memcached.git', ref:"6f32a279cfff3c189a7d16ac3472b77299ce93da"
cookbook 'timezone', :git => 'git://github.com/ryuzee-cookbooks/timezone', ref:"bb758452e4efb83d5608eb51597be0ecc84ec185"
cookbook 'ca-certificates', :git => 'git://github.com/ryuzee-cookbooks/ca-certificates', tag: "v0.1.0"

ここまでできたら、

berks vendor cookbooks

として、ローカル環境にCookbookをダウンロードしておきます。

仮想マシンの起動とプロビジョニング

通常テストなしでテンプレートを作成する場合はこれで準備は終わりです。 ここまででビルドするためには、以下のような、jsonファイルを用意します。

内容自体は特に特筆すべき点はありません。

  • 冒頭で作成する仮想マシンの種類を設定します。ここではDockerを使います。元となるイメージはここでは自作のものを使っていますが、適宜変えてください。
  • provisionersの箇所では仮想マシンの設定をどのようにおこなうかを設定します。ここではChef Soloを使っています。また利用するCookbookは先ほどBerkshelfを使って手元に用意したものを使い、run_listの箇所で適用するCookbookを、jsonの箇所で適宜Attributeを指定しています。
  • post-processorsの箇所では、プロビジョニングなどが終わったあとの処理を指定しており、ここでは最後にDockerのイメージを作成しています。
{
  "builders": [{
    "type": "docker",
    "image": "ryuzee/centos_chef:6.4",
    "run_command": ["-d", "--hostname=packer-sample", "-i", "-t", "{{.Image}}", "/bin/sh"],
    "export_path": "image.tar"
  }],

  "provisioners":[
  {
    "type": "chef-solo",
    "cookbook_paths": ["./cookbooks/"],
    "run_list": ["ca-certificates", "timezone", "apache2-simple", "memcached"],
    "json": {"memcached":{"maxcon":"512","cachesize":"512"}},
    "prevent_sudo": true,
    "skip_install": false 
  }
  ],
  "post-processors": [{
    "type": "docker-import",
    "repository": "ryuzee/packer-sample",
    "tag": "0.1"
  }]
}

ここまでできたら、

packer build docker.json

のようにして仮想マシンを作成します。

Serverspecによるテストを組込み

ここからが肝です。まずChef Soloのプロビジョニングが終わったら、Serverspecが実行できるように準備します。 ここでは、Shell Provisionerを使います。

以下のようなスクリプトを用意し、scripts/serverspec.shに保存してください。

当たり前ですが、Serverspecの動作にはRubyが必要です。Rubyを仮想マシンにインストールしても良いのですが、既にChef Soloを動かすために、/opt/chef/embedded/bin以下にRubyがインストールされていますので、これを使うように設定します。

#!/bin/bash
export PATH=/opt/chef/embedded/bin:$PATH
cd /tmp/tests
bundle install --path=vendor
bundle exec rake spec

(補足)なお、環境によっては(例えばAmazon Linuxなど)では以下のようにsudoを使った形で設定する必要がある場合もあります。

#!/bin/bash
cd /tmp/tests
sudo sh -c "PATH=/opt/chef/embedded/bin:$PATH; bundle install --path=vendor"
sudo sh -c "PATH=/opt/chef/embedded/bin:$PATH; bundle exec rake spec"

また実際のテストやRakefileを用意しないといけませんので、testsディレクトリを作成し、GemfileRakefile.rspec、そして実際のテストを用意します。

Gemfile

source "https://rubygems.org"

gem "rake"
gem "serverspec"

Rakefile

require 'rake'
require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new(:spec) do |t|
  t.pattern = 'spec/*/*_spec.rb'
end

spec/spec_helper.rb

require 'serverspec'

set :backend, :exec

spec/localhost/sample_spec.rb

require 'spec_helper'

describe package('httpd'), :if => os[:family] == 'redhat' do
  it { should be_installed }
end

describe service('httpd'), :if => os[:family] == 'redhat' do
  it { should be_enabled }
  it { should be_running }
end

describe port(80) do
  it { should be_listening }
end

.rspec

--format documentation

ここまでできたら、先ほど用意したpacker用のjsonを以下のように変更しましょう。 追加したのは、テスト関連のファイルを仮想マシン側の/tmp/testsに転送する処理と、用意したscripts/serverspec.shを動作させる箇所です。

{
  "builders": [{
    "type": "docker",
    "image": "ryuzee/centos_chef:6.4",
    "run_command": ["-d", "--hostname=packer-sample", "-i", "-t", "{{.Image}}", "/bin/sh"],
    "export_path": "image.tar"
  }],

  "provisioners":[
  {
    "type": "chef-solo",
    "cookbook_paths": ["./cookbooks/"],
    "run_list": ["ca-certificates", "timezone", "apache2-simple", "memcached"],
    "json": {"memcached":{"maxcon":"512","cachesize":"512"}},
    "prevent_sudo": true,
    "skip_install": false
  },
  {
    "type": "file",
    "source": "tests",
    "destination": "/tmp"
  },
  {
    "type": "shell",
    "script": "scripts/serverspec.sh"
  }
  ],
  "post-processors": [{
    "type": "docker-import",
    "repository": "ryuzee/packer-sample",
    "tag": "0.1"
  }]
}

ここまでの作業のディレクトリ構成は以下のようになっているはずです。

.
├── Berksfile
├── Gemfile
├── docker.json
├── scripts/
│  └── serverspec.sh
└── tests/
    ├── .rspec 
    ├── Gemfile
    ├── Rakefile
    └── spec/
        ├── localhost/
        │  └── sample_spec.rb
        └── spec_helper.rb

ここまでできたら、仮想マシンをビルドしましょう。いつも通り以下のような形でOKです。もしデバッグログが見たい場合は、PACKER_LOG=1を設定してください。

packer build docker.json

ビルドすると、以下のように、Serverspecによるテストが実行されることが分かります!

出力結果

(おまけ) Cookbookに含まれているテストをまとめて実行する方法

この手順を応用すると、利用したCookbookに含まれているテストを全部一気に実行することができます。

やり方は簡単です。Chef Soloプロビジョナーでは、/tmp/packer-chef-solo/cookbooks-0などにCookbookを転送します。したがってこのディレクトリ全体の中の*_spec.rbをテスト実行の対象にすれば良いわけです。 (なお、このパスは元のjsonの設定によって変わります)

require 'rake'
require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new(:spec) do |t|
  t.pattern = '/tmp/packer-chef-solo/cookbooks-0/**/*_spec.rb'
end

これで仮想マシンのテンプレートを作成する際に全部のテストを改めてまとめて実行することもできます。

それでは。

アジャイルコーチングやトレーニングを提供しています

株式会社アトラクタでは、アジャイル開発に取り組むチーム向けのコーチングや、認定スクラムマスター研修などの各種トレーニングを提供しています。ぜひお気軽にご相談ください。

詳細はこちら
  • スクラム実践者が知るべき97のこと
  • 著者/訳者:Gunther Verheyen / 吉羽龍太郎 原田騎郎 永瀬美穂
  • 出版社:オライリージャパン(2021-03-23)
  • 定価:¥ 2,640
  • スクラムはアジャイル開発のフレームワークですが、その実装は組織やチームのレベルに応じてさまざまです。本書はスクラムの実践において、さまざまな課題に対処してきた実践者が自らの経験や考え方を語るエッセイ集です。日本語書き下ろしコラムを追加で10本収録
  • プロダクトマネジメント ―ビルドトラップを避け顧客に価値を届ける
  • 著者/訳者:Melissa Perri / 吉羽龍太郎
  • 出版社:オライリージャパン(2020-10-26)
  • 定価:¥ 2,640
  • プロダクト開発を作った機能の数やベロシティなどのアウトプットで計測すると、ビルドトラップと呼ばれる失敗に繋がります。本書ではいかにしてビルドトラップを避けて顧客に価値を届けるかを解説しています。
  • SCRUM BOOT CAMP THE BOOK 【増補改訂版】
  • 著者/訳者:西村直人 永瀬美穂 吉羽龍太郎
  • 出版社:翔泳社(2020-05-20)
  • 定価:¥ 2,640
  • スクラム初心者に向けて基本的な考え方の解説から始まり、プロジェクトでの実際の進め方やよく起こる問題への対応法まで幅広く解説。マンガと文章のセットでスクラムを短期間で理解できます。スクラムの概要を正しく理解したい人、もう一度おさらいしたい人にオススメ。
  • みんなでアジャイル ―変化に対応できる顧客中心組織のつくりかた
  • 著者/訳者:Matt LeMay / 吉羽龍太郎、永瀬美穂、原田騎郎、有野雅士
  • 出版社:オライリージャパン(2020-3-19)
  • 定価:¥ 2,640
  • アジャイルで本当の意味での成果を出すには、開発チームだけでアジャイルに取り組むのではなく、組織全体がアジャイルになる必要があります。本書にはどうやってそれを実現するかのヒントが満載です
  • レガシーコードからの脱却 ―ソフトウェアの寿命を延ばし価値を高める9つのプラクティス
  • 著者/訳者:David Scott Bernstein / 吉羽龍太郎、永瀬美穂、原田騎郎、有野雅士
  • 出版社:オライリージャパン( 2019-9-18 )
  • 定価:¥ 3,132
  • レガシーコードになってから慌てるのではなく、日々レガシーコードを作らないようにするにはどうするか。その観点で、主にエクストリームプログラミングに由来する9つのプラクティスとその背後にある原則をわかりやすく説明しています。
  • Effective DevOps ―4本柱による持続可能な組織文化の育て方
  • 著者/訳者:Jennifer Davis、Ryn Daniels / 吉羽 龍太郎、長尾高弘
  • 出版社:オライリージャパン( 2018-3-24 )
  • 定価:¥ 3,888
  • 主にDevOpsの文化的な事柄に着目し、異なるゴールを持つチームが親和性を高め、矛盾する目標のバランスを取りながら最大限の力を発揮する方法を解説します
  • ジョイ・インク 役職も部署もない全員主役のマネジメント
  • 著者/訳者:リチャード・シェリダン / 原田騎郎, 安井力, 吉羽龍太郎, 永瀬美穂, 川口恭伸
  • 出版社:翔泳社( 2016-12-20 )
  • 定価:¥ 1,944
  • 米国で何度も働きやすい職場として表彰を受けているメンローの創業者かつCEOであるリチャード・シェリダン氏が、職場に喜びをもたらす知恵や経営手法、より良い製品の作り方などを惜しみなく紹介しています
  • アジャイルコーチの道具箱 – 見える化の実例集
  • 著者/訳者:Jimmy Janlén / 原田騎郎, 吉羽龍太郎, 川口恭伸, 高江洲睦, 佐藤竜也
  • 出版社:Leanpub( 2016-04-12 )
  • 定価:$14.99
  • この本は、チームの協調とコミュニケーションを改善したり、行動を変えるための見える化の実例を集めたものです。96個(+2)の見える化の方法をそれぞれ1ページでイラストとともに解説しています。アジャイル開発かどうかに関係なくすぐに使えるカタログ集です
  • カンバン仕事術 ―チームではじめる見える化と改善
  • 著者/訳者:原田騎郎 安井力 吉羽龍太郎 角征典 高木正弘
  • 出版社:オライリージャパン( 2016-03-25 )
  • 定価:¥ 2,138
  • チームの仕事や課題を見える化する手法「カンバン」について、その導入から実践までを図とともにわかりやすく解説した書籍。カンバンの原則などの入門的な事柄から、サービスクラス、プロセスの改善など、一歩進んだ応用的な話題までを網羅的に解説します。
  • Software in 30 Days スクラムによるアジャイルな組織変革“成功"ガイド
  • 著者/訳者:Ken Schwaber、Jeff Sutherland著、角征典、吉羽龍太郎、原田騎郎、川口恭伸訳
  • 出版社:アスキー・メディアワークス( 2013-03-08 )
  • 定価:¥ 1,680
  • スクラムの父であるジェフ・サザーランドとケン・シュエイバーによる著者の日本語版。ビジネス層、マネジメント層向けにソフトウェア開発プロセス変革の必要性やアジャイル型開発プロセスの優位性について説明
  • How to Change the World 〜チェンジ・マネジメント3.0〜
  • 著者/訳者:Jurgen Appelo, 前川哲次(翻訳), 川口恭伸(翻訳), 吉羽龍太郎(翻訳)
  • 出版社:達人出版会
  • 定価:500円
  • どうすれば自分たちの組織を変えられるだろう?それには、組織に変革を起こすチェンジ・マネジメントを学習することだ。アジャイルな組織でのマネージャーの役割を説いた『Management 3.0』の著者がコンパクトにまとめた変化のためのガイドブック