A common misconception is that Elastic Beanstalk is difficult to work with because it is not customizable. I fell into this trap myself when I first took a look at AWS Elastic Beanstalk. After working with AWS Elastic Beanstalk directly and looking at it more closely though, there are plenty of ways to customize Elastic Beanstalk. I’ll cover the main ways to customize AWS Elastic Beanstalk environments in this post.

Plethora of Ways to Customize Elastic Beanstalk

Ironically, I believe some of the misconception that Elastic Beanstalk is hard to configure is because there is an overabundance of ways in which to configure EB. Let’s look at the ways in which we can configured these Configuration Options according to the official Elastic Beanstalk Documentation:

The documentation is sectioned off to Before, During and After Creation to show that there are some slight differences in ways you can change the Configuration Options. Here’s a summary of the ways in a table of contents structure:

  • Setting Configuration Options Before Environment Creation
    • Configuration Files (.ebextensions)
    • Saved Configurations
    • JSON Document
    • EB CLI Configuration
  • Setting Configuration Options During Environment Creation
    • In the AWS Management Console
      • Using Configuration Files (.ebextensions)
      • Using a Saved Configuration
      • Using the New Environment Wizard
    • With the EB CLI
      • Using Configuration Files (.ebextensions)
      • Using Saved Configurations
      • Using Command Line Options
    • With the AWS CLI
      • Using Configuration Files (.ebextensions)
      • Using a Saved Configuration
      • Using Command Line Options
  • Setting Configuration Options After Environment Creation
    • The Elastic Beanstalk console
      • Using Configuration Files (.ebextensions)
      • Using a Saved Configuration
      • Using the Environment Management Console
    • The EB CLI
      • Using Configuration Files (.ebextensions)
      • Using a Saved Configuration
      • Using eb config
      • Using eb setenv
    • The AWS CLI
      • Using Configuration Files (.ebextensions)
      • Using a Saved Configuration
      • Using Command Line Options

Holy moly! It can hurt someone’s head looking at this the first time. Instead of painstalkingly walking through each of these methods, I’m going to take another approach to explain how to customize Elastic Beanstalk. I’ll break up the customizations into 3 categories that works better for my brain:

  1. Configuration Options/Resource Tweaking: Customizing the standard resources that EB launches and maintains for you.
  2. Ebextensions/Scripting Hooks: How to run scripts that do anything you want to the instance.
  3. Custom CloudFormation Resources: How to insert your own custom resources into EB.

Configuration Options/Resource Tweaking

Any resource that Elastic Beanstalk creates is customizable through what are called Configuration Options. As mentioned above there’s a vast array of options to how you can set these Configuration Options. We can change these configurations using the EB Console GUI, the eb config command, as CloudFormation code, with the aws cli tool, and even with ebextensions.

The important point is to understand that the Configuration Options allow us to adjust the resources that EB maintains. Underneath it all, EB implements the details with CloudFormation to spin up AWS resources. Configuration Options allow us to modify the properties on these CloudFormation resources. After you create an EB environment if you go over to the CloudFormation console, you see a stack with a awseb- prefix that is associated with your EB environment. Here’s an example of me using that stack name to get a list of the corresponding CloudFormation resources:

$ aws cloudformation describe-stack-resources --stack-name awseb-e-hmpjnryxdp-stack | jq '.StackResources[]' | grep ResourceType
  "ResourceType": "AWS::ElasticLoadBalancing::LoadBalancer",
  "ResourceType": "AWS::CloudFormation::WaitConditionHandle",
  "ResourceType": "AWS::CloudFormation::WaitConditionHandle",
  "ResourceType": "AWS::EC2::SecurityGroup",
  "ResourceType": "AWS::AutoScaling::LaunchConfiguration",
  "ResourceType": "AWS::AutoScaling::AutoScalingGroup",
  "ResourceType": "AWS::CloudFormation::WaitCondition",
  "ResourceType": "AWS::AutoScaling::ScalingPolicy",
  "ResourceType": "AWS::AutoScaling::ScalingPolicy",
  "ResourceType": "AWS::CloudWatch::Alarm",
  "ResourceType": "AWS::CloudWatch::Alarm",
  "ResourceType": "AWS::EC2::SecurityGroupIngress",
  "ResourceType": "AWS::RDS::DBSecurityGroup",
  "ResourceType": "AWS::RDS::DBInstance",
$

The Configuration Options exposes the porcelain of the resources that EB manages and allows you to change almost everything to them. There is very little you cannot change. The list of options is extremely comprehensive:

  • General Options for All Environments - This list is huge. As of this writing, there are 203 options that allow you configure things like Environment variables, AutoScaling, Launch Configs, VPC and more.
  • Platform Specific Options - There are even platform specific options. For example, if you are deploying a Ruby on Rails application, you can set RAILS_SKIP_MIGRATIONS.
  • Custom Options - This is for options that are completely custom to you. Let’s say you run a script later and want to reference a configuration option, this is a way to do that.

Tip: A really nice way to see all the Option Settings is using the eb config tool. Here’s an example. I’ve also written a tool called jack that makes use of these configuration files with a more streamlined flow, so you can preview your changes and version control them easily.

Ebextensions/Scripting Hooks

Ebextensions provides a hook in to boot up process of the EC2 instance that we can use to do things before and after the instance or container starts. You package up the scripts in .ebextensions directory in the root of your project and deploy the project. We can use ebextension to install packages, users, services, and run artbitary commands.

Good Starter Links:

Ebextensions leverages cloud-init to provide a YAML DSL that allows you do configuration management framework type of tasks like: packages, groups, users, sources, files, commands, services, container commands. All configuration management frameworks follow the same pattern.

  1. Install
  2. Configure
  3. Run Service

So for example, with ebextensions and cloud-init you can

  1. Install nginx
  2. Configure /etc/nginx/nginx.conf
  3. Ensure that nginx is always running with systemd

Custom CloudFormation Resources

Custom CloudFormation Resources is an advanced way of modifying and customizing ElasticBeanstalk. You can literally add any CloudFormation resource you want with it. If you wanted to have an additional SQS or an ElastiCache server you can add it. You also do this with ebextensions and adding it under the “Resources” key. Here’s the documentation on how to do this: EB CloudFormation Environment Resources

You can also modify the resources that EB spins up with this approach. An example of this is changing the Autoscaling HealthTypeCheck to ELB. This is not exposed as an Configuration Option but we can still modify it via ebextensions. We could also have a script that modifies things after the stack is done but it won’t be orchestrated, we’ll have to manually wait and then run a script.

Basically if we cannot figure out how to customize via Configuration Options or cloud-init, then we can modify the actual EB CloudFormation template that EB launches. This is very powerful.

Summary

Hopefully by breaking up how you can customize Elastic Beanstalk into different categories it helps explain it better. Here are the categories again:

  1. Configuration Options/Resource Tweaking: Customizing the standard resources that EB launches and maintains for you.
  2. Ebextensions/Scripting Hooks: How to run scripts that do anything you want to the instance.
  3. Custom CloudFormation Resources: How to insert your own custom resources into EB.

I hope this article helps you with AWS Elastic Beanstalk.