Elastic Beanstalk made simple: End-to-End automation with CloudFormation

Vivek Sethia
Beck et al.
Published in
4 min readMay 15, 2020

Elastic Beanstalk is an orchestration service provided by Amazon Web Services (AWS) to create web applications easily and quickly. As an end user, one would just need to either upload the code (which can be in any of the following languages: Java, .NET, PHP, Node.js, Python, Ruby, or Go) or the Docker images, and all the complexities pertaining to server capacity, scalability, application health monitoring, and load balancing are handled by the Elastic Beanstalk application.

In this article, we will focus on the creation of a single container application running on Nginx server as an example. I will try and demonstrate how to create such an Elastic Beanstalk application using a CloudFormation template as well as configure the server for enhanced security. As a pre-requisite, we will need an Amazon S3 bucket where the relevant .ebextensions directory for advanced configuration and the Dockerrun.aws.json file will be uploaded. The latter takes care of deploying the Docker image from the Elastic Container Registry (ECR) to the created Elastic Beanstalk application. The ECR will be created as part of the CloudFormation stack.

Before getting into details regarding the setup, let us understand the architecture. We are using a nested CloudFormation template which creates the below-mentioned architecture having an ECR and ElasticBeanstalk Application. It also creates the relevant IAM policies required for ECR and Elastic Beanstalk application. Furthermore, it creates a user with access to ECR. You can use either the credentials of this user for pushing images to ECR or ignore if you already have a user with relevant push permissions to ECR. We will not be going into the details of CloudFormation and its nested template here as that is an extensive topic in itself.

Architecture components for the application described in this article

Note: For the following steps, you will need the relevant permissions on AWS to create (IAM) roles. I will henceforth assume that Administrator Access on AWS is available.

Steps to follow:

  1. Create a zip file containing the relevant config files (.ebextensions and Dockerrun.aws.json mentioned above).
  2. For Dockerrun.aws.json, you may use this file from the repository after replacing the AWS account id, project name, and environment name under the Image name section.
  3. The .ebextensions available here can directly be used, without any modifications. For further details regarding the various files within this folder, refer to the section at the end of this article.
  4. Create an S3 bucket (let's call it configuration-bucket) and add the created zip file.
  5. Create another S3 bucket (let’s call this one template-bucket) and add the all the template files available here.
  6. Log in to the AWS console and navigate to CloudFormation. Provide the S3 object URL of main-template.yaml file to quickly set up the environment ( from Step 5). The following table lists the parameters required for configuring the CloudFormation template.
Used Parameters explanation for the Cloud Formation Template

Note: We have to select two private (parameters q,r) and two public (parameters s,t) subnets in two different availability zones to ensure reliable applications with high availability.
The combination of the project (parameter n) and prod/test environment name (parameter l/m) will be the actual environment name on AWS.

6. After completely filling out the parameters, create the CloudFormation stack. This results in the environment being created, albeit failed deployment.

7. Push the Docker image(s) for the desired application(s) to the relevant ECR repository and then re-build the Elastic Beanstalk application environment (created at the end of Step 6) for a successful deployment. You can follow this AWS documentation for pushing docker images to ECR.

Let's dive into the different files within .ebextensions directory:

  1. Configuring the Nginx server:
  • The files key is used to create a file called 02_proxy.conf in the /etc/nginx/conf.d/ directory. Further details can be found in the AWS documentation.
  • The file mode has been set to “00644” and the owner and the group have been set to root.
  • The server_tokens being set to off ensures that server tokens (such as server engine version) are hidden. Specifying the Content-Security-Policy to be “script-src ‘self’” enforces a strict content security policy that prevents malicious attacks, like cross-site scripting attacks.

2. Monitoring the application health

The below-mentioned file sets the health reporting of the application to enhanced, which helps in detail monitoring of the application. Further details can be found in the AWS documentation.

3. Minor/Patch update of the platform running the application

This particular configuration enables the managed update settings of the application and sets the maintenance window of minor/patch update to every Sunday at 21:00 UTC. This is essential as the supported platforms keep changing over time and such auto maintenance keeps the application running without interruption.

4. Redirection of HTTP to HTTPS on the load balancer:

Considering the usage of an Application Load Balancer, the following configuration file creates a redirection rule on the load balancer of the application which ensures that only HTTPS requests are served.

5. Restarting the Nginx server:

This configuration is needed to apply the relevant changes to the Nginx server.

  • The files key is used to create a file called 06_nginx_restart.sh in the /opt/elasticbeanstalk/hooks/appdeploy/post/ directory. Further details can be found in the AWS documentation.
  • The file mode has been set to “000755” and the owner and the group have been set to root.
  • The content key includes the command for restarting the Nginx server.

Thanks for reading and feel free to comment with your suggestions/feedback for improvement.

In an upcoming article, I will showcase the automated deployment on Elastic Beanstalk application triggered by a push to ECR using AWS Codepiepeline.

--

--