「どちらもAMIを作成するのは知っていますが、実務ではどちらを選ぶべきですか?」
この記事がその疑問に答えます。
<

🎯 この記事で扱う内容
- AWS Image BuilderとPackerの主要な概念と動作方式の比較
- 使用難易度と学習曲線 — どちらがより早く習得できるか
- 実務シナリオ別の選択基準(CI/CDパイプライン統合、マルチクラウド、コンプライアンス環境)
- セキュリティ・コンプライアンス観点の違い
- ビルドコストと速度の比較
- 結論:どのチームに何が適しているか
📌 はじめに / 背景
AMI(Amazon Machine Image)は、EC2インスタンスのゴールデンイメージです。特定の設定が施されたインスタンスをスナップショットとして保存し、その後のデプロイメントでは常にこのイメージを基にインスタンスを起動します。Auto Scaling、Blue/Greenデプロイ、Immutable Infrastructure戦略のすべてにおいて、ゴールデンAMIのビルド自動化が前提となります。
問題は、このゴールデンイメージをどのように作成するかです。
AWSが2019年にImage Builderをリリースするまで、ほとんどのDevOpsチームはHashiCorpのPackerを使用していました。現在では両方のツールが共存しており、新規プロジェクトを開始するチームは常に選択を迫られます。
この記事は、単に2つのツールを並べるのではなく、実務でCI/CD経験のあるエンジニアがどちらを選択すべきかについて明確な基準を提示することを目的としています。

🔍 まずは2つのツールの概念を理解する
AWS Image Builder
AWSが直接開発したマネージドサービスです。コンソール、CloudFormation、Terraformなどでパイプラインを宣言すると、AWSが一時的なEC2インスタンスを起動し → コンポーネント(インストールスクリプト)を実行し → AMIを作成し → インスタンスを終了する全プロセスを自動で処理します。
主要な構成要素:
| 構成要素 | 役割 |
| Recipe | ベースイメージ + コンポーネントの組み合わせを定義 |
| Component | インストール・設定スクリプトの単位 (YAML) |
| Pipeline | ビルドスケジュールとデプロイ対象を設定 |
| Distribution | 完成したAMIをどのリージョン/アカウントに配布するか |
Packer
HashiCorpが開発したオープンソースのCLIツールです。JSONまたはHCL2ファイルでビルド構成を定義し、`packer build`コマンド一つで実行します。AWSだけでなく、Azure、GCP、VMware、Dockerイメージまで同じ方法で作成できます。
主要な構成要素:
| 構成要素 | 役割 |
| Builder | どのプラットフォームにイメージを作成するかを定義 (amazon-ebsなど) |
| Provisioner | Shell、Ansible、Chefなどで内部設定を実行 |
| Post-processor | ビルド後の処理(Manifestファイル生成、タグ付けなど) |
| Variable | ビルドのパラメータ化(リージョン、AMI名、バージョンなど) |
—
🔍 使用難易度 / 学習曲線
AWS Image Builder
初期の導入はコンソールベースなので簡単に感じられます。しかし、この利便性は長く続きません。
コンポーネントのYAML構文は独自のものであり、ビルド失敗時にはログをS3やCloudWatch Logsで探す必要があります。ローカルで事前にテストする方法がなく、コンポーネントを一つ修正するだけでもパイプライン全体を再実行して結果を確認しなければなりません。これは、開発の反復サイクルが遅いことを意味します。
学習難易度: 最初の3日間は簡単ですが、その後デバッグと詳細な制御で詰まります。
Packer
CLIベースなので導入障壁はありますが、Terraformを使ったことのあるDevOpsエンジニアであればHCL2構文に慣れているでしょう。`packer validate`で構文検証、`packer build -debug`でインタラクティブなデバッグが可能です。ローカルでDockerビルダーを使ってプロビジョナースクリプトを事前に検証してからAWSビルドに適用するパターンも広く使われています。
# packer buildの基本構造 (HCL2)
packer {
required_plugins {
amazon = {
version = ">= 1.2.0"
source = "github.com/hashicorp/amazon"
}
}
}
variable "aws_region" {
type = string
default = "ap-northeast-2"
}
variable "app_version" {
type = string
}
source "amazon-ebs" "golden_ami" {
region = var.aws_region
instance_type = "t3.micro"
# ベースイメージ: 最新のAmazon Linux 2023を自動検出
source_ami_filter {
filters = {
name = "al2023-ami-*-x86_64"
root-device-type = "ebs"
virtualization-type = "hvm"
}
owners = ["amazon"]
most_recent = true
}
ssh_username = "ec2-user"
ami_name = "my-app-golden-${var.app_version}-{{timestamp}}"
ami_description = "Golden AMI for my-app v${var.app_version}"
tags = {
Name = "my-app-golden"
Version = var.app_version
BuildDate = "{{timestamp}}"
ManagedBy = "Packer"
}
}
build {
sources = ["source.amazon-ebs.golden_ami"]
# ステップ1: システムアップデート
provisioner "shell" {
inline = [
"sudo dnf update -y",
"sudo dnf install -y amazon-cloudwatch-agent"
]
}
# ステップ2: Ansibleでアプリ設定
provisioner "ansible" {
playbook_file = "./ansible/app-setup.yml"
extra_arguments = [
"--extra-vars", "app_version=${var.app_version}"
]
}
# ステップ3: ビルド結果マニフェストを保存 (次のデプロイ段階でAMI ID参照用)
post-processor "manifest" {
output = "manifest.json"
strip_path = true
}
}
学習難易度: 最初の設定に1〜2日、その後Ansible・Shellの組み合わせを習得すれば迅速に拡張できます。
🔍 実務におけるCI/CDパイプライン統合
これが最も重要な比較点です。
Packer + GitHub Actions
PackerはCLIツールなので、パイプラインで単一のコマンドを実行するだけで済みます。AMI IDは`manifest.json`に記録され、後続のTerraformデプロイ段階に直接渡すことができます。
# .github/workflows/build-ami.yml
name: Build Golden AMI
on:
push:
branches: [main]
paths:
- 'packer/**'
- 'ansible/**'
jobs:
build-ami:
runs-on: ubuntu-latest
permissions:
id-token: write # OIDCベースのAWS認証
contents: read
steps:
- uses: actions/checkout@v4
# OIDCでAWS認証 (長期資格情報は不要)
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsPackerRole
aws-region: ap-northeast-2
# Packerのインストール
- name: Setup Packer
uses: hashicorp/setup-packer@main
with:
version: "1.10.0"
# プラグインの初期化
- name: Packer Init
run: packer init ./packer/
# 有効性検証
- name: Packer Validate
run: packer validate -var "app_version=${{ github.sha }}" ./packer/
# AMIのビルド
- name: Packer Build
run: |
packer build
-var "app_version=${{ github.sha }}"
./packer/
# ビルドされたAMI IDを次のジョブに渡す
- name: Extract AMI ID
id: ami
run: |
AMI_ID=$(jq -r '.builds[-1].artifact_id' manifest.json | cut -d: -f2)
echo "ami_id=$AMI_ID" >> $GITHUB_OUTPUT
# Terraformで即時デプロイをトリガー
- name: Trigger Deployment
run: |
echo "Built AMI: ${{ steps.ami.outputs.ami_id }}"
# 後続のTerraform applyまたはAuto Scaling Groupの更新
AWS Image Builder + EventBridge
Image Builderは、コンソールまたはCLIでパイプライン実行をトリガーし、完了イベントをEventBridgeで受信してLambda → Terraformを接続するパターンを使用します。動作はしますが、パイプライン構成が複数のAWSサービスに分散されるため、可視性が低下します。
結論: CI/CD統合の単純さと可視性においては、Packerが圧倒的に有利です。
🔍 セキュリティ・コンプライアンス観点
AWS Image Builderの強み
Image BuilderにはInspector統合が組み込まれています。ビルドパイプライン内でCVEスキャンを実行し、脆弱性が発見された場合、AMIの配布を自動的にブロックします。AWS Organizations環境でSCPs(Service Control Policies)と組み合わせることで、承認されていないイメージの使用自体を阻止できます。
また、AWSが直接STIG(セキュリティ技術実装ガイド)コンポーネントを提供しています。金融・公共環境のコンプライアンス要件を迅速に満たす必要がある場合に有用です。
Packerのセキュリティアプローチ
Packer自体にはスキャン機能がありません。代わりに、プロビジョナー段階でTrivy、Lynis、OpenSCAPなどのツールを直接呼び出す方式です。より柔軟ですが、自分で構成する必要があります。
# PackerでTrivyを使って脆弱性スキャンする例
provisioner "shell" {
inline = [
# Trivyのインストール
"curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin",
# OSパッケージの脆弱性スキャン
"trivy rootfs --exit-code 1 --severity HIGH,CRITICAL /",
# 結果をS3に保存 (監査ログ用)
"trivy rootfs --format json / > /tmp/trivy-report.json",
"aws s3 cp /tmp/trivy-report.json s3://my-compliance-bucket/trivy-reports/$(date +%Y%m%d)/report.json"
]
}
コンプライアンス環境(金融、公共、医療): Image Builderが有利です。 独自のセキュリティパイプラインをすでに持つチーム: Packerがより柔軟です。
🔍 コスト・速度観点
両ツールともビルド中に一時的なEC2インスタンスを使用します。ツール自体の追加費用はありません。違いはビルド時間で生じます。
| 項目 | AWS Image Builder | Packer |
| ツール費用 | 無料 (EC2費用のみ) | 無料 (EC2費用のみ) |
| ビルドインスタンス起動オーバーヘッド | 約3〜5分 (サービス初期化含む) | 約1〜2分 |
| ビルド失敗時の再試行費用 | 毎回インスタンス再起動 | -debugモードでインスタンス維持可能 |
| ローカル事前テスト | 不可 | Dockerビルダーで可能 (無料) |
| 並列マルチリージョンビルド | 配布構成でサポート | parallelブロックでサポート |
Packerのローカル事前テストパターンは、実質的なコスト削減に有利です。スクリプトエラーをAWSビルド前にローカルのDockerコンテナで捕捉できれば、不要なEC2費用が発生しません。
🔍 マルチクラウド / ハイブリッド環境
これがPackerの最も強力なカードです。
AWS AMI、Azure Managed Image、GCP Custom Image、VMware vSphere Templateを同じHCLファイル一つで管理できます。
# マルチクラウド同時ビルドの例
source "amazon-ebs" "aws_golden" {
region = "ap-northeast-2"
instance_type = "t3.micro"
# ... AWS設定
}
source "azure-arm" "azure_golden" {
location = "Korea Central"
vm_size = "Standard_B1s"
# ... Azure設定
}
build {
# 両プラットフォームを同時にビルド
sources = [
"source.amazon-ebs.aws_golden",
"source.azure-arm.azure_golden"
]
# 同じプロビジョナーを両方に適用
provisioner "ansible" {
playbook_file = "./ansible/golden-base.yml"
}
}
AWS Image BuilderはAWS専用です。マルチクラウドやオンプレミスイメージが必要になった瞬間、選択肢から外れます。
⚠️ 注意事項 / よくある間違い
① Image Builderコンポーネントのバージョン管理を怠ること コンポーネントは一度作成すると修正できません。変更するたびに新しいバージョンを作成する必要があります。バージョンポリシーなしで運用すると、どのバージョンが本番環境に導入されているか追跡が困難になります。
② Packerで一時的なキーペア・セキュリティグループを手動でクリーンアップしないこと ビルド中に強制終了された場合、Packerが作成した一時リソースがAWSに残る可能性があります。`packer build`に`–on-error=abort`オプションと合わせてクリーンアップスクリプトをCIに含めてください。
③ AMI名にバージョン情報を入れないこと `golden-ami-latest`のように上書きされる名前を使用すると、ロールバックが不可能になります。`app-v1.2.3-20240327`のような不変の名前を推奨します。
④ ビルドIAM権限を過度に付与すること ビルド用Roleに`AdministratorAccess`を付与するケースがあります。最小権限の原則に従い、AMI作成・タグ付け・S3アクセスなど、必要な権限のみを定義してください。
✅ まとめ / 終わりに
率直な結論を述べます。
| 状況 | 推奨 |
| AWS単一環境 + コンプライアンス重視(金融・公共) | AWS Image Builder |
| AWS Organizations + Inspector自動スキャンが必要 | AWS Image Builder |
| CI/CDパイプラインに完全統合、コードで管理したい | Packer |
| マルチクラウドまたはオンプレミスイメージを併用 | Packer |
| Terraformをすでに使用中、HCLに慣れているチーム | Packer |
| 迅速な反復開発、デバッグの利便性を重視 | Packer |
ほとんどの実務DevOpsチームにとって、Packerがより良い選択肢です。CI/CD統合、コードの可視性、マルチクラウドの柔軟性、迅速な反復開発 — この4つの観点からPackerが優れています。
AWS Image Builderは、AWSエコシステム内でInspector・SCPs・Organizationsを組み合わせてコンプライアンスを自動化する必要がある場合に真価を発揮します。両方のツールを併用するチームもあります。Packerでベースイメージを作成し、Image Builderでコンプライアンス検証レイヤーを追加する方式です。
結局のところ、ツールの優劣よりもチームのワークフローと環境に何が合っているかが重要です。🎯
コメントを残す