はじめに
Terraformを利用していると、インフラはコードで管理できるようになります。しかし、OSやミドルウェアの初期設定を毎回実行していると、デプロイ時間が長くなったり、環境差異が発生したりします。
そこで活躍するのが、 Packer です。
Packerは「Images as Code」を実現するツールで、AWS AMIやAzure VM Imageなどをコードで作成・管理できます。TerraformがInfrastructure as Codeであるのに対し、PackerはImage as Codeと呼ばれることがあります。Packerは単一の設定ファイルから複数プラットフォーム向けのマシンイメージを作成できます。
今回はHashiCorp公式のAWS Getting Started Tutorialを実施しながら、Amazon EC2向けのRHEL 9 AMIを作成してみました。
Packerとは
Packerは仮想マシンやクラウドイメージを自動生成するためのツールです。
例えばAWSでは以下の処理を自動化できます。
EC2起動
↓
OS設定
↓
パッケージ導入
↓
ミドルウェア導入
↓
AMI作成
↓
EC2削除
一度作成したAMIを利用することで、
- デプロイ時間短縮
- 環境差異の排除
- セキュリティ設定の標準化
- ゴールデンイメージ運用
を実現できます。
実施したチュートリアル
今回のやってみたのベースにしたHashiCorp公式のチュートリアルは、以下の2つです。自分の環境や要件に合わせて変更している部分がありますので、それはその都度、説明します。
チュートリアルの実行開始
Packerのインストール
今回は、私の実行環境はmacOSです。macOSの場合はHomebrewが簡単です。
$ brew tap hashicorp/tap
$ brew install hashicorp/tap/packer
正しくインストールできたか、確認します。(出力は例です)
$ packer version
Packer v1.16.0
Your version of Packer is out of date! The latest version
is 1.16.1. You can update by downloading from www.packer.io/downloads
Packerテンプレートの作成
Tutorial: Write Packer template
Packerで作成するイメージのテンプレートを作成します。テンプレートというのは、HashiCorp Configuration Languageで記載するイメージのファイルです。Terraformでいうところの構成ファイルに当たります。
ファイルを配置するディレクトリーを作成します。
mkdir packer-rhel9
cd packer-rhel9
そのディレクトリーに2つのファイルを作成します。
touch main.pkr.hcl (メインのテンプレート)
touch variables.pkr.hcl (変数定義用のテンプレート)
1つのファイルに記載しても良いのですが、Terraformと同様に変数は別ファイルで定義することにします。
packer {
required_plugins {
amazon = {
version = ">= 1.3.0"
source = "github.com/hashicorp/amazon"
}
}
}
source "amazon-ebs" "rhel9" {
region = var.aws_region
instance_type = var.instance_type
ami_name = "${var.ami_name_prefix}-${formatdate("YYYYMMDD-hhmmss", timestamp())}"
source_ami_filter {
filters = {
name = "RHEL-9*-x86_64-*"
root-device-type = "ebs"
virtualization-type = "hvm"
}
owners = ["ここは適切なIDを入れてください"]
most_recent = true
}
ssh_username = "ec2-user"
}
build {
name = "rhel9-image"
sources = [
"source.amazon-ebs.rhel9"
]
}
テンプレートの内容を少し説明します。
Packer Block
packerブロックには、必要な Packer のバージョン指定を含む、Packer 全体の設定を記述します。また、この Packer ブロック内には required_plugins ブロックで、イメージのビルドに必要なすべてのプラグインを指定します。
Packer は単一のバイナリとして提供されていますが、その機能の多くはプラグインによって実現されています。例えば、これから使用する Amazon AMI Builder のようなプラグインは HashiCorp によって開発・保守・提供されています。しかし、プラグインは誰でも開発して利用することができます。各プラグイン定義には、以下の属性が含まれます。
- version
- source
Packer はこれらの情報を利用して、適切なプラグインを自動的にダウンロードします。これはTerraformのプロバイダーと同じです。
このサンプルテンプレートでは、
Packer Amazon AMI Builder プラグインのバージョン 1.2.8 以上
を使用するよう指定されています。
Sourceブロック
source ブロックは、特定の Builderプラグイン の設定を定義するためのものです。この設定は後で build ブロックから呼び出されます。
source ブロックでは、Builder(ビルダー) と Communicator(コミュニケーター) を使用して、以下の内容を定義します。
- どの種類の仮想化プラットフォームを利用するか
- プロビジョニング対象となるイメージをどのように起動するか
- 起動したマシンへどのように接続するか
Builder と Communicator はセットで利用され、同じ source ブロック内で設定します。1つの source は複数の build から再利用できます。また、1つの build の中で複数の source を利用することも可能です。
Builderプラグインは、マシンを作成し、そのマシンをイメージとして保存する役割を担う Packer のコンポーネントです。
今回のやってみたでは、チュートリアルとは違う、Red Hat Enterprise Linuxを使っています。また、ownersには、AMIのowner IDを入れるのですが、ここは適切なIDを入れてください。AWSには多数のRHELライクOSが存在します。誤って非公式イメージを利用しないように注意しましょう。
Buildブロック
build ブロックは、EC2インスタンスが起動した後に Packer が何を実行するか を定義します。今回のPackerの基本編では、build ブロックは前述の source ブロックで定義したAMI設定するだけで、何もしません。ここは後続の記事でフォローするようにします。
variable "aws_region" {
type = string
default = "ap-northeast-1"
}
variable "instance_type" {
type = string
default = "t3.micro"
}
variable "ami_name_prefix" {
type = string
default = "learn-packer-rhel9"
}
変数の設定
ここで定義した変数は、公式チュートリアルから下記を変更しています。
- リージョン > 東京
- インスタンスタイプ > t3.micro
- プリフィックス > learn-packer-rhel9
これでコードは準備できました。次に、いよいよ、イメージの作成に入ります。
AWS認証設定
AMIを構築する前に、AWS認証情報をPackerに提供する必要があります。これらの認証情報には、EC2インスタンスの作成、変更、削除を行う権限が必要です。 PackerがIAMユーザーの認証情報にアクセスできるように、下記のように、AWSアクセスキーIDを環境変数として設定してください。
$ export AWS_ACCESS_KEY_ID="<YOUR_AWS_ACCESS_KEY_ID>"
$ export AWS_SECRET_ACCESS_KEY="<YOUR_AWS_SECRET_ACCESS_KEY>"
設定の初期化
Tutorial: Initialize Packer configuration
Packerの設定を初期化します。この時にプラグインがダウンロードされます。
$ packer init .
テンプレートのフォーマットと検証
Tutorial: Format and validate your Packer template
Packerのテンプレートをフォーマットします。すべてのテンプレートで一貫した書式を使用することが推奨されています。このpacker fmtコマンドは、読みやすさと一貫性を向上させるため、現在のディレクトリー内のテンプレートを更新します。Packerは、変更したファイルがあれば、そのファイル名を表示します。テンプレートファイルは既に正しくフォーマットされている場合には、Packerはファイル名を表示しません。
$ packer fmt .
次に、テンプレートが構文的に有効であるterraformことを確認します。Packer が無効な設定を検出した場合、無効な設定のファイル名、エラーの種類、行番号を出力します。有効なテンプレートであれば、Packer は"The configuration is valid."と出力します。
$ packer validate .
The configuration is valid.
イメージの作成
buildコマンドでイメージを作成します。(なんでbuildコマンドだけ、ファイル名指定かはわかりません。)
$ packer build --var-file=variables.pkr.hcl main.pkr.hcl
実際に、AWS上でAMIを作成して登録されるので、数分かかります。私の環境では、5分から6分かかりました。
作成されたイメージ(AMI)の確認
AWSのコンソールにログインして、AMIが作成されているか確認してください。
EC2 (サービス) > AMI (イメージ)
まとめ
今回はHashiCorp公式Tutorialをベースに、
- Packerのインストール
- AWS AMI作成
- RHEL 9イメージ利用
を実践しました。Packerを活用すると、インフラ構築前のOS設定まで含めてコードで管理できるようになります。Terraformと組み合わせることで、Infrastructure as Code + Images as Codeを実現でき、より再現性の高いクラウド基盤を構築できます。次回は、HCP Packerを使ったイメージ・レジストリーの作成をやってみたいと思います。