はじめに
何種類か EC2 サーバを管理しているとき、プログラミングの実行環境やサーバミドルウェア など共通して必要になるものがあります。 私が居るチームでは、 Packer を使って共通のイメージを作成してリリースに掛かる時間や運用コストを削減しています。
Packer は以下のような JSON ファイルでパラメータ等を指定して、マシンイメージを作成することが出来ます。なお私のチームでは、Jenkins 上で Packer を実行するジョブを実行して EC2 の AMI を作成しています。
"builders": [{
"type": "amazon-ebs",
"region": "ap-northeast-1",
"source_ami": "ami-01234567",
"instance_type": "t2.micro",
"ssh_username": "dummy",
"ami_name": "peach-ami-{{timestamp}}",
"user_data_file": "user-data.txt",
"vpc_id": "vpc-abcdedf",
"subnet_id": "subnet-fedcba"
}],
"provisioners": [
{ "type": "file", "source": "files/", "destination": "/tmp" }
{
"type": "shell",
"scripts": [
"scripts/python/packages.sh",
"scripts/base-dev.sh"
]
},{
"type": "shell",
"scripts": [
"scripts/python/config-dev.sh"
]
}
]
}
ジョブはこんな感じのシェルスクリプト。

packer build packer.json
ジョブ自体は packer を実行しているだけです。
今回、CPU の脆弱性対応のために
"source_ami": "ami-01234567" の箇所を更新する必要があったのですが、「AMI を変更する度に設定ファイル自体を書き換えるのは、もしかして無駄なのでは」と思いました。
そもそも、Jenkins や Packer のようなツールで引数が取れないわけないので、
Jenkins で AMI の ID を引数を取る ↓ Packer の引数として使う ↓ 設定ファイルを変えることなく、AMI の ID を変更することが出来る
ということを考えました。
Packer に引数を渡す
公式ドキュメント の User Variablesによると、
- JSON ファイルに
variablesの項目を作り変数名を指定 - 引数を使いたい場所に
{{ user \`変数名\` }}と記述 - pakcer 実行時に オプションで
-var 変数名=値を追加
とすることで、引数を使ったビルドが出来ます。
variables の変数名の後に書いた値がデフォルト値になり、 null を指定すると引数がない場合にエラーとなります。
今回の場合、値を必ず引数で指定して欲しいので
null にしました。
{
"variables": {
"source_ami": null
},
"builders": [{
"type": "amazon-ebs",
"region": "ap-northeast-1",
"source_ami": "{{user `source_ami`}}",
"instance_type": "t2.micro",
"ssh_username": "dummy",
"ami_name": "peach-ami-{{timestamp}}",
"user_data_file": "user-data.txt",
"vpc_id": "vpc-abcdedf",
"subnet_id": "subnet-fedcba"
}],
"provisioners": [
{ "type": "file", "source": "files/", "destination": "/tmp" }
{
"type": "shell",
"scripts": [
"scripts/python/packages.sh",
"scripts/base-dev.sh"
]
},{
"type": "shell",
"scripts": [
"scripts/python/config-dev.sh"
]
}
]
}
次に、Jenkins のジョブで実行するコマンドに引数を追加しておきます。 とりあえず、値を直接書きます。
packer build -var source_ami=ami-12345678 packer.json
これでジョブを実行してみて、引数の ami を元にしたイメージが作成されていれば成功です。
Jenkins ジョブに引数を渡す
Jenkins のジョブ設定の中に「ビルドのパラメータ化」があります。これが、引数の設定です。 チェックを入れてパラメータの形式を選びます。

「文字列」と「テキスト」という似たような選択肢がありますが、文字列が一行テキスト、テキストは複数行テキストです。(英語だと何になってるんでしょうね?)
今回は一行なので「文字列」を選び、ジョブ中で使用する引数名を指定します。

最後にジョブのシェルスクリプトで引数を受け取るよう修正します。
packer build -var source_ami=$source_ami_id packer.json
これで、ジョブを実行するときに以下のようにパラメータを聞かれるようになります

ここに入れた値を引数に packer が実行され、Jenkins にパラメータを渡して、Packer で引数付きビルドを行うことができました。
江藤 光
まだまだ気持ちは新人です。