Elastic Beanstalkの.extensionsの挙動を確認する

Elastic Beanstalkの.extensionsの挙動を確認する。

Elastic Beanstalkにおける設定オプションについて確認します。
以下のページによりますと、Elastic Beanstalkの設定オプションは4つ存在します。

https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/command-options.html

  1. 環境に直接適用される設定
  2. 保存済み設定
  3. 設定ファイル (.ebextensions)
  4. デフォルト値

上の方が優先順位が高いです。

今回は.ebextensionsを使用して設定変更します。
具体的には以下のパターンの挙動を確認します。

  • .ebextensionsでのみ設定した項目
  • 上位の設定オプション(保存済み設定)と競合する項目

構築する環境

Diagram of checking the behavior of .extensions in Elastic Beanstalk.

最小構成のElastic Beanstalk環境を構築します。
Elastic Beanstalkの環境はWebサーバーを選択します。
プラットフォームはPython3.8を選択します。

本構成において、.ebextensionsの挙動を確認します。

具体的には、CodeBuildでElastic Beanstalk用のソースバンドルをビルドしますが、.ebextensionsも同様に作成します。
このCodeBuildを実行するトリガーは、CloudFormationカスタムリソースを使用します。

CloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。

https://github.com/awstut-an-r/awstut-dva/tree/main/01/002

テンプレートファイルのポイント解説

本ページでは、.ebextensionsの挙動を確認することを目的としています。

具体的には、保存された設定および.ebestensionsで以下の通りに設定を試みます。

設定項目保存された設定.ebextensions
aws:elasticbeanstalk:environment EnvironmentTypeSingleInstanceLoadBalanced
aws:autoscaling:launchconfiguration IamInstanceProfileInstanceProfile
aws:autoscaling:launchconfiguration InstanceTypet3.nano

Elastic Beanstalkに関する基本的な事項については、以下のページをご確認ください。

あわせて読みたい
CloudFormationを使用してElastic Beanstalk入門 【CloudFormationを使用してElastic Beanstalk入門】 Elastic Beanstalkを取り上げます。 Elastic Beanstalk を使用すると、アプリケーションを実行しているインフラス...

CodeBuild

Resources:
  CodeBuildProject:
    Type: AWS::CodeBuild::Project
    Properties:
      Artifacts:
        Type: NO_ARTIFACTS
      Cache:
        Type: NO_CACHE
      Environment:
        ComputeType: !Ref ProjectEnvironmentComputeType
        EnvironmentVariables:
          - Name: BUCKET_NAME
            Type: PLAINTEXT
            Value: !Ref BucketName
          - Name: ENVIRONMENT_TYPE
            Type: PLAINTEXT
            Value: !Ref EnvironmentType
          - Name: INSTANCE_TYPE
            Type: PLAINTEXT
            Value: !Ref InstanceType
          - Name: SOURCE_BUNDLE_NAME
            Type: PLAINTEXT
            Value: !Ref SourceBundleName
          - Name: SOURCE_FILE_NAME
            Type: PLAINTEXT
            Value: !Ref SourceFileName
        Image: !Ref ProjectEnvironmentImage
        ImagePullCredentialsType: CODEBUILD
        Type: !Ref ProjectEnvironmentType
        PrivilegedMode: true
      LogsConfig:
        CloudWatchLogs:
          Status: DISABLED
        S3Logs:
          Status: DISABLED
      Name: !Ref Prefix
      ServiceRole: !GetAtt CodeBuildRole.Arn
      Source:
        Type: NO_SOURCE
        BuildSpec: !Sub |
          version: 0.2

          phases:
            pre_build:
              commands:
                - |
                  cat << EOF > $SOURCE_FILE_NAME
                  import datetime

                  def application(environ, start_response):
                      response = str(datetime.datetime.now())
                      start_response("200 OK", [
                          ("Content-Type", "text/html")
                      ])
                      return [bytes(response, 'utf-8')]
                  EOF
                - mkdir .ebextensions
                - |
                  cat << EOF > .ebextensions/sample.config
                  option_settings:
                    aws:elasticbeanstalk:environment:
                      EnvironmentType: $ENVIRONMENT_TYPE
                    aws:autoscaling:launchconfiguration:
                      InstanceType: $INSTANCE_TYPE
                  EOF
            build:
              commands:
                - zip $SOURCE_BUNDLE_NAME -r * .[^.]*
            post_build:
              commands:
                - aws s3 cp $SOURCE_BUNDLE_NAME s3://$BUCKET_NAME/
      Visibility: PRIVATE
Code language: YAML (yaml)

CodeBuildを使用して、Elastic Beanstalk用のソースバンドルを作成します。

BuildSpecプロパティでbuildspec.yamlの中身を記載します。

pre_buildフェーズで2つのファイルを作成します。

1つ目はElastic Beanstalk上で実行するPythonスクリプトです。
現在日時を返すシンプルな内容です。

2つ目は.ebextensions用の設定ファイルです。
今回はsample.configという名前とします。
環境タイプを「LoadBalanced」に、インスタンスタイプを「t3.nano」に設定する内容です。
後述する.ebextensionsにおいて、前者は設定し、後者は設定しません。

これらのファイルを以下のディレクトリ構造で配置します。

% tree -a
.
├── .ebextensions
│   └── sample.config
└── application.pyCode language: plaintext (plaintext)

これをZIP化してS3バケットに配置し、Elastic Beanstalk用ソースバンドルとします。

Elastic Beanstalk Configuration Template

Resources:
  ConfigurationTemplate:
    Type: AWS::ElasticBeanstalk::ConfigurationTemplate
    Properties:
      ApplicationName: !Ref Application
      OptionSettings:
        - Namespace: aws:autoscaling:launchconfiguration
          OptionName: IamInstanceProfile
          Value: !Ref InstanceProfile
        - Namespace: aws:elasticbeanstalk:environment
          OptionName: EnvironmentType
          Value: !Ref EnvironmentType
        - Namespace: aws:elasticbeanstalk:environment
          OptionName: ServiceRole
          Value: !Sub "arn:aws:iam::${AWS::AccountId}:role/service-role/aws-elasticbeanstalk-service-role"
        - Namespace: aws:ec2:vpc
          OptionName: VPCId
          Value: !Ref VPC
        - Namespace: aws:ec2:vpc
          OptionName: Subnets
          Value: !Ref PublicSubnet1
      SolutionStackName: !Ref SolutionStackName

  InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Path: /
      Roles:
        - !Ref InstanceRole

  InstanceRole:
    Type: AWS::IAM::Role
    DeletionPolicy: Delete
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action: sts:AssumeRole
            Principal:
              Service:
                - ec2.amazonaws.com
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AWSElasticBeanstalkWebTier
Code language: YAML (yaml)

保存された設定に関係する項目に注目します。

ポイントは1つ目の設定です。
本項目はインスタンスプロファイルに関するものです。
EC2インスタンス用のIAMロールを関連づけたインスタンスプロファイルを指定します。
これは.ebextensionsでは設定していない項目です。

もう1つのポイントは2つ目の設定です。
本項目は環境タイプに関するものです。
本項目に「t3.nano」を指定します。
これは.ebextensionsでは設定している項目です。

環境構築

CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。

CloudFormationスタックを作成し、スタック内のリソースを確認する

CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。

あわせて読みたい
CloudFormationのネストされたスタックで環境を構築する 【CloudFormationのネストされたスタックで環境を構築する方法】 CloudFormationにおけるネストされたスタックを検証します。 CloudFormationでは、スタックをネストす...

各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。

  • CodeBuildプロジェクト:dva-01-002
  • Elastic Beanstalkアプリケーション:dva-01-002-application
  • Elastic Beanstalk環境:dva-01-002-env

AWS Management Consoleから各リソースの作成状況を確認します。

CodeBuildプロジェクトの動作状況を確認します。

Detail of CodeBuild 1.

確かにCodeBuildプロジェクトが実行されています。

ちなみに実行されたプロジェクトのbuildspec.ymlは以下のものです。

Detail of CodeBuild 2.

CloudFormationで指定した通りの内容です。
Elastic Beanstalk上で実行するPythonスクリプトと、.ebextensions用の設定ファイルをビルドします。

動作確認

準備が整いましたので、作成されたElastic Beanstalkを確認します。

まずElastic Beanstalk環境を見ます。

Detail of Elastic Beanstalk 1.

確かに環境が作成されています。

次にElastic Beanstalkアプリケーションを確認します。

Detail of Elastic Beanstalk 2.

こちらも正常に作成されています。
イベントを見ると、1台のEC2インスタンス(i-0be44ab4041ef92ba)が構築されたことが読み取れます。

Elastic Beanstalkによって自動的に生成されたCloudFormationスタックも確認します。

Detail of CloudFormation 1.

様々なリソースが生成された中で、Auto Scalingグループが含まれていることがわかります。
先ほどのEC2インスタンスはAuto Scalingグループによって、自動的に生成されたものであることがわかります。

このリソース群を見ると、ELBリソースがないことに気づきます。
.ebextensionsでは、「LoadBalanced」、保存された設定では、「SingleInstance」を指定しました。
両者で同じ項目を設定した場合、設定された保存が優先されることがわかります。

次に生成されたインスタンスを確認します。

Detail of EC2 1.

Instance Typeを見ると、「t3.nano」とあります。
つまり.ebextensionsでのみ設定した項目に関しては、この値でデフォルトの値を上書きすることができます。

次にIAM Roleの値を見ます。
CloudFormationで生成したIAMロールが指定されています。

このIAMロールを確認します。

Detail of EC2 2.

IAMロールにアタッチされているポリシーを見ると、やはりCloudFormationで作成したIAMロールですね。
つまり保存された設定によって、インスタンスに関連付けられるIAMロール(インスタンスプロファイル)が指定されたということです。

今までの検証の結果をまとめます。
Elastic Beanstalkは保存された設定、および.ebextensionsで設定できます。
両者で同じ項目を設定した場合、設定された保存が優先されます。

まとめ

Elastic Beanstalkの.extensionsの挙動を確認しました。