tl;dr

Windows Server の EC2 AMI を作りたくて Packer を久し振りに触っていたら、テンプレートを修正してビルドして成果物(AMI)を起動して確認するという繰り返しを出来るだけ簡素化したくて Rakefile に落とし込んでみた。(以前に作っていたものを更新した)

作ったもの

packer-operation - Packer で AMI 作成を自動化する試み

github.com

以前に作ったものを AWS SDK v2 で利用出来るようにしたり、Windows Server 対応にしてみた。

memo / demo

簡素化したかったこと

  • packer build を叩く(テンプレートファイルを指定して)
  • 作成されたイメージを利用してインスタンスを起動する
  • 起動したインスタンスの Administrator パスワードを取得する(Windows Server のみ)
  • インスタンスを起動したら、事前に作成しておいた Serverspec の spec ファイルを使ってテスト

使い方は…

  • README を…

Windows Server で AMI 作成、インスタンス起動、Serverspec でテストする demo

  • イメージのビルド
PACKER_TEMPLATE_PATH=~/git/myrepo/packer-windows/template.json rake build

以下のように出力される。

2016/04/03 19:20:24 ui: --> amazon-ebs: AMIs were created:

ap-northeast-1: ami-xxxxxxxx
2016/04/03 19:20:24 waiting for all plugin processes to complete...
--> amazon-ebs: AMIs were created:

ap-northeast-1: ami-xxxxxxxx
2016/04/03 19:20:24 /path/to/bin/packer: plugin process exited
2016/04/03 19:20:24 /path/to/bin/packer: plugin process exited

ビルドが終わったらイメージ名 を確認しておく。(イメージ名を固定しておけば確認は不要)

  • config.yml を作成する

以下のように config.yml に作成したイメージ ID を指定する。また、秘密鍵やセキュリティブループ、サブネット等を指定する。

access_key_id: 'AKxxxxxxxxxxxxxxxxxxxxxxxxxx'
secret_access_key: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
region: 'ap-northeast-1'
user: "username"
key_path: "/path/to/key.pem"
instance_type: "t2.micro"
vpc_subnet: "subnet-xxxxxxxx"
security_group: "sg-xxxxxxxxx"
key_name: "keyname"
tag_name: "tagname"
image_tag_name: "imagename"
user_data_path: "/path/to/userdata.txt"

今のところ userdata は固定。今回のデモでは以下のような userdata を利用する。


tzutil.exe /s "Tokyo Standard Time"
Set-NetConnectionProfile -NetworkCategory Private

  • インスタンスの起動

以下のようにインスタンスを起動。

rake ec2:launch

#wait_until メソッドでインスタンスステータスが Running になるまで待つ。そして、Windows の場合には Administrator パスワードが取得可能な状態になるまで待つ。その場合には以下のように実行することでパスワードが取得可能であるかを確認することが出来る。

rake ec2:getpw

パスワードが取得出来ない場合には以下のように出力される。

password_data empty

体感で 10 分位待てばパスワードが取得可能な状態になる。

尚、インスタンスの情報は確認する必要がない。SSH や RDP でアクセスする必要があれば、マネジメントコンソールや API で確認する。(これも rake コマンドで叩けるようにしておこう)

  • Serverspec を実行する準備

今回は Windows Server が対象になるので、以下のように実行する。

rake genspec:win

実行すると、以下のようにカレントディレクトリの spec/ 以下に spec_helper.rb と対象となるインスタンスのディレクトリが作成され、spec ファイルが作成(コピー)される。

got password
rm -rf ./spec/ec*
Created ./spec//spec_helper.rb
Created ./spec/ec2-xx-xxx-xx-xxx.ap-northeast-1.compute.amazonaws.com/common_spec.rb

ファイル構成は以下の通り。

% tree spec
spec
├── ec2-xx-xxx-xx-xxx.ap-northeast-1.compute.amazonaws.com
│   └── common_spec.rb
└── spec_helper.rb
  • Serverspec 実行
rake spec:ec2-xx-xxx-xx-xxx.ap-northeast-1.compute.amazonaws.com

以下のように出力される。

ExecutionPolicy が RemoteSigned になっている場合...
  Command "powershell -Command "Get-ExecutionPolicy""
    stdout
      should match /RemoteSigned/

NetConnectionProfile が Private になっている場合...
  Command "powershell -Command "Get-NetConnectionProfile | select -First 1 NetworkCategory -ExpandProperty NetworkCategory""
    stdout
      should match /Private/

(略)

Time Zone が Tokyo Standard Time に設定されている場合...
  Command "powershell -Command "tzutil.exe /g""
    stdout
      should match /Tokyo Standard Time/

Finished in 7.4 seconds (files took 2.14 seconds to load)
6 examples, 0 failures

テストが通ったところでメデタシメデタシ。インスタンスを破棄しましょう。

  • インスタンスの破棄
rake ec2:terminate

インスタンス起動時と同様に #wait_until メソッドでターミネートされる状態を待つ。

おわり

  • CI ツールで利用出来ないか妄想中
  • Rakefile は汚いし、Ruby を理解していないので更に汚い
  • AWS SDK v2 は直感的で使い易いと思った

これで Packer を使ってパカパカ出来る!(かも)

元記事はこちら

Packer をパカパカしたくて Rakefile を作って Windows Server の AMI を作成して Serverspec でテストするメモ