⚰️

これからPackerを使うあなたへ

2021/03/14に公開

はじめに

みなさん、Packer使ってますか?
私自身は業務で使うことがあるんですが、ちょっとしたことを調べたいときにぴったりなドキュメントがあればいいんですが、公式ドキュメントを見に行くことがほとんどで...
(それはそれであながち間違ってはいない、むしろ正しいと書きながら思った次第です)

既に使ってる人や理解している人なら、公式ドキュメントは理解しやすいと思うんですが
これから始める人たちにとって公式ドキュメントってとっつきにくい感じがするんですよね...

こうゆうドキュメントが増えて、Packerを使う人が少しでも増えたらいいなと思った次第です

Packerって?

マシンイメージの作成を自動化 してくれるソフトウェアです
(TerraformやVagrantを提供しているHashiCorp製)

https://www.packer.io/

  • テンプレート(コード)で環境を管理できる
  • jsonで良い!(プログラムの知識いらないのよ)
    • バージョンが 1.7.0 からHCL2(HashiCorp Configuration Language)が推奨
  • AnsibleやChefなどのプロビジョニングツールと連携できる
  • ・・・あと何か!(急に雑になります)

とりあえず、便利なソフトウェアと思っていただければと思います!

インストール

今回は プリコンパイルされたバイナリ をダウンロードし、解凍して使えるようにします

インストールの手順は Packerのチュートリアルページ 通りにやります
手順は以下の3ステップ(ホップステップジャンプ)

  • zipファイルをダウンロード(環境にあうやつ)
  • 解凍
    • unzipやツール
  • PATHが通っている場所に移動
    • mvやなんかで(雑)

私はMacやLinuxを普段触っているので /usr/local/bin に置きました
Windowsの場合は、Packerを置いたパスをシステム環境変数に追加してください

バージョン表示
$ packer --version

バージョンが表示されれば、インストールが完了しています(PATHが通っています)

テンプレート

マシンイメージを作成するために、Packerのさまざまなコンポーネントを構成するものです

jsonテンプレートの構成

jsonテンプレートの構成について公式ページから噛み砕いて記載します
https://www.packer.io/docs/templates/legacy_json_templates

キー 役割
builders
(required)
作成するマシンイメージのビルダーを指定
description
(option)
テンプレートの説明を記載
min_packer_version
(option)
動作を保証する最小バージョン
provisioners
(option)
コマンドやプロビジョニングツールなどを指定
post-processors
(option)
provisioners後に実行することを指定
variables
(option)
ユーザが指定できる変数

表に記載されたものだけだと、お前は何を言ってるんだ? になると思いますのでもう少し簡単に説明を加えると...

builders で AWS や GCP, VMware など、どの仮想マシンイメージを作成するのか、またそれに紐づくパラメータを指定します

provisioners で仮想マシンにやりたいことを指定します
ミドルウェアやアプリケーションなど、ソフトウェアのインストールや設定を自動的にできます
例えば、Apacheだけ入れておきたい とか Ansibleと連携する などができます

上記2つがあれば事足りますが、テンプレートなので variables を使って汎用的にしたり、post-processors で アーティファクト(成果物)の出力先を指定したりなどができます

まだ お前は何を言ってるんだ? って方は調べてください

変数について

変数は variables変数ファイル,コマンドオプション で指定できます

variablesでの指定
  "variables": {
    "key1": "value2",
    "key2": "value2"
  }
変数ファイルでの指定
{
  "key1": "value1",
  "key2": "value2"
}

以下のように指定することで使えます

使い方
"{{user `key1`}}"

これ以外の環境変数なども使えるみたいですので、興味がある方は調べてみてください
https://www.packer.io/docs/templates/legacy_json_templates/user-variables

優先度

変数の強さ(優先度)は、 コマンドオプション(変数ファイル) > variables になります

コマンドオプションと変数ファイルの優先度は後に指定した方が適用されます

variables.json
{
  "key1": "foo",
  "key2": "bar"
}
buildコマンド
packer build -var 'key1=bar' \
    -var-file=variables.json \
    -var 'key2=hoge' \
    template.json

結果は以下のようになります

変数
key1 foo
key2 hoge

Packerで用意している変数

https://www.packer.io/docs/builders/amazon/ebs#build-template-data

サンプルテンプレート

例として AWSのAMI用のテンプレートを載せておきます(builders の部分のみ)
https://www.packer.io/docs/builders/amazon/ebs

テンプレート例
packer.json
{
  "variables": {
    "profile": "default"
  },
  "builders": [
    {
      "type": "amazon-ebs",
      "ami_name": "{{user `service_name`}}-{{user `environment`}}",
      "profile": "{{user `profile`}}",
      "region": "{{user `region`}}",
      "source_ami_filter": {
        "filters": {
          "name": "amzn2-ami-hvm-*-x86_64-gp2"
        },
        "owners": ["amazon"],
        "most_recent": true
      },
      "instance_type": "{{user `instance_type`}}",
      "vpc_id": "{{user `vpc_id`}}",
      "subnet_id": "{{user `subnet_id`}}",
      "security_group_id": "{{user `security_group_id`}}",
      "ssh_username": "ec2-user",
      "ssh_timeout": "5m",
      "ssh_interface": "{{user `ssh_interface`}}",
      "tags": {
        "Name": "{{user `service_name`}}-{{user `environment`}}",
        "Environment": "{{user `environment`}}"
      },
      "run_tags": {
        "Name": "Packer Build"
      }
    }
  ]
}

AWSのシークレットキーやシークレットアクセスキーを指定する必要がありますが、上記には記載していません
指定しない場合は、以下のパスに対してcredential情報を読みにいくようになっているためです

LinuxおよびOS X
$ HOME/.aws/credentials
Windows
%USERPROFILE%.aws\credentials

上記以外のパスに置いている方は access_keysecret_key を指定してください
もっと詳しく知りたい方は公式ページをご確認ください

variables.json
{
  "environment": "",
  "instance_type": "",
  "region": "",
  "service_name": "",
  "ssh_interface": "",
  "security_group_id": "sg-********",
  "subnet_id": "subnet-********",
  "vpc_id": "vpc-********",
}
各オプションの補足
オプション 説明 設定例
type
(required)
使うビルダー amazon-ebs, amazon-instance,
amazon-chroot, amazon-ebssurrogate
ami_name
(required)
作成するAMIにつける名前 任意の名前
profile credentialsで設定しているprofile名 default(デフォルト) ※1
region
(required)
作成時に使うリージョン(AMIを作成したいリージョン) ap-northeast-1
source_ami_filter
(required)
作成時に使うベースのAMI
例の場合はamzn2の最新版を使うようになります
※2
instance_type 作成時に使うインスタンスタイプ t3.micro, t3.smallなど
vpc_id 作成時に使うVPC vpc-*
subnet_id 作成時に使うサブネット subnet-*
security_group_id 作成時に使うセキュリティグループ sg-* ※3
ssh_username インスタンスへSSHする際に使うユーザ ec2-userなど
ssh_timeout SSHが利用可能になるのを待つ時間 デフォルト10m
ssh_interface SSHする際に使用するホスト public_ip(デフォルト), private_ip, public_dns, private_dns
tags AMIに設定するタグ 任意の名前
run_tags ビルド中のインスタンスにつけるタグ 任意の名前

※1 別のprofileを使いたい場合は、コマンドのオプションでオーバーライドしましょう
※2 ベースで使うAMIがあるなら source_ami を代わりに使いましょう
※3 指定しない場合、0.0.0.0/0のインバウンドルールでセキュリティグループを作成しアタッチします

ビルド

テンプレートファイルの名前を packer.json としていますが任意の名前で問題ありません
また、実行する際は同ディレクトリで実行しましょう

https://www.packer.io/docs/commands/build

基本
$ packer build packer.json
変数を使う場合
$ packer build -var 'key1=value1' -var 'key2=value2' packer.json
変数ファイルを使う場合
$ packer build -var-file='var_file_path' packer.json

あとは -debug を使って対話形式にしてその隙にSSHして仮想マシン(サーバ)の中に入ったり
-on-error を使ってエラー時にその環境を残して調査したりすることも可能です

おわりに

いかがだったでしょうか?
これからPackerを使う方が少しでも理解して使ってみようかなって思える内容になっていれば幸いです!!

時間ができたらHCL2で同じことができるかを試したいと思います

Discussion