🤹‍♂️

AWS CLIでスポットインスタンスを起動する#2

2024/12/04に公開

AWS CLIでスポットインスタンスを起動する#1に引き続き,EC2スポットインスタンスをAWS CLIで起動する一例を紹介します.
ここでは,spot-fleet-requestを用いてスポットインスタンスを起動してみます.

参考にしたサイト

aws-cliでスポットリクエストをスポット群リクエストでスポットインスタンスの立ち上げからダウンまでやってみる

環境

  • 0S: macOS Sonoma 14.6.1
  • AWS CLI: aws-cli/2.11.15 Python/3.11.3 Darwin/23.6.0 exe/x86_64

概要

ここでは,以下の条件でスポットフリートリクエスト(以下リクエスト)を実行し,スポットインスタンスを起動します.今回は,リクエストのキャンセル及びインスタンスの終了まで行います.

  • リージョン:ap-northeast-1(東京)
  • インスタンスタイプ:t1.micro
  • AMI:Amazon linux 2023

手順

以下の手順でスポットインスタンスを起動します.

  1. IAMロールの作成
  2. リクエストの設定ファイルの作成
  3. リクエストの実行
    • リクエストの履歴を確認
    • リクエストで起動したインスタンスの情報を取得
  4. リクエストのキャンセル・インスタンスの終了

1.IAMロールの作成

AWSコンソールを開きます.
IAM>アクセス管理>ロールの検索ボックスで,AWSServiceRoleForEC2SpotFleetと検索します.

これはAWSがデフォルトで用意しているスポットフリート用ロールです.詳細を知りたい方や細かい権限を設定したい方は公式ドキュメントを参照してください.
このロールのARNを控えておきます.

2.リクエストの設定ファイルの作成

JSON形式で,リクエスト用の設定ファイルを作成します.

config.json
{
    "TargetCapacity": 1,
    "SpotPrice": "0.04",
    "IamFleetRole":"<先ほど控えたロールのARN>",
    "LaunchSpecifications": [
        {
            "ImageId": "ami-023ff3d4ab11b2525",
            "KeyName": "your_key",
            "SecurityGroups": [
              { "GroupId":"sg-xxxxxxxx"}
            ],
            "InstanceType": "t1.micro",
            "UserData":"<ある場合はここに記載>"
        }
    ]
}

主な設定項目

  • TargetCapacity:起動するインスタンス数
  • SpotPrice:上限価格(入札価格)
  • LaunchSpecifications:高度な詳細

3.リクエストの実行

以下のコマンドでリクエストを実行します.

aws ec2 request-spot-fleet \
--spot-fleet-request-config file://config.json \
--region ap-northeast-1

リクエストが成功すると,以下のようなレスポンスが返ってきます.
このIDを使ったコマンドも後述していますので控えておいてください.

{
    "SpotFleetRequestId": "sfr-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

リクエストの履歴を確認

以下のコマンドで,最新のリクエスト履歴を確認します.

aws ec2 describe-spot-fleet-requests --max-results 1

以下のようなレスポンスがJSON形式で返ってきます.
ActivityStatus"fullfilled"になっていることから,リクエストが受理されスポットインスタンスが起動されていることがわかります.

    "NextToken": "~",
    "SpotFleetRequestConfigs": [
        {
            "ActivityStatus": "fulfilled",
            "CreateTime": "2024-12-04T08:03:57.571000+00:00",
            "SpotFleetRequestConfig": {
                "AllocationStrategy": "lowestPrice",
                "OnDemandAllocationStrategy": "lowestPrice",
                "ExcessCapacityTerminationPolicy": "Default",
                "FulfilledCapacity": 1.0,
                "OnDemandFulfilledCapacity": 0.0,
                "IamFleetRole": "arn:aws:iam::spot-fleet-role",
                "LaunchSpecifications": [
                    {
                        "SecurityGroups": [
                            {
                                "GroupId": "sg-xxxxxxxxxxxxxxxx"
                            }
                        ],
                        "ImageId": "ami-023ff3d4ab11b2525",
                        "InstanceType": "t1.micro",
                        "KeyName": "my_key",
                        "UserData": "~"
                    }
                ],
                "SpotPrice": "0.04",
                "TargetCapacity": 1,
                "OnDemandTargetCapacity": 0,
                "Type": "maintain",
                "ReplaceUnhealthyInstances": false,
                "InstanceInterruptionBehavior": "terminate",
                "InstancePoolsToUseCount": 1
            },
            "SpotFleetRequestId": "sfr-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
            "SpotFleetRequestState": "active"
        }
    ]
}

リクエストで起動したインスタンスの情報を取得

以下のコマンドで,リクエストで起動したインスタンスの情報を取得できます.
sfr-で始まるリクエストIDはリクエストの実行のレスポンスに含まれていたものです.

aws ec2 describe-spot-fleet-instances \
--spot-fleet-request-id sfr-xxxxxx-xxxxx-xxx-xxxx-xxxxxxxxxx

以下のようなレスポンスがJSON形式で返ってきます.
インスタンスのIDとインスタンスの状態(Health)などがわかります.

{
    "ActiveInstances": [
        {
            "InstanceId": "i-xxxxxxxxxxxxxxxxx",
            "InstanceType": "t1.micro",
            "SpotInstanceRequestId": "sir-xxxxxxxx",
            "InstanceHealth": "healthy"
        }
    ]
}

4.リクエストのキャンセル・インスタンスの終了

以下のコマンドで,リクエストのキャンセルと,リクエストによって起動されているインスタンスを終了できます.
--terminate-instancesでインスタンスを終了しています.

aws ec2 cancel-spot-fleet-requests \
--spot-fleet-request-ids sfr-xxxxxx-xxxxx-xxx-xxxx-xxxxxxxxxx \
--terminate-instances

リクエストが成功すると,以下のようなレスポンスが返ってきます.
これで,リクエストのキャンセル・インスタンスの終了ができました.

{
    "SuccessfulFleetRequests": [
        {
            "CurrentSpotFleetRequestState": "cancelled_terminating",
            "PreviousSpotFleetRequestState": "active",
            "SpotFleetRequestId": "sfr-xxxxxx-xxxxx-xxx-xxxx-xxxxxxxxxx"
        }
    ],
    "UnsuccessfulFleetRequests": []
}

最後に

スポットフリートリクエストの方が,スポットインスタンスリクエストより新しいということもあり,扱いやすいと個人的には感じました.
ここではほんの一例を紹介しましたが,フリート(艦隊)なので,複数のスポットインスタンスをユーザの要件に応じて管理することもできます.

Discussion