[Osaka/Yokohama] Looking for infrastructure/server side engineers!

[Osaka/Yokohama] Looking for infrastructure/server side engineers!

[Deployed by over 500 companies] AWS construction, operation, maintenance, and monitoring services

[Deployed by over 500 companies] AWS construction, operation, maintenance, and monitoring services

[Successor to CentOS] AlmaLinux OS server construction/migration service

[Successor to CentOS] AlmaLinux OS server construction/migration service

[For WordPress only] Cloud server “Web Speed”

[For WordPress only] Cloud server “Web Speed”

[Cheap] Website security automatic diagnosis “Quick Scanner”

[Cheap] Website security automatic diagnosis “Quick Scanner”

[Reservation system development] EDISONE customization development service

[Reservation system development] EDISONE customization development service

[Registration of 100 URLs is 0 yen] Website monitoring service “Appmill”

[Registration of 100 URLs is 0 yen] Website monitoring service “Appmill”

[Compatible with over 200 countries] Global eSIM “Beyond SIM”

[Compatible with over 200 countries] Global eSIM “Beyond SIM”

[If you are traveling, business trip, or stationed in China] Chinese SIM service “Choco SIM”

[If you are traveling, business trip, or stationed in China] Chinese SIM service “Choco SIM”

[Global exclusive service] Beyond's MSP in North America and China

[Global exclusive service] Beyond's MSP in North America and China

[YouTube] Beyond official channel “Biyomaru Channel”

[YouTube] Beyond official channel “Biyomaru Channel”

PackerでHCL2がサポートされたので既存のJson形式のコードを書き換えた話

インフラエンジニアの寺岡です。
Packerで待ちに待ったアップデートがありました。
ついにHCL2をサポートしてくれました!

今回は既存のJsonで書いていたコードをHCL2ベースに書き直してみましたので
それぞれのコードを比較しながらまとめてみたいと思います。

Packerとは

マルチクラウド対応のゴールデンイメージを作成できるCLIツールです。

https://packer.io

この手のゴールデンイメージを作成するツールは
Immutable Infrastructureやブルーグリーンデプロイメントと非常に相性が良く
AutoScalingなどのサーバの作成と破棄が頻繁に繰り返される環境下において重宝します。

開発はHashiCorpによって継続されておりGolangで記述されています。
同じくTerraformも有名なツールなのでご存知の方が多いのではないでしょうか。

PackerはAWS・GCP・Azureなどの主要なクラウドサービスはもちろんのこと
DockerイメージやVMwareなどのハイパーバイザー型のマシンイメージの作成にも対応しています。
多数のサービス(Packerではbuilderと言います)に対応していますが
どのbuilderでも共通の書式でコードを書いて処理を記述できるのがメリットです。

以前まではJson形式でしか記述できませんでしたが
バージョン1.5よりHCL2形式をサポートしました。
本記事を書いた時点(2020/03/31)ではまだベータ版のため
プロダクション環境における利用は事前によく検証してからの方が良いかもしれません。

HCLとは

HashiCorp Configuration Languageの略で同じくHashiCorpにとって開発されています。
実装的にはJson互換ですが、あくまで独自言語のためJsonとは全く違う独自の記述を行うことができます。
コマンドラインツールでの利用が想定されており、Terraformでは以前からサポートされていたので
tfファイルを書いている方からすると馴染み深いものになっていると思います。
ちなみにバージョン違いでHCL1とHCL2があり現在はHCL2が主流になっています。

Packerのテンプレートを書いてみる(Json)

Packerはイメージの作成をテンプレートと呼ばれるものを記述して作成しますが
テンプレートの内容をJson形式と比較しながらHCL2で書いていきたいと思います。
まずはJson形式で書いたものを見てみましょう。

{
    "builders": [
        {
            "type": "amazon-ebs",
            "region": "{{user `region`}}",
            "source_ami_filter": {
                "filters": {
                    "name": "{{user `ami_name`}}*"
                },
                "owners": [
                    "self"
                ],
                "most_recent": true
            },
            "instance_type": "{{user `instance_type`}}",
            "ssh_username": "{{user `ssh_username`}}",
            "ami_name": "{{user `ami_name`}}_{{timestamp}}",
            "tags": {
                "Name": "{{user `ami_name`}}_{{timestamp}}"
            },
            "iam_instance_profile": "{{user `iam_instance_profile`}}"
        }
    ],
    "provisioners": [
        {
            "type": "shell",
            "inline": [
                "sudo yum -y update"
            ]
        }
    ]
}

{{user `ami_name`}}などの部分が変数となっており
格納される値は別ファイルに記述されています。

{
  "ssh_username": "ec2-user",
  "region": "ap-northeast-1",
  "instance_type": "t3.micro",
  "ami_name": "ami-packer-test",
  "iam_instance_profile": "role-packer-test"
}

このテンプレートファイルを用いて

$ packer build main.json -var-file=variables.json

とコマンドを実行することで
variables.jsonから変数に格納する値を読み込みつつイメージをビルドすることができます。
上記のテンプレートの内容通りにビルドを行うと

  • source_ami_filterに記述した内容でベースとなるAMIIDを検索する
  • 検索に該当したAMIをベースにビルド処理を開始する
  • ベースAMIから新しくEC2インスタンスを起動する
  • EC2インスタンスにログインするためのテンポラリのキーペアを作成する
  • SSHでインスタンスにログインしてprovisionersに記述されている処理を実行する
  • EC2インスタンスを停止する
  • 停止したインスタンスからAMIを取得する
  • 取得完了後にインスタンスを削除する

という一連の処理を行います。
AMIの情報を取得するときはIAMロールを利用することができるため
上記の例ではpackerコマンドを実行するEC2インスタンスに
実行に必要なIAMロールを事前に設定しています。
IAMロールに必要な権限は以下にまとめられています。

https://packer.io/docs/builders/amazon.html

Packerのテンプレートを書いてみる(HCL2)

では上記のJsonをHCL2に書き直してみるとどのようになるでしょうか。
まず変数に対して格納する値を書いていきます。
以下の2つのファイルを利用します。

variables.pkrvars.hcl

ssh_username         = "ec2-user"
region               = "ap-northeast-1"
instance_type        = "t3.micro"
ami_name             = "ami-packer-test"
iam_instance_profile = "role-packer-test"

variables.pkr.hcl

variable "ssh_username" {
  type        = string
  description = "SSH User Name"
}

variable "region" {
  type        = string
  description = "AWS Region"
}

variable "instance_type" {
  type        = string
  description = "EC2 Instance Type"
}

variable "ami_name" {
  type        = string
  description = "EC2 AMI Name"
}

variable "iam_instance_profile" {
  type        = string
  description = "EC2 IAM Instance Profile"
}

variables.pkrvars.hclに変数に格納する値を記述します。
Jsonでは「値名:値」でしたがHCL2では「値名 = 値」になります。

HCL2で変数を表現する場合はvariableを利用します。
プログラミング言語と同様に型の概念があり
今回は全て文字列(string)型の変数を利用しています。
その他にも

  • 数値型(number)
  • リスト型(list)
  • マップ型(map)
  • ブーリアン型(bool)

などがあります。

次に実際のビルド処理部分の記述をしていきます。
以下の2つのファイルを利用します。

sources.pkr.hcl

## Source
source "amazon-ebs" "example" {
  region               = var.region
  ami_name             = "${var.ami_name}_{{timestamp}}"
  instance_type        = var.instance_type
  iam_instance_profile = var.iam_instance_profile
  ssh_username         = var.ssh_username

  source_ami_filter {
    owners      = ["self"]
    most_recent = true

    filters {
      virtualization-type = "hvm"
      name                = "${var.ami_name}*"
      root-device-type    = "ebs"
    }
  }

  tags {
    Name = "${var.ami_name}_{{timestamp}}"
  }
}

build.pkr.hcl

## Build
build {
  sources = [
    "source.amazon-ebs.example"
  ]

  provisioner "shell" {
    inline = [
      "sudo yum -y update"
    ]
  }
}

この通り、Json形式では1つのファイルに書いていたものを
sourceとbuildという単位で別ファイルに分けることができます。
またHCL2の場合はコードの途中でコメントを挿入することができるのが特徴です。
変数の参照は「var.変数名」で可能です。

build.pkr.hclではsourceの設定を読み込み
provisionerの部分でビルド時に実行する処理を書いています。
sourcesの部分はlist型になっているため以下のように複数指定することも可能です。

sources = [
    "source.amazon-ebs.example",
    "source.amazon-ebs.example2"
]

ビルドを実行するときはテンプレートファイルが存在するディレクトリに移動して

$ packer build -var-file=variables.pkrvars.hcl ./

とすればカレントディレクトリのファイルを全て読み込んで実行してくれます。

現時点の問題点

Packerには構文チェックを行うvalidateコマンドがありますが
HCLで記述した場合はこれが利用できません。
今後のアップデートに期待です。
https://github.com/hashicorp/packer/issues/8538

まとめ

Packerはクラウドサービスを使ったDevOpsを実践する上で便利なツールとなっています。
CI/CDのフローに組み込みやすくPacker自体の構成も非常にシンプルなため
皆様も是非一度利用してみてください。

この記事がお役に立てば【 いいね 】のご協力をお願いいたします!
0
読み込み中...
0 票, 平均: 0.00 / 10
3,581
X facebook はてなブックマーク pocket
[2024.6.30 CentOS support ended] CentOS server migration solution

[2024.6.30 CentOS support ended] CentOS server migration solution

[2025.6.30 Amazon Linux 2 support ended] Amazon Linux server migration solution

[2025.6.30 Amazon Linux 2 support ended] Amazon Linux server migration solution

[Osaka/Yokohama] Actively recruiting infrastructure engineers and server side engineers!

[Osaka/Yokohama] Actively recruiting infrastructure engineers and server side engineers!

The person who wrote this article

About the author

Yuki Teraoka

Joined Beyond in 2016 and is currently in his 6th year as an Infrastructure Engineer
MSP, where he troubleshoots failures while
also designing and building infrastructure using public clouds such as AWS.
Recently, I
have been working with Hashicorp tools such as Terraform and Packer as part of building container infrastructure such as Docker and Kubernetes and automating operations, and I
also play the role of an evangelist who speaks at external study groups and seminars.

・GitHub
https://github.com/nezumisannn

・Presentation history
https://github.com/nezumisannn/my-profile

・Presentation materials (SpeakerDeck)
https://speakerdeck.com/nezumisannn

・Certification:
AWS Certified Solutions Architect - Associate
Google Cloud Professional Cloud Architect