Packer on Ubuntu — AWSカスタムAMIを自動ビルドするIaCの実践

IaC/自動化

この記事のポイント

  • Packer を Ubuntu 24.04 に HashiCorp apt リポジトリで入れると packer_1.15.4-1 がインストールされる(2026年6月14日実測)
  • packer validate -syntax-only は AWS クレデンシャルなしで HCL テンプレートの構文をローカルチェックできる
  • packer init を実行すると packer-plugin-amazon v1.8.1 が自動ダウンロードされる(実測確認済み)
  • AMI ビルドは「一時 EC2 起動 → provisioner 実行 → AMI 登録 → インスタンス削除」という流れで全自動
  • HCL テンプレートは変数・タグ・post-processor まで書いておくと Infrastructure as Code として管理しやすい

「EC2 を新しく立てるたびに毎回 apt update からやり直し…」そんな経験がある方に向けて書いた記事です。Packer を使えば、Nginx や Python 環境があらかじめ入った「自分専用のカスタム AMI」を Ubuntu から自動ビルドできます。次回から EC2 を起動すれば5秒でセットアップ済みの環境が使えるようになります。

本記事では Ubuntu 24.04 LTS に Packer v1.15.4 を実際にインストールし、HCL テンプレートの書き方・packer validate による構文チェック・packer init によるプラグイン取得まで実行結果をそのまま掲載します。

注意

packer build で AMI を実際に作成すると AWS の EC2 インスタンス料金(一時インスタンス)と AMI ストレージ費用(EBS スナップショット)が発生します。本記事の構文チェック手順(packer validate)まではクレデンシャルなしで無料で試せます。

目次

  1. Packer とは何か — なぜ AMI を自動ビルドするのか
  2. Ubuntu 24.04 に Packer をインストールする
  3. HCL テンプレートの書き方
  4. packer init — amazon プラグインをインストールする
  5. packer validate — 構文チェックで事前にエラーを潰す
  6. packer build — AMI ビルドの実行
  7. SSH 鍵の生成と設定
  8. よくあるエラーと解決策
  9. まとめ

Packer とは何か — なぜ AMI を自動ビルドするのか

Packer は HashiCorp が開発するオープンソースのイメージビルドツールです。「マシンイメージを コードで定義し、自動で作る」のが目的で、Terraform と並んで IaC(Infrastructure as Code)の代表的なツールです。

AWS の AMI(Amazon Machine Image)は EC2 インスタンスの起動テンプレートです。カスタム AMI があれば次のようなことができます。

  • 新しい EC2 インスタンスが 起動した瞬間から Nginx や Docker が使える
  • Auto Scaling グループで使うとスケールアウト後の初期化が不要
  • ステージング / 本番の環境差異をゼロにしたイミュータブルインフラが実現できる
HashiCorp Packer 公式リリースページ(releases.hashicorp.com)
HashiCorp Packer 公式リリースページ(releases.hashicorp.com)

Packer の動作は「一時 EC2 インスタンスを起動 → シェルスクリプトでソフトを入れる → AMI を作ってインスタンスを削除」という流れです。Terraform で言う “apply” のようなもので、実行が終わると AMI ID だけが残り、ビルド用インスタンスは自動的に消えます。

Packer AMI ビルドの全体ワークフロー
Packer AMI ビルドの全体ワークフロー

Ubuntu 24.04 に Packer をインストールする

HashiCorp は公式 apt リポジトリを提供しています。apt install packer だけで最新版が入ります。

手順1:HashiCorp apt リポジトリを追加する




ubuntu@linuxlab: ~
$ sudo apt-get update && sudo apt-get install -y wget gpg
Reading package lists… Done
Building dependency tree… Done
$ wget -qO- https://apt.releases.hashicorp.com/gpg \
| gpg –dearmor \
| sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg > /dev/null
$ echo “deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \
https://apt.releases.hashicorp.com $(lsb_release -cs) main” \
| sudo tee /etc/apt/sources.list.d/hashicorp.list
deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com noble main

lsb_release -cs は Ubuntu のコードネーム(24.04 なら noble)を返します。HashiCorp のリポジトリはコードネームごとにパッケージを管理しているため、この書き方にしておくと Ubuntu 22.04 / 24.04 のどちらでも動きます。

手順2:Packer をインストールする




ubuntu@linuxlab: ~
$ sudo apt-get update && sudo apt-get install -y packer
Get:1 https://apt.releases.hashicorp.com noble InRelease [12.9 kB]
Get:2 https://apt.releases.hashicorp.com noble/main arm64 Packages [117 kB]
Selecting previously unselected package packer.
Preparing to unpack …/packer_1.15.4-1_arm64.deb …
Unpacking packer (1.15.4-1) …
Setting up packer (1.15.4-1) …
$ packer version
Packer v1.15.4
$ which packer
/usr/bin/packer

Packer v1.15.4 と表示されれば成功です(2026年6月14日時点の最新版)。/usr/bin/packer にインストールされます。

Packer インストール実ログ(ubuntu:24.04 実測)
Packer インストール実ログ(ubuntu:24.04 実測)
著者アイコン
著者アイコン

正直、最初は「なんで AMI を自動ビルドするツールをわざわざ入れるの?」と思っていました。でも実際に使ってみると、毎回ゼロから apt install する手間が一切なくなるのでかなり快適です。

HCL テンプレートの書き方

Packer v1.7 以降は HCL2(HashiCorp Configuration Language 2)がデフォルトの記法です。拡張子は .pkr.hcl で、Terraform の書き方に似ています。

HCL テンプレートは大きく4つのブロックで構成されます。

  • packer ブロック:使用するプラグインのバージョン制約を書く
  • variable ブロック:テンプレート内で使う変数を定義(リージョンやインスタンスタイプなど)
  • source ブロック:どの AMI を元にどの設定でビルドするかを指定
  • build ブロック:source を参照し、provisioner でソフトをインストール
HCL テンプレート ubuntu-nginx.pkr.hcl のコード表示
HCL テンプレート ubuntu-nginx.pkr.hcl のコード表示

以下が実際に動く最小限の HCL テンプレートです。ファイル名は ubuntu-nginx.pkr.hcl として保存してください。




ubuntu-nginx.pkr.hcl
packer {
required_plugins {
amazon = {
version = “>= 1.3.0”
source = “github.com/hashicorp/amazon”
}
}
}

variable “region” {
type = string
default = “ap-northeast-1”
}

variable “instance_type” {
type = string
default = “t3.micro”
}

source “amazon-ebs” “ubuntu” {
region = var.region
instance_type = var.instance_type
ssh_username = “ubuntu”
ami_name = “custom-ubuntu-24.04-{{timestamp}}”
source_ami_filter {
filters = {
name = “ubuntu/images/hvm-ssd/ubuntu-noble-24.04-amd64-server-*”
root-device-type = “ebs”
virtualization-type = “hvm”
}
most_recent = true
owners = [“099720109477”]
}
tags = {
ManagedBy = “Packer”
OS = “Ubuntu 24.04 LTS”
}
}

build {
name = “ubuntu-nginx-ami”
sources = [“source.amazon-ebs.ubuntu”]

provisioner “shell” {
inline = [
“sudo apt-get update -y”,
“sudo apt-get install -y nginx”,
“sudo systemctl enable nginx”,
“sudo systemctl start nginx”,
“nginx -v”,
]
}

post-processor “manifest” {
output = “manifest.json”
}
}

①主要設定項目の解説

設定項目 値(例) 説明
region ap-northeast-1 東京リージョン。AMI の保存先になる
instance_type t3.micro ビルド中だけ使う一時インスタンス。終了後は自動削除される
ami_name custom-ubuntu-24.04-{{timestamp}} {{timestamp}} で重複防止。自動で Unix 時刻が入る
source_ami_filter Ubuntu 24.04 公式 AMI most_recent = true で常に最新パッチを使える
owners "099720109477" Canonical(Ubuntu の公式 AWS アカウント ID)。偽 AMI を引かないために必須
provisioner "shell" inline = [...] ビルド中の EC2 で実行するコマンド。ここで apt install を書く

owners = ["099720109477"] の指定は セキュリティ上非常に重要です。Canonical 公式のアカウント ID を指定しないと、悪意のある第三者が公開した偽 AMI を引いてしまうリスクがあります。ここだけは省略しないでください。

packer init — amazon プラグインをインストールする

packer build を実行する前に、テンプレートで指定したプラグインを取得する必要があります。packer init がその役割を担います。




ubuntu@linuxlab: ~/packer-ami
$ packer init ubuntu-nginx.pkr.hcl
Installed plugin github.com/hashicorp/amazon v1.8.1 in
“~/.config/packer/plugins/github.com/hashicorp/amazon/
packer-plugin-amazon_v1.8.1_x5.0_linux_arm64″
$ ls ~/.config/packer/plugins/github.com/hashicorp/amazon/
packer-plugin-amazon_v1.8.1_x5.0_linux_arm64
packer-plugin-amazon_v1.8.1_x5.0_linux_arm64_SHA256SUM

実際に実行すると packer-plugin-amazon v1.8.1~/.config/packer/plugins/ 以下にダウンロードされます(2026年6月14日実測)。SHA256 チェックサムも自動で検証されるため、改ざんされたプラグインが入る心配はありません。

packer init 実ログ(packer-plugin-amazon v1.8.1 インストール 実測)
packer init 実ログ(packer-plugin-amazon v1.8.1 インストール 実測)

注意

packer init はプラグインをダウンロードするためネット接続が必要です。社内ネットワークなどプロキシ環境下では HTTPS_PROXY 環境変数を設定するか、オフラインインストール手順を確認してください。

packer validate — 構文チェックで事前にエラーを潰す

HCL テンプレートを書いたら、packer build の前に必ず packer validate を実行しましょう。これがPackerを使う上でとても便利な点で、AWS クレデンシャルなしで構文エラーをローカルで確認できます

①構文のみチェック(推奨:クレデンシャル不要)




ubuntu@linuxlab: ~/packer-ami
$ packer validate -syntax-only ubuntu-nginx.pkr.hcl
Syntax-only check passed. Everything looks okay.

-syntax-only フラグを付けると AWS に接続せず HCL の構文だけを検証します。「Syntax-only check passed. Everything looks okay.」が返れば構文エラーなしです(2026年6月14日実測)。

②フォーマットチェック(可読性の統一)




ubuntu@linuxlab: ~/packer-ami
$ packer fmt ubuntu-nginx.pkr.hcl
ubuntu-nginx.pkr.hcl
# ファイルが修正された場合はファイル名が出力される
# 修正なし = 出力なし

packer fmt は Terraform の terraform fmt と同じ役割で、インデントや空行を自動で整形します。チームで使う場合は CI に組み込んでおくと手動整形の手間がなくなります。

③テンプレート構造を確認する(packer inspect)




ubuntu@linuxlab: ~/packer-ami
$ packer inspect ubuntu-nginx.pkr.hcl
Packer Inspect: HCL2 mode

> input-variables:
var.region: “ap-northeast-1”
var.instance_type: “t3.micro”

> builds:
> ubuntu-nginx-ami:
sources:
amazon-ebs.ubuntu
provisioners:
shell
post-processors:
manifest

packer inspect はテンプレートで定義された変数・ビルド名・source・provisioner の一覧を表示します。これも AWS 接続不要で実行できます(2026年6月14日実測)。

packer validate / packer inspect 実測結果
packer validate / packer inspect 実測結果

packer build — AMI ビルドの実行

構文チェックが通ったら、いよいよ packer build で AMI を作成します。これには AWS クレデンシャル(AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY)と、EC2・AMI を操作できる IAM 権限が必要です。

①必要な IAM ポリシー

Packer が EC2 インスタンスを起動・停止・AMI 登録するためには、以下の IAM アクションが最低限必要です。

IAM アクション 用途
ec2:RunInstances ビルド用一時インスタンスを起動
ec2:TerminateInstances ビルド完了後にインスタンスを削除
ec2:CreateImage カスタム AMI を作成・登録
ec2:DescribeImages ベース AMI(Ubuntu 公式)を検索
ec2:CreateKeyPair SSH 接続用の一時キーペアを作成
ec2:CreateSecurityGroup ビルド用の一時セキュリティグループを作成

②クレデンシャルを設定してビルドを実行




ubuntu@linuxlab: ~/packer-ami
$ export AWS_ACCESS_KEY_ID=”AKIAXXXXXXXXXXXXXXXX”
$ export AWS_SECRET_ACCESS_KEY=”xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx”
$ export AWS_DEFAULT_REGION=”ap-northeast-1″
$ packer build ubuntu-nginx.pkr.hcl
ubuntu-nginx-ami.amazon-ebs.ubuntu: output will be in this color.

==> ubuntu-nginx-ami.amazon-ebs.ubuntu: Prevalidating any provided VPC information
==> ubuntu-nginx-ami.amazon-ebs.ubuntu: Prevalidating AMI Name: custom-ubuntu-24.04-1749881234
==> ubuntu-nginx-ami.amazon-ebs.ubuntu: Launching a source AWS instance…
ubuntu-nginx-ami.amazon-ebs.ubuntu: Instance ID: i-0a1b2c3d4e5f6a7b8
==> ubuntu-nginx-ami.amazon-ebs.ubuntu: Waiting for instance (i-0a1b2c3d4e5f6a7b8) to become ready…
==> ubuntu-nginx-ami.amazon-ebs.ubuntu: Connected to SSH!
==> ubuntu-nginx-ami.amazon-ebs.ubuntu: Provisioning with shell script…
ubuntu-nginx-ami.amazon-ebs.ubuntu: Get:1 http://ap-northeast-1.ec2.archive.ubuntu.com noble InRelease [256 kB]
ubuntu-nginx-ami.amazon-ebs.ubuntu: The following additional packages will be installed: nginx-common nginx-core
ubuntu-nginx-ami.amazon-ebs.ubuntu: nginx version: nginx/1.24.0 (Ubuntu)
==> ubuntu-nginx-ami.amazon-ebs.ubuntu: Stopping the source instance…
==> ubuntu-nginx-ami.amazon-ebs.ubuntu: Creating AMI ubuntu-nginx-ami from instance i-0a1b2c3d4e5f6a7b8…
ubuntu-nginx-ami.amazon-ebs.ubuntu: AMI: ami-0123456789abcdef0
==> ubuntu-nginx-ami.amazon-ebs.ubuntu: Terminating the source AWS instance…
Build ‘ubuntu-nginx-ami.amazon-ebs.ubuntu’ finished after 8 minutes 42 seconds.
==> Wait completed after 8 minutes 42 seconds
==> Builds finished. The artifacts of successful builds are:
–> ubuntu-nginx-ami.amazon-ebs.ubuntu: AMIs were created:
ap-northeast-1: ami-0123456789abcdef0

ビルドには約8〜15分かかります。完了すると AMI ID(例:ami-0123456789abcdef0)が出力され、東京リージョンの AMI カタログに登録されます。このとき ビルドに使った EC2 インスタンスは自動的に削除されます。

注意

クレデンシャルは環境変数で渡すか、~/.aws/credentials ファイルに書いてください。HCL テンプレート本体には絶対に書かないこと(Git に push してしまうと漏洩します)。

SSH 鍵の生成と設定

Packer はビルド中に EC2 インスタンスへ SSH 接続して provisioner を実行します。デフォルトでは Packer が一時的な SSH キーペアを自動生成します。独自の鍵を使いたい場合は事前に ssh-keygen で生成しておきます。




ubuntu@linuxlab: ~
$ ssh-keygen -t ed25519 -f ~/.ssh/packer_ami_key -N ” -C ‘packer-ami-builder@linuxlab’
Generating public/private ed25519 key pair.
Your identification has been saved in /home/ubuntu/.ssh/packer_ami_key
Your public key has been saved in /home/ubuntu/.ssh/packer_ami_key.pub
The key fingerprint is:
SHA256:xXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx packer-ami-builder@linuxlab
$ cat ~/.ssh/packer_ami_key.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA… packer-ami-builder@linuxlab

-t ed25519 は RSA-4096 より短い鍵長でも同等のセキュリティを持ちます。-N '' でパスフレーズなし(ビルドスクリプトから自動実行するため)。

SSH 鍵生成(ed25519 / 実測)
SSH 鍵生成(ed25519 / 実測)

HCL テンプレートに独自鍵を指定する場合は source ブロックに ssh_private_key_file = "~/.ssh/packer_ami_key" を追加します。ただし一時鍵(デフォルト)のままで大抵の用途は問題ありません。

よくあるエラーと解決策

①Error: No valid credential sources found




ubuntu@linuxlab: ~/packer-ami
Error: No valid credential sources found for AWS Provider.
Please see https://www.packer.io/docs/builders/amazon#authentication

原因:AWS クレデンシャルが設定されていない。

対処:export AWS_ACCESS_KEY_ID="..."export AWS_SECRET_ACCESS_KEY="..." を設定する。あるいは aws configure~/.aws/credentials に書き込む。

②Error: Timeout waiting for SSH




ubuntu@linuxlab: ~/packer-ami
==> amazon-ebs.ubuntu: Error waiting for SSH: ssh: connect to host 3.x.x.x port 22: Connection timed out

原因:セキュリティグループでポート 22 の inbound が許可されていないか、VPC の設定に問題がある。

対処:デフォルト VPC を使っている場合は多くの場合自動で解決します。カスタム VPC の場合は source ブロックに vpc_idsubnet_idassociate_public_ip_address = true を追加してください。

③Error: AMI Name: … already exists




ubuntu@linuxlab: ~/packer-ami
==> amazon-ebs.ubuntu: Error: AMI Name: custom-ubuntu-24.04-1749880000 already exists

原因:ami_name{{timestamp}} を使っていない場合、同じ名前の AMI が重複する。

対処:ami_name = "custom-ubuntu-24.04-{{timestamp}}" の形式にすれば毎回ユニークな名前が自動で付く。古い AMI は定期的に削除すること。

④Plugin not found: github.com/hashicorp/amazon

原因:packer init を実行していない。

対処:packer init ubuntu-nginx.pkr.hcl を実行してプラグインをダウンロードする。インターネット接続が必要。

まとめ

Packer on Ubuntu で AWS カスタム AMI を自動ビルドする手順をまとめます。

  • HashiCorp apt リポジトリ経由で apt install packerPacker v1.15.4 がインストールされる(2026年6月14日実測)
  • HCL テンプレート(.pkr.hcl)に packervariablesourcebuild の4ブロックを書く
  • packer initpacker-plugin-amazon v1.8.1 を自動インストール(実測確認済み)
  • packer validate -syntax-only は AWS クレデンシャル不要でローカル構文チェックができる
  • packer build を実行すると一時 EC2 が自動起動 → provisioner 実行 → AMI 登録 → インスタンス削除の全自動ビルドが完了する
  • ビルド所要時間は目安で8〜15分(インスタンスタイプと provisioner の量による)

Packer を Terraform と組み合わせると、「Packer で AMI ビルド → Terraform でその AMI を使った EC2 を定義」という完全な IaC パイプラインが作れます。まずは本記事の HCL テンプレートを手元で packer validate してみてください。

VPS で Packer をデプロイして CI/CD パイプラインと組み合わせる場合は、東京リージョンとの遅延が少ない VPS を選ぶと体感速度が上がります。

VPS 選びで迷ったら、実測ベンチマークを比較した記事も参考にしてください。

コメント

タイトルとURLをコピーしました