PackerでAWS、Vagrant用のCentOSのVMイメージを同時に生成する


## 概要

[Packer](http://www.packer.io/)を使うと、VMイメージの生成が自動化できてとても便利です。

最近だと、ローカルでは[Vagrant](http://www.vagrantup.com/)を使って開発をして、AWSへデプロイするなど、VM環境をまたいで開発、デプロイをすることが多くなり、VMの生成を統一し、自動化したいというニーズが増えてきているのではないかと思います。

Packerを使って、各VM環境毎のセットアップ手順を共通化しておくことで、開発、ステージング、プロダクション等の環境の間の違いをなくし、デプロイ時の不具合を最小化することが出来るようになります。

Packerは、JSON形式のファイルを用いて、設定を記述していきます。
下記の設定を用いると、AWS及びVagrantbox用のCentOS 6のVMイメージが並列に生成できます。

```json:centos6.json
{
  "variables": {
    "aws_access_key": "{{env `AWS_ACCESS_KEY`}}",
    "aws_secret_key": "{{env `AWS_SECRET_ACCESS_KEY`}}"
  },
  "builders": [
    {
      "name": "centos6-aws",
      "type": "amazon-ebs",
      "ami_name": "CentOS6_x64_ebs_{{isotime | clean_ami_name}}",
      "access_key": "{{user `aws_access_key`}}",
      "secret_key": "{{user `aws_secret_key`}}",
      "region": "ap-northeast-1",
      "source_ami": "ami-31e86030",
      "instance_type": "t1.micro",
      "ssh_username": "root",
      "ssh_timeout": "5m"
    },
    {
      "name": "centos6-vagrantbox",
      "type": "virtualbox-iso",
      "headless": false,
      "guest_os_type": "RedHat_64",
      "disk_size": 100000,
      "iso_url": "http://mirrors.kernel.org/centos/6.5/isos/x86_64/CentOS-6.5-x86_64-minimal.iso",
      "iso_checksum": "f21a71e8e31df73297bdd1ccd4a64a36831284bd",
      "iso_checksum_type": "sha1",
      "boot_wait": "12s",
      "http_directory": "scripts/centos6-vagrantbox/http",
      "guest_additions_path": "VBoxGuestAdditions_{{.Version}}.iso",
      "virtualbox_version_file": ".vbox_version",
      "ssh_username": "root",
      "ssh_password": "ytWV6EaJz9fkqa",
      "ssh_wait_timeout": "10000s",
      "vboxmanage": [
        ["modifyvm", "{{.Name}}", "--memory", "512"],
        ["modifyvm", "{{.Name}}", "--cpus", "1"]
      ],
      "boot_command": [
        "<tab> text ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ks.cfg<enter><wait>"
      ],
      "shutdown_command": "/sbin/halt -h -p"
    }
  ],
  "provisioners": [
    {
      "type": "shell",
      "inline": [
        "yum -y update",
        "iptables -F INPUT",
        "iptables -F FORWARD",
        "iptables -F OUTPUT",
        "service iptables save"
      ]
    },
    {
      "type": "shell",
      "inline": [
        "rm -f /root/.ssh/authorized_keys",
        "iptables -A INPUT -i lo -j ACCEPT",
        "iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT",
        "iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT",
        "iptables -P INPUT DROP",
        "service iptables save"
      ],
      "only": [
        "centos6-aws"
      ]
    },
    {
      "type": "shell",
      "scripts": [
        "scripts/centos6-vagrantbox/vagrant.sh",
        "scripts/centos6-vagrantbox/vboxguest.sh",
        "scripts/centos6-vagrantbox/compact.sh"
      ],
      "only": [
        "centos6-vagrantbox"
      ]
    }
  ],
  "post-processors": [
    {
      "output": "centos6-x86_64_{{isotime}}.box",
      "type": "vagrant",
      "only": [
        "centos6-vagrantbox"
      ]
    }
  ]
}
```

Packerがインストールされていれば、下記コマンドで実行できます。

```
$ git clone https://github.com/ikuyamada/centos-packer-example
$ cd centos-packer-example
$ export AWS_ACCESS_KEY=YOUR_ACCESS_KEY
$ export AWS_SECRET_ACCESS_KEY=YOUR_SECRET_KEY
$ packer build centos6.json
```

実行結果として、AWSは、timestampの入ったAMIが自動的に登録され、Vagrantは、該当するVagrantboxファイルが、カレントフォルダに生成されます。

Vagrantboxについては、VirtualboxでISOイメージからビルドしており、いくつかのシェルスクリプトを使っています。また、AWSでは、リモートに立てる蝉蛻で、SSH(ポート22)へのインバウンド接続以外は全て外部からの接続をDROPするiptablesを設定しています。

ここで作成しているイメージは最低限のものなので、各利用用途に応じて、[Provisioner](http://www.packer.io/docs/templates/provisioners.html)を追加することでカスタマイズすることが前提です。Packerの場合は、Chef、Puppet、Ansibleなど使えるので、こちらも構成を自動化して管理しておくと便利だと思います。

## ソースコード

上記ソースコードはGitHub上に公開されています。
https://github.com/ikuyamada/centos-packer-example


## その他補足
* AWSは、リージョンは東京リージョン(`ap-northeast-1`)、ベースとなるAMIはCentOS 6の公式AMI(東京リージョン)である`ami-31e86030`を指定しています。
* Vagrantboxでは、CentOS6.5のISOイメージをダウンロードして、Virtualboxを使ってインストールしています。