Packer で OpenStack のイメージを作ってみた

Packer で OpenStack のイメージを作ってみた

Packer で OpenStack のイメージを作ってみたので,その知見を共有します。

Packer とは

かんたんに, Packer について説明します。 Packer とは, Json で記述された template を元に,クラウドなどで動作するイメージを作ってくれる子です。

Packer のために,記述する Template には Builder と Provisioner というセクションがあります。 それぞれについて,説明していきます。

Builder

これは,イメージを作成するために,どんな環境を,どのように利用するのかを指定します。 環境には, OpenStack や Amazon EC2, Docker などがあります。 そして,それぞれの環境にどのようにアクセスするのかを指定します。

Provisioner

これは,作成したイメージにプロビジョニングするための設定を書くセクションです Puppet や Chef 等を利用できます。

作ってみるぞ!

それでは,上で説明した事を利用して,イメージを実際に作っていきます。 利用したコードは,下記のようになります。

{
  "builders": [
    {
      "type": "openstack",
      "flavor": "m1.small",
      "networks": "xxxxxxxxxxxxxxxxx",
      "ssh_interface": "eth0",
      "floating_ip" : "xxxxxxxxxxxxxxxxx",
      "security_groups": ["xxxxxxxxxxxxxxxxx", 
                          "xxxxxxxxxxxxxxxxx"],
      "availability_zone": "xxxx",
      "ssh_username": "centos",
      "image_name": "{{user `role`}}_centos7_{{user `date`}}",
      "source_image": "xxxxxxxxxxxxxxxxx",
      "user_data_file": "user_data"
    }

  ],

  "provisioners": [
    {
      "type": "puppet-server",
      "puppet_bin_dir": "/opt/puppetlabs/bin/",
      "puppet_server": "puppetserver.xxx.com",
      "options": "--test --certname={{uuid}} --environment={{user `environment`}}",
      "facter": {
         "role": "{{user `role`}}"
      }
    }
  ]
}

Builder セクションの type に OpenStack を指定すると,source_image に指定したイメージで,OpenStackにインスタンスが起動します。 その後,起動したインスタンスに対して, SSH でログインし, Provisioner セクションで指定した方法でプロビジョニングしていきます。

ですので, Builder セクションでは, Packer を利用した場所から SSH ができるような設定が必用で, ssh_username や ssh_interface , security_groups などがその設定に当たります。

Provisioner セクションでは, puppet を利用するために必用な設定を行います。

注意事項として, Provisioner ではプロビジョニングに利用するツールをインストールしてくれるわけではないので,もととなるイメージに Puppet が含まれているか, cloud-init などでインストールする必要があります。

今回は cloud-init でインストールしました。

#cloud-config
bootcmd:
    - rpm -Uvh https://yum.puppetlabs.com/puppetlabs-release-pc1-el-7.noarch.rpm
    - yum install -y puppet-agent

また, Packer には, User Variable という機能があって,コマンドライン引数や,環境変数から Packer templateに情報を渡すことができます。

今回は,コマンドライン引数から渡したいので

 "options": "--test --certname={{uuid}} --environment={{user `environment`}}",

の用に書いています。

packer build -var 'role=xxx' -var 'environment=xxx' -var \
       'date=`date +"%Y-%m-%d-%H-%M-%S"`' template.json

などのように実行すると,コマンドライン引数で指定した値が {{user environment}} などのようにかれた箇所で利用されます。

{{uuid}}

にはランダムな値が入ります。 こうしておかないと, 同じ証明書が Puppet で使いまわされることになり,Puppet で怒られます。


幾つか, Packer Template の記法で悩むことはありましたが,割とシュッとできたな,という所感です。 今は,最低限のプロビジョニングが施された,基本となるイメージしか作成できていませんが,Role ごとにプロビジョニングされたイメージを作ることで スケールアウトのために時間が短縮できたらな,と考えています。

以上です。