Packer とは
サーバーイメージを作成するためのツールです
AWSであればAMI、Azureであれば arm を作成します
Vagrant を開発している HashiCorp社 が開発しているツールなので使用感は Vagrant と同じような感じです
構築済みのサーバーイメージをAMIとして作成しておき、これをベースとしてインスタンスを立ち上げるのはよくあるパターンだと思います
※ "ゴールデンイメージ" というインフラパターンらしいです
ただ、このAMIがどうやって作られたか?がわからなくなりがちなのですが、Packerを使うことでAMI構築手順を全てコード化することができます
TL;DR
json ファイルに定義内容を記述し、$ packer build hoge.json
を実行するだけで定義内容の通りに自動でサーバーイメージを作成してくれます
インストール
以下に従って OS 毎のビルド済みバイナリをダウンロードしてきてパスを通すだけです
https://www.packer.io/downloads.html
Mac の場合
Mac の場合は Homebrew でインストールできます
$ brew update
$ brew install packer
AWS での使い方
事前準備
IAM ユーザーを作る
aws cli を利用するための アクセスキーを取得します
管理者に依頼して IAM ユーザーを作成してもらってください
https://console.aws.amazon.com/iam/home?#/home
利用したい AWS サービス(EC2だけかな?)に対しての操作権限をつけてもらう必要があります
AWS CLI をセットアップする
以下を参考に aws コマンドを使えるように設定する
http://docs.aws.amazon.com/ja_jp/streams/latest/dev/kinesis-tutorial-cli-installation.html
$ aws configure
で認証情報をセットした後であれば、Pakcer からはこのAWS認証情報を参照してくれます
※~/.aws/credentials
にAWSの認証情報が保存されます
AMIを作成する
1. json ファイルを作成する
例として以下の AMI を作成する定義を見てみましょう
項目 | 設定値 | メモ |
---|---|---|
リージョン | ap-northeast-1 (東京) | |
ベースのAMI | 公式 ubuntu 16.04 の最新版 | |
インスタンスタイプ | t2.micro | |
ssh ユーザー名 | ubuntu | |
AMIの名前 | Packer test YYYY-MM-DDThh-mm-ssZ | 作成時のタイムスタンプがセットされる |
ディスク | 30GB、gp2 の EBS を /dev/sda1 として接続 | |
初期化コマンド | apt update を実行してから python-simplejson をインストール |
この AMI 定義は以下のように json ファイルで書きます
定義できる項目は packer のドキュメントを参照のこと
https://www.packer.io/docs/builders/amazon.html
{
"builders": [{
"type": "amazon-ebs",
"region": "ap-northeast-1",
"source_ami_filter": {
"filters": {
"virtualization-type": "hvm",
"name": "*ubuntu-xenial-16.04-amd64-server-*",
"root-device-type": "ebs"
},
"owners": ["099720109477"],
"most_recent": true
},
"instance_type": "t2.micro",
"ssh_username": "ubuntu",
"ami_name": "Packer Test {{isotime | clean_ami_name}}",
"launch_block_device_mappings": [{
"delete_on_termination": true,
"device_name": "/dev/sda1",
"volume_size": 10,
"volume_type": "gp2"
}]
}],
"provisioners": [{
"type": "shell",
"inline": [
"sudo apt update",
"sudo apt install -y python-simplejson",
"sudo echo `date`' - packer provisioned this AMI' > /home/ubuntu/packer_provisioners"
]
}]
}
2. 構文チェック
$ packer validate
を実行すると構文チェックされます
$ packer validate packer-example.json
以下のメッセージが出力されれば構文チェックはOKです
Template validated successfully.
もしエラーがある場合はエラーメッセージが出力されます
$ packer build packer-example.json
Failed to parse template: Error parsing JSON: invalid character '"' after object key:value pair
At line 4, column 6 (offset 49):
3: "type": "amazon-ebs"
4: "
^
3. ビルド実行
$ packer build
を実行して AMI をビルドします
$ packer build packer-example.json
初期化タスクの内容にもよりますが AMI ビルドには数分かかります
以下のように AMIs were created
と出力されればビルド成功です
・・・
Build 'amazon-ebs' finished.
==> Builds finished. The artifacts of successful builds are:
--> amazon-ebs: AMIs were created:
ap-northeast-1: ami-c5f49528
ビルド中 EC2 のコンソールを開くと "Packer Builder" というインスタンスが起動されて、このインスタンス内で処理が実行され定義した内容の AMI が作成されます
ビルドが完了すると以下のように AMI が追加されていることが確認できます
[Advanced] イメージの初期化処理を Ansible でやる
packer で provisioners で設定したタスクによりイメージの初期化を行うことができます
https://www.packer.io/docs/provisioners/index.html
↑のサンプルでは Shell Provisioner を使うことで、イメージとなるインスタンスの内部で指定されたシェルコマンドが実行されていたということです
Ansible Provisioner というのを使うと、初期化タスクを ansible に任せることができます
先ほどの packer-example.json
を修正し Provisioner に ansible を指定します
playbook_file
に指定された playbook に沿って ansible が実行されます
※playbook の書き方はここでは割愛します
{
"builders": [{
"type": "amazon-ebs",
"region": "ap-northeast-1",
"source_ami_filter": {
"filters": {
"virtualization-type": "hvm",
"name": "*ubuntu-xenial-16.04-amd64-server-*",
"root-device-type": "ebs"
},
"owners": ["099720109477"],
"most_recent": true
},
"instance_type": "t2.micro",
"ssh_username": "ubuntu",
"ami_name": "Packer Ansible Example {{isotime | clean_ami_name}}",
"launch_block_device_mappings": [{
"delete_on_termination": true,
"device_name": "/dev/sda1",
"volume_size": 30,
"volume_type": "gp2"
}]
}],
"provisioners": [{
"type": "shell",
"inline": [
"sudo apt update",
"sudo apt install -y python-simplejson"
]
}, {
"type": "ansible",
"playbook_file": "./ansible/playbook.yml"
}]
}