2017年9月22日金曜日

packer のビルドフロー中に serverspec でテストする方法

概要

packer の provisioners でインストールしたパッケージなどを serverspec でテストしたということはよくあると思います
イメージなどを作成後に VM として起動して serverspec を実行する手法はよくあると思いますが少し面倒くさいです
今回は packer build 内で serverspec を実行する方法を紹介したいと思います

環境

  • macOS X 10.12.6
  • packer 1.0.4
  • go 1.8
  • serverspec 2.40.0

serverspec 準備

今回は serverspec のテストも 1 から作成してみたいと思います

  • bundle init
  • vim Gemfile
gem "serverspec"
  • bundle install
  • serverspec-init
  1) UN*X
  2) Windows

Select number: 1

Select a backend type:

  1) SSH
  2) Exec (local)

Select number: 2

 + spec/
 + spec/localhost/
 + spec/localhost/sample_spec.rb
 + spec/spec_helper.rb
 + Rakefile
 + .rspec

ここで 1 つポイントですが実行するホストは localhost にしましょう
要するにビルド中に作成された VM (localhost) に対して実行するようにします

  • vim spec/localhost/sample_spec.rb
require 'spec_helper'

describe package('httpd'), :if => os[:family] == 'redhat' do
  it { should be_installed }
end
  • vim spec/spec_helper.rb
require 'serverspec'
require 'net/ssh'

options = Net::SSH::Config.for(host, [])
options[:user] = ENV['TARGET_USER']
options[:keys] = ENV['TARGET_KEY']
options[:host_name] = ENV['TARGET_HOST']
options[:port] = ENV['TARGET_PORT']
options[:paranoid] = false unless ENV['SERVERSPEC_HOST_KEY_CHECKING'] =~ (/^(true|t|yes|y|1)$/i)

set :host,         options[:host_name]
set :ssh_options,  options
set :backend,      :ssh
set :display_sudo, true
set :request_pty,  true

sample_spec.rb と spec_helper.rb はとりあえず上記をそのまま利用してください

プラグインのインストール

今回 Github で公開されている packer-provisioner-serverspec を使います

  • go get github.com/unifio/packer-provisioner-serverspec
  • mkdir $HOME/.packer.d/plugins
  • cp $GOPATH/bin/packer-provisioner-serverspec $HOME/.packer.d/plugins

で OK です

テンプレートファイルの作成

  • vim centos7_with_serverspec.json
{
    "builders": [
    {
        "type": "virtualbox-iso",
        "vboxmanage": [
        [ "modifyvm", "{{.Name}}", "--memory", "2048" ],
        [ "modifyvm", "{{.Name}}", "--nic1", "nat" ],
        [ "modifyvm", "{{.Name}}", "--nic2", "hostonly" ],
        [ "modifyvm", "{{.Name}}", "--hostonlyadapter2", "vboxnet0"]
        ],
        "iso_checksum": "27bd866242ee058b7a5754e83d8ee8403e216b93d130d800852a96f41c34d86a",
        "iso_checksum_type": "sha256",
        "iso_url": "http://ftp.riken.jp/Linux/centos/7/isos/x86_64/CentOS-7-x86_64-Minimal-1611.iso",
        "ssh_username": "root",
        "ssh_password": "password",
        "ssh_wait_timeout": "40m",
        "disk_size": "8000",
        "guest_os_type": "RedHat_64",
        "shutdown_command": "/sbin/shutdown -h now",
        "shutdown_timeout": "20s",
        "vm_name": "centos7_from_packer",
        "boot_command": [
        "<tab> text ks=http://192.168.56.101/centos.ks<enter><wait>"
        ]
    }
    ],
    "provisioners": [
    {
        "type": "shell",
        "inline": ["yum install -y vim httpd"]
    },
    {
        "type": "serverspec",
        "rake_file": "Rakefile",
        "rake_task": "spec:all",
        "rake_env_vars": "$BUNDLE_GEMFILE=Gemfile"
    }
    ]
}

基本は過去に CentOS7 をビルドしたテンプレートを使っています
またテンプレートを作成する場所は serverspec-init を実行したパスと同じ場所に配置してください

ポイントは provisioners に "type": "serverspec" が追加されている点です
プラグインをインストールすることでこのタイプが使えるようになります

また、今回は OS のインストールも自動化することを想定しているので kickstart サーバも使っています
kickstart サーバの構築に関してはこちらを御覧ください

動作確認

  • packer build centos7_with_serverspec.json

でいろいろとログが流れます
長いので割愛しますが流れとしては

ISO 取得 -> VM 起動 -> OS インストール -> SSH 接続 -> provisioner 実行 (yum) -> provisioner 実行 (serverspec)

になります
最終的に serverspec が実行されてエラーが出なければ成功です

試しに作成されたイメージを一度起動して VM の中を確認してみましょう
(今回は Virtualbox を使っているので仮想アプライアンスのインポートから作成された ovf を選択すれば OK です)
今回の場合であれば httpd がインストールされていれば OK となります
また、今回の手順の場合作成されたイメージないに serverspec コマンドはインストールされません
packer_with_serverspec1.png

最後に

プラグインを使って packer + serverspec でビルド中にイメージのテストを実施してみました
こっちのほうが手順としても packer build 1 回で済むのでスマートかなと思います

いろいろと調べてみると packer + serverspec を連携する方法は出てきますがビルドするイメージ内に serverspec をインストールする方法が結構多いです
それでも特に問題はないですが ruby など使わないのであれば、あまり入れたいとは思いません
今回の手順はイメージ内に serverspec をインストール必要がないのも嬉しい点かなと思います

少し心配な点があるとすれば今回使ったプラグインがあまりメンテナンスされていない点でしょうか、、、

参考サイト

0 件のコメント:

コメントを投稿