UUUM攻殻機動隊

UUUMのエンジニアによる技術ブログです

PackerでAMIビルド時にスポットインスタンスを使う

nazo です。

AWS で使う AMI を作成する時には Packer が便利ですが、Packer のビルド時にスポットインスタンスを使えると、費用削減に効果があると思います。Packer にはその機能があるので、試してみようと思います。

設定

設定は簡単で、spot_pricespot_price_auto_product の2項目のみです。

spot_price

ここで入力した価格で入札を行います。"0" または未入力だとオンデマンドインスタンスになります(デフォルトの挙動)。

spot_price_auto_product

spot_price"auto" に設定する必要があります。 以下の文字列のいずれか(DescribeSpotPriceHistory で指定する項目と同じです)を指定することにより、該当する種類のインスタンスを現在の最適な値段で起動します。

  • Linux/UNIX
  • SUSE Linux
  • Windows
  • Linux/UNIX (Amazon VPC)
  • SUSE Linux (Amazon VPC)
  • Windows (Amazon VPC)

通常は Linux/UNIX (Amazon VPC) を指定することが多いかと思います。

使ってみる

以下のように設定してみます。

{
    "builders": [
        {
            "type": "amazon-ebs",
            "instance_type": "m3.large",
            "region": "us-east-1",
            "associate_public_ip_address": true,
            "spot_price": "auto",
            "spot_price_auto_product": "Linux/UNIX (Amazon VPC)",
            ...
        },
        ...

実行します。

% packer build test.json
amazon-ebs output will be in this color.

==> amazon-ebs: Force Deregister flag found, skipping prevalidating AMI Name
==> amazon-ebs: Inspecting the source AMI...
==> amazon-ebs: Creating temporary keypair: packer xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx
==> amazon-ebs: Launching a source AWS instance...
    amazon-ebs: Finding spot price for Linux/UNIX (Amazon VPC) m3.large...
    amazon-ebs: Requesting spot instance 'm3.large' for: 0.0187
    amazon-ebs: Waiting for spot request (sir-xxxxxxxx) to become active...
    amazon-ebs: Instance ID: i-90734d0a
==> amazon-ebs: Waiting for instance (i-xxxxxxxx) to become ready...
==> amazon-ebs: Waiting for SSH to become available...
==> amazon-ebs: Connected to SSH!
==> amazon-ebs: Provisioning with Ansible...

t2.micro に近い価格の $0.0187 で m3.large インスタンスを仕様することができました。packer でのビルドに使うインスタンスはすぐ終了するので、これで十分かと思われます。

試しに無理な金額を指定してみましょう。

{
    "builders": [
        {
            "type": "amazon-ebs",
            "instance_type": "m3.large",
            "associate_public_ip_address": true,
            "region": "us-east-1",
            "spot_price": "0.005",
            ...
        },
        ...

実行します

% packer build test.json
amazon-ebs output will be in this color.

==> amazon-ebs: Force Deregister flag found, skipping prevalidating AMI Name
==> amazon-ebs: Inspecting the source AMI...
==> amazon-ebs: Creating temporary keypair: packer xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx
==> amazon-ebs: Launching a source AWS instance...
    amazon-ebs: Requesting spot instance 'm3.large' for: 0.005
    amazon-ebs: Waiting for spot request (sir-xxxxxxxx) to become active...

応答しなくなりました。AWS のコンソールから確認すると price-too-low になっています。最低価格を下回るのを待っている状態になってしまいました。

まとめ

packer での AMI 作成のような、「一時的に強力なインスタンスを使いたい」という場合にスポットインスタンスはベストな選択肢だと思います。今回は m3.large を使いましたが、実用するには c4 シリーズのインスタンスを使うのが、ほとんどの場合で有利かと思います。コストやビルド内容と相談して決めてください。

また、スポットインスタンスを使う場合、スポットインスタンスのリクエストの時間分、起動が遅くなります。ビルド時間がそもそもそんなに長くないという場合にはオンデマンドで済ますのもありだと思います。

spot_price_auto_product を指定した場合でも、 price-too-low で止まることはあるので、利用時はコンソールで状態を確認してください。