Elastic Beanstalk でキャパシティ予約のグループを使用して EC2 オンデマンドキャパシティ予約を適用するには

2022.08.31

困っていた内容

Elastic Beanstalk が作成する EC2 インスタンスに対して、以下の利用資格且つリソースグループを指定して EC2 のオンデマンドキャパシティ予約を適用したいです。

インスタンスの利用資格:この予約を指定するインスタンスのみを受け入れます。

適格性:targeted

リソースグループ

設定方法を教えてください。

どう対応すればいいの?

Elastic Beanstalk 環境の AutoScaling グループが使用する起動テンプレートにキャパシティ予約の設定を追加し、リソースグループを指定する必要があります。

設定するためには、.ebextensions 配下に以下の内容を記述した設定ファイル xxx.config をアプリケーションのソースコードに追加し、デプロイします。

Resources:
  AWSEBEC2LaunchTemplate:
    Type: AWS::EC2::LaunchTemplate
    Properties:
      LaunchTemplateData:
        CapacityReservationSpecification: 
          CapacityReservationTarget:
            CapacityReservationResourceGroupArn: arn:aws:resource-groups:ap-northeast-1:アカウントID:group/リソースグループ名

CapacityReservationResourceGroupArn にはリソースグループの ARN を指定します。

やってみた

おおまかな流れは以下になります。

  1. キャパシティ予約の作成
  2. リソースグループの作成とグループヘの追加
  3. AWS のドキュメントからサンプルコードをダウンロード
  4. .ebextensions 配下に .config ファイルを配置
  5. Elastic Beanstalk で環境を作成
  6. 作成された EC2 インスタンスにてキャパシティ予約が適用されていることを確認

キャパシティ予約の作成

グループで利用する想定のため、キャパシティ予約を ap-northeast-1a、ap-northeast-1c で1つずつ、計2つ作成しました。

キャパシティ予約の作成については割愛します。詳細は以下ブログをご参照ください。
RIを購入せずに任意の期間でEC2のキャパシティを確保可能になりました

リソースグループの作成とグループヘの追加

リソースグループを作成します。

リソースグループの作成は AWS CLI にて行います。

$ aws resource-groups create-group --name CR-ResourceGroup --configuration '{"Type":"AWS::EC2::CapacityReservationPool"}' '{"Type":"AWS::ResourceGroups::Generic", "Parameters": [{"Name": "allowed-resource-types", "Values": ["AWS::EC2::CapacityReservation"]}]}'

{
    "Group": {
        "GroupArn": "arn:aws:resource-groups:ap-northeast-1:アカウントID:group/CR-ResourceGroup",
        "Name": "CR-ResourceGroup"
    },
    "GroupConfiguration": {
        "Configuration": [
            {
                "Type": "AWS::EC2::CapacityReservationPool"
            },
            {
                "Type": "AWS::ResourceGroups::Generic",
                "Parameters": [
                    {
                        "Name": "allowed-resource-types",
                        "Values": [
                            "AWS::EC2::CapacityReservation"
                        ]
                    }
                ]
            }
        ],
        "Status": "UPDATE_COMPLETE"
    }
}

リソースグループ作成後、先ほど作成したキャパシティ予約の ARN を指定してグループへ追加します。

$ aws resource-groups group-resources --group CR-ResourceGroup --resource-arns arn:aws:ec2:ap-northeast-1:アカウントID:capacity-reservation/cr-06xxxxxxxxxxxxxxx arn:aws:ec2:ap-northeast-1:アカウントID:capacity-reservation/cr-0exxxxxxxxxxxxxxx

{
    "Succeeded": [
        "arn:aws:ec2:ap-northeast-1:アカウントID:capacity-reservation/cr-06xxxxxxxxxxxxxxx",
        "arn:aws:ec2:ap-northeast-1:アカウントID:capacity-reservation/cr-0exxxxxxxxxxxxxxx"
    ],
    "Failed": [],
    "Pending": []
}

リソースグループ内のキャパシティーの予約の一覧を確認します。

$ aws resource-groups list-group-resources --group CR-ResourceGroup

※結果省略

マネジメントコンソールからも確認が可能です。

グループ ARN の情報は後ほど使用します。

AWS のドキュメントからサンプルコードをダウンロード

以下のドキュメントからサンプルコードをダウンロードします。プラットフォームは Python で検証するため、Python のサンプルコードをダウンロードします。

https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/tutorials.html

.ebextensions 配下に .config ファイルを配置

先ほど作成したリソースグループのグループ ARN を CapacityReservationResourceGroupArn に指定し ec2launchtemplate.config として保存します。

Resources:
  AWSEBEC2LaunchTemplate:
    Type: AWS::EC2::LaunchTemplate
    Properties:
      LaunchTemplateData:
        CapacityReservationSpecification: 
          CapacityReservationTarget:
            CapacityReservationResourceGroupArn: arn:aws:resource-groups:ap-northeast-1:アカウントID:group/CR-ResourceGroup

.ebextensions 配下に ec2launchtemplate.config を配置し、zip コマンドにてソースバンドルを作成します。

$ ls -al
drwxrwxrwx 1 root root 4096 Aug 30 10:58 .ebextensions
-rwxrwxrwx 1 root root  612 May 30  2020 EBSampleApp-Python.iml
-rwxrwxrwx 1 root root 4982 Jun  6  2020 application.py
-rwxrwxrwx 1 root root   84 Jan 15  2020 cron.yaml
$ cd .ebextensions/
$ ls -al
-rwxrwxrwx 1 root root 215 Jan 15 2020 00sample_log.config*
-rwxrwxrwx 1 root root 246 Jul 2 16:39 ec2launchtemplate.config*
$ cd ..
$ zip ../python-myapp.zip -r * .[^.]*
updating: cron.yaml (deflated 24%)
updating: application.py (deflated 60%)
updating: .ebextensions/ (stored 0%)
updating: .ebextensions/00sample_log.config (deflated 53%)
updating: EBSampleApp-Python.iml (deflated 47%)
  adding: .ebextensions/ec2launchtemplate.config (deflated 46%)
$

Elastic Beanstalk で環境を作成

Elastic Beanstalk で検証用の環境を作成します。 先ほど作成した「python-myapp.zip」を選択してアップロードを実施します。 今回は検証のため AZ(アベイラビリティーゾーン) を指定したいため、「より多くのオプションの設定」でカスタム設定を追加します。

EC2 インスタンスタイプおよび AZ を指定したいため、容量の変更を行います。

環境タイプを負荷分散に変更
今回は EC2 インスタンスを2台作成したいため、最小、最大を「2」に変更します。

インスタンスタイプは t3.micro のみに指定
AZ は ap-northeast-1a、ap-northeast-1c を指定します。

上記設定で「保存」→「環境の作成」を押下し Elastic Beanstalk 環境の作成完了まで待ちます。

作成された EC2 インスタンスにてキャパシティ予約が適用されていることを確認

EC2 インスタンスが2台作成され、キャパシティーの予約 ID に先ほど作成したキャパシティ予約が適用されていることを確認しました。

キャパシティ予約の画面でも利用可能な数量が 0 になっており、2台の EC2 インスタンスに適用されていることを確認しました。

補足

作成したリソースグループはマネジメントコンソール上から削除できないため、リソースグループを削除したい場合は AWS CLI を利用します。

$ aws resource-groups delete-group --group CR-ResourceGroup

参考資料

キャパシティーの予約 グループの操作 - Amazon Elastic Compute Cloud

Elastic Beanstalk 環境リソースの追加とカスタマイズ - AWS Elastic Beanstalk

Elastic Beanstalk が環境向けに作成するリソースを変更する - AWS Elastic Beanstalk

コマンドラインからソースバンドルを作成する - AWS Elastic Beanstalk

AWS::EC2::LaunchTemplate CapacityReservationSpecification - User Guide