Checking the behavior of .extensions in Elastic Beanstalk

Checking the behavior of .extensions in Elastic Beanstalk.

We will review the configuration options for Elastic Beanstalk.
According to the following page, there are four configuration options for Elastic Beanstalk.

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

  1. Settings applied directly to the environment
  2. Saved settings
  3. Configuration files (.ebextensions)
  4. Default Values

The top is a higher priority.

This time we will use .ebextensions to change the settings.
Specifically, we will check the behavior of the following pattern.

  • Items set only in .ebextensions
  • Items that conflict with higher-level configuration options (saved settings)

Environment

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

Create a minimally configured Elastic Beanstalk environment.
Select Web Server for the Elastic Beanstalk environment.
Choose Python 3.8 as the platform.

Check the behavior of .ebextensions in this configuration.

Specifically, CodeBuild will build the source bundle for Elastic Beanstalk, but it will also create .ebextensions as well.
The trigger to run this CodeBuild is a CloudFormation custom resource.

CloudFormation template files

The above configuration is built with CloudFormation.
The CloudFormation templates are placed at the following URL

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

Explanation of key points of template files

The purpose of this page is to check the behavior of .ebextensions.

Specifically, attempt to configure the following in the saved settings and .ebestensions

PropertiesSaved Configurations.ebextensions
aws:elasticbeanstalk:environment EnvironmentTypeSingleInstanceLoadBalanced
aws:autoscaling:launchconfiguration IamInstanceProfileInstanceProfile
aws:autoscaling:launchconfiguration InstanceTypet3.nano

For basic information on Elastic Beanstalk, please refer to the following pages.

あわせて読みたい
Introduction to Elastic Beanstalk with CloudFormation 【Introduction to Elastic Beanstalk with CloudFormation】 Elastic Beanstalk will be covered. With Elastic Beanstalk, you can quickly deploy and manage applic...

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)

Use CodeBuild to create source bundles for Elastic Beanstalk.

Describe the contents of buildspec.yaml in the BuildSpec property.

Create two files in the pre_build phase.

The first is a Python script that runs on Elastic Beanstalk.
It is simple enough to return the current date and time.

The second is a configuration file for .ebextensions.
This time we name it sample.config.
This content sets the environment type to “LoadBalanced” and the instance type to “t3.nano”.
In .ebextensions described below, the former is set and the latter is not.

Place these files in the following directory structure

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

This is then zipped and placed in an S3 bucket as a source bundle for 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)

We will focus on the items related to the saved settings.

The key point is the first setting.
This item concerns instance profiles.
Specifies the instance profile associated with the IAM role for the EC2 instance.
This is an item that is not set in .ebextensions.

Another key point is the second setting.
This item is related to the environment type.
Specify “t3.nano” for this item.
This item is set for .ebextensions.

Architecting

Use CloudFormation to build this environment and check its actual behavior.

Create CloudFormation stacks and check the resources in the stacks

Create CloudFormation stacks.
For information on how to create stacks and check each stack, please see the following page.

あわせて読みたい
CloudFormation’s nested stack 【How to build an environment with a nested CloudFormation stack】 Examine nested stacks in CloudFormation. CloudFormation allows you to nest stacks. Nested ...

After reviewing the resources in each stack, information on the main resources created in this case is as follows

  • CodeBuild Project: dva-01-002
  • Elastic Beanstalk application: dva-01-002-application
  • Elastic Beanstalk environment: dva-01-002-env

Check the creation status of each resource from the AWS Management Console.

Check the working status of your CodeBuild project.

Detail of CodeBuild 1.

Indeed, the CodeBuild project is running.

Incidentally, the buildspec.yml of the executed project is as follows

Detail of CodeBuild 2.

As specified in CloudFormation. Build a Python script to run on Elastic Beanstalk and a configuration file for .ebextensions.

Operation Check

Now that it is ready, check the created Elastic Beanstalk.

First, look at the Elastic Beanstalk environment.

Detail of Elastic Beanstalk 1.

Indeed, an environment is created.

Next, check the Elastic Beanstalk application.

Detail of Elastic Beanstalk 2.

This one is also created successfully.
The event reads that one EC2 instance (i-0be44ab4041ef92ba) has been built.

Also check the CloudFormation stack automatically generated by Elastic Beanstalk.

Detail of CloudFormation 1.

Among the various resources generated, you can see that the Auto Scaling group is included.
We can see that the EC2 instance we just created was automatically created by the Auto Scaling group.

Looking at this set of resources, we notice that there are no ELB resources.
In .ebextensions, we specified “LoadBalanced” and in the saved configuration, “SingleInstance”.
If the same item is set in both, the saved setting will take precedence.

Next, check the generated instance.

Detail of EC2 1.

If you look at Instance Type, you will see “t3.nano”.
That is, for items set only in .ebextensions, this value can override the default value.

Next, look at the IAM Role value.
The IAM role generated by CloudFormation is specified.

Check this IAM role.

Detail of EC2 2.

If you look at the policy attached to the IAM role, it is still the IAM role created by CloudFormation.
This means that the saved configuration specified the IAM role (instance profile) that will be associated with the instance.

Here is a summary of the results of the verification so far.
Elastic Beanstalk can be configured with saved settings and .ebextensions.
If the same item is set in both, the saved configuration takes precedence.

Summary

Elastic Beanstalk .extensions behavior.