PackerでAWS AMIを自動で作成する
AWS AMIの管理は面倒
AWSでEC2(IaaS)使ったアプリケーションを構築する時に、AMIの管理が地味に面倒です。例えば、AWS側から提供されているAMIをそのまま使うと、OSがデフォルトに近い状態なので、アプリケーションの実行に必要なものを準備する必要があります。
そこで、実行するために必要な準備を完了させているAMIを作成して、それを使ってインスタンスを作成して、アプリケーションコードを反映するだけで、すぐに使える状態にするということをします。
ただ、これをするのが地味に面倒です。やり方とかは以下の記事に詳しくあります。 tikasan.hatenablog.com
ざっくりいうと、出来上がってるインスタンスからスナップショットを作成して、スナップショットからAMIを作成して、AMIを使ってインスタンスを作成するという手順を踏む必要があります。
これらを自動でやってくれるのが、Packerです。
Packerとは
AWSマネジメントコンソールを使わず、AMIの作成の手順を単純化してくれます。また、プロビジョニング機能があったり、並列実行が出来たりするそうです。
アーティファクト
Packerは最終生成物として、アーティファクトを作成します。アーティファクトとは、Packer独自の抽象化されたマシンイメージの概念のことです。
AWSでいうところのAMIやAMI IDや管理情報。
アーティファクトの作成には、以下の機能を使って作成することができます。(番号は実行順序です)
- ビルダー(builder)
マシンイメージの生成。JSONでテンプレートを定義し、自動で良い感じにしてくれる - プロビジョナー(provisioner)
マシンイメージ内のミドルウェアやアプリケーションのインストールや設定などを行う。ここではシェルスクリプトはもちろんChefなどの構成管理ツールを実行することもできます - ポスト・プロセッサー(post-processor)
ここでは、最終的な生成物をどうするかということをやる(圧縮とかアップロードとか)
実際にやってみる
インストールはここ見ればわかる Install Packer - Getting Started - Packer by HashiCorp
$ touch hello_ami.json
{ "variables": { "aws_access_key": "hoge", "aws_secret_key": "fuga" }, "builders": [ { "type": "amazon-ebs", "access_key": "{{user `aws_access_key`}}", "secret_key": "{{user `aws_secret_key`}}", "region": "ap-northeast-1", "source_ami": "ami-06128816a1c781a57", "instance_type": "t2.micro", "ssh_username": "root", "ami_name": "hello_ami {{timestamp}}" } ] }
❯ packer build hello_ami.json amazon-ebs output will be in this color. ==> amazon-ebs: Prevalidating AMI Name: hello_ami 1529395142 amazon-ebs: Found Image ID: ami-06128816a1c781a57 ==> amazon-ebs: Creating temporary keypair: packer_5b28b7c6-9716-5682-837a-45051c4baae6 ==> amazon-ebs: Creating temporary security group for this instance: packer_5b28b7c7-913b-2b6d-fa7d-f2dcf8a51770 ==> amazon-ebs: Authorizing access to port 22 from 0.0.0.0/0 in the temporary security group... ==> amazon-ebs: Launching a source AWS instance... ==> amazon-ebs: Adding tags to source instance amazon-ebs: Adding tag: "Name": "Packer Builder" amazon-ebs: Instance ID: i-0284843a27b02a39c ==> amazon-ebs: Waiting for instance (i-0284843a27b02a39c) to become ready... ==> amazon-ebs: Waiting for SSH to become available... ==> amazon-ebs: Connected to SSH! ==> amazon-ebs: Stopping the source instance... amazon-ebs: Stopping instance, attempt 1 ==> amazon-ebs: Waiting for the instance to stop... ==> amazon-ebs: Creating the AMI: hello_ami 1529395142 amazon-ebs: AMI: ami-02749c4f55b57389c ==> amazon-ebs: Waiting for AMI to become ready... ==> amazon-ebs: Terminating the source AWS instance... ==> amazon-ebs: Cleaning up any extra volumes... ==> amazon-ebs: No volumes to clean up, skipping ==> amazon-ebs: Deleting temporary security group... ==> amazon-ebs: Deleting temporary keypair... Build 'amazon-ebs' finished. ==> Builds finished. The artifacts of successful builds are: --> amazon-ebs: AMIs were created: ap-northeast-1: ami-02749c4f55b57389c
AMIが作成できました!便利すぎる!w
作成するために使ったEC2インスタンスは自動的に削除までされています。
www.packer.io とりあえず、雑に作成しましたが、Builderに必要な権限やクレデンシャルの設定方法は公式見れば分かります。
プロビジョニングは以下のような感じで軽く書ける。
{ "variables": { "aws_access_key": "hoge", "aws_secret_key": "fuga" }, "builders": [ { "type": "amazon-ebs", "access_key": "{{user `aws_access_key`}}", "secret_key": "{{user `aws_secret_key`}}", "region": "ap-northeast-1", "source_ami": "ami-06128816a1c781a57", "instance_type": "t2.micro", "ssh_username": "root", "ami_name": "hello_ami {{timestamp}}" } ], "provisioners": [ { "type": "shell", "inline": [ "sleep 30", "sudo apt-get update", "sudo apt-get install -y redis-server" ] } ] }
sleep30を最初に書く理由は、ちょっと準備出来るまで余裕ほしいという文脈らしい。なるほど。 www.packer.io
AMI作成自動化最高。