cloudpack の 自称 Sensu芸人 の かっぱこと 川原 洋平@inokara)です。


はじめに

前回は初めて Packer ということでシンプルな EC2AMI を作ってみましたが、も少し手心を加えたいので Chef Solo を利用して手心を加えた AMI を作ってみたいと思います。



provisioner に Chef Solo を利用する


選べる provisioner

Packer でイメージを作成する際に手心を加えるのが provisioner です。手心の加え方は様々で以下のような加え方があります。

好きなの選んでください。

尚、provisionertemplate 内では例えば Shell の場合には以下のように指定します。

  "provisioners": [{
    "type": "shell",
    "inline": [
      "command1",
      "command2"
    ]
  }]

Chef Solo の場合には以下のように指定します。

  "provisioners": [{
    "type": "chef-solo",
    "cookbook_paths": ["./cookbooks/"],
    "run_list": ["yum-epel", "sensu-uchiwa-chef"],
    "prevent_sudo": false
  }]

Chef Solo を利用する場合、上記以外にもオプションは多数ありますので詳しくはドキュメントはもちろん、こちらこちらで詳しく解説頂いているので御覧ください。


Cookbook を指定する

今回は Uchiwa をインストールする cookbook を作って利用します。template には以下のように指定します。

  {
    "type": "chef-solo",
    "cookbook_paths": ["./cookbooks/"],
    "run_list": ["yum-epel", "sensu-uchiwa-chef"],
    "prevent_sudo": false
  }

カレントディレクトリの cookbooks を指定して、必要になる cookbookrun_list として指定します。prevent_sudofalse にしているのは、今回は元となるイメージには root でログインして処理を行うので false にしました。


ちょっとした後処理を指定する

Cookbook を使ってセットアップした後に、下記のような処理も入れておきたいと思います。

  • iptables の設定(今回は停止した)
  • インスタンス内の時刻を日本時間にする
  • motduchiwa Linux という文字を入れる
  • /root/.ssh/authorized_keys を削除

以下のように shellprovisioner を追加しました。

  {
    "type": "shell",
    "inline": [
      "/etc/init.d/iptables stop",
      "chkconfig iptables off",
      "cp /usr/share/zoneinfo/Japan /etc/localtime",
      "cp /etc/motd /etc/motd.original",
      "echo 'uchiwa Linux' < /etc/motd",
      "rm -f /root/.ssh/authorized_keys"
    ]
  }

provisioner は複数設定することが出来、逐次上から実行されるようです(このあたりの順番とかかなり気になります…)


template

結局、以下のような template となりました。

{
  "variables": {
    "aws_access_key": "AK123456789123456789",
    "aws_secret_key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  },
  "builders": [{
    "type": "amazon-ebs",
    "access_key": "{{user `aws_access_key`}}",
    "secret_key": "{{user `aws_secret_key`}}",
    "region": "us-east-1",
    "source_ami": "ami-eb6b0182",
    "instance_type": "t1.micro",
    "ssh_username": "root",
    "ami_name": "uchiwa {{timestamp}}"
  }],
  "provisioners": [{
    "type": "chef-solo",
    "cookbook_paths": ["./cookbooks/"],
    "run_list": ["yum-epel", "sensu-uchiwa-chef"],
    "prevent_sudo": false
    },{
    "type": "shell",
    "inline": [
      "/etc/init.d/iptables stop",
      "chkconfig iptables off",
      "cp /usr/share/zoneinfo/Japan /etc/localtime",
      "cp /etc/motd /etc/motd.original",
      "echo 'uchiwa Linux' < /etc/motd",
      "rm -f /root/.ssh/authorized_keys"
    ]
  }]
}


作ってみよう


Berksfile の用意と依存する Cookbook を準備する

今回は [yum-epel] という Cookbook と自作の sensu-uchiwa-chef という Cookbook を使いますので Berksfile のお出ましとなります。


作業のディレクトリを作成して template を置く

mkdir /path/to/working
vim /path/to/working/example.json


Berksfile

次に以下のように Berksfile を用意します。

source "https://api.berkshelf.com"

cookbook "yum-epel"
cookbook "sensu-uchiwa-chef", :path =< "/path/to/sensu-uchiwa-chef"


berks vendor

次に berks vendor を実行して依存する Cookbookcookbooks ディレクトリ以下に置きます。

berks vendor cookbooks

以下のようなディレクトリ構成となります。

.
├── Berksfile
├── Berksfile.lock
├── cookbooks
└── example.json

1 directory, 3 files


packer build

準備は整いましたので packer build してみましょう。

cd /path/to/working
packer build example.json

しばらく待ちましょう…。

packer-provisioner-chef-solo-uchiwa-ami_01


AMI の確認


マネジメントコンソールで

packer-provisioner-chef-solo-uchiwa-ami_02

出来てますね。


aws-cli で

aws ec2 describe-images --filters "Name=name,Values=uchiwa*"

以下のように出力されます。

packer-provisioner-chef-solo-uchiwa-ami_03

出来てますね。



AMI からインスタンスを起動してみる


Serverspec によるテスト

こちらのような spec ファイルを用意してテストを実行します。

rake spec SPEC_OPTS="-fd --color"

以下のように全てのテストが Success でした。

packer-provisioner-chef-solo-uchiwa-ami_04


uchiwa にアクセスしてみる

ブラウザを使って uchiwa にもアクセスしてみましょう。

packer-provisioner-chef-solo-uchiwa-ami_05

起動しているインスタンスの 8999 ポートにアクセスすると…上記のように uchiwa にアクセスすることが出来ました。sensu api の設定を行っていないので上記のような表示になっていますが、AMI 化したインスタンスにアクセスすることが出来ました。



まとめ


やったこと

  • provisionerChef SoloShell を使って uchiwa が起動する AMI を作成しました
  • 作成した AMI からインスタンスを起動して Serverspec を使ってインスタンスが正しく設定されているかを確認しました


学んだこと

  • provisionerChef Solo を使う際のお作法について知ることが出来ました
  • provisioner を複数組み合わせることが出来ることを知りました


今後は…

  • cookbook を修正して GitHub にコミットしたら自動で AMI を生成するような流れを作ってみたいと思います
  • 他の Builder も試してみたいです

元記事は、こちら