Using .ebextensions to extend nginx default configuration in AWS Elastic Beanstalk

Manoj Acharya
The Startup
Published in
4 min readMay 24, 2019

AWS Elastic Beanstalk helps us quickly deploy and manage applications in the AWS Cloud without having to learn about the infrastructure that runs those applications. It automatically handles the deployment, from capacity provisioning, load balancing, auto-scaling to application health monitoring. It comes with so many cool features that make our life easier. On top of that, we only pay for resources to run the applications, not for the service itself.

This post will address how I utilized the .ebextensions configuration file to extend the nginx default configuration in /etc/nginx/nginx.conf.

The problem

The Elastic Beanstalk environment has a classic load balancer with an idle timeout of 120s and pointing to an auto-scaling group of instances running Docker containers on 64bit Amazon Linux. The environment uses nginx as a web server.

Some of our web service hosted by nginx requires more than 60 seconds (which is more than the default keepalive timeout for nginx i.e 60 s). This caused the load balancer to throw 504 gateway timeout error. Somehow I have to increase the waiting time in the nginx configuration before sending timeout errors.

The default nginx configuration

Below is the default Elastic Beanstalk nginx configuration which is located at /etc/nginx/nginx.conf for most of the distributions. The location of this file will vary depending on how you installed the software on your machine. To validate and test the configuration file and find the location of the file, you can use service nginx configtest command.

# Elastic Beanstalk Nginx Configuration Fileuser  nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;

log_format healthd '$msec"$uri"$status"$request_time"$upstream_response_time"$http_x_forwarded_for';
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}

Breaking down the configuration

The file contains different sets of brackets ({}) called contexts, which contains different directives configurations. Each context is separated as they specify the configuration for a different area of concern.

The “events” context is used to set global options that affect how Nginx handles connections at a general level. When configuring Nginx as a web server or reverse proxy, the “http” context will hold the majority of the configuration. This context will contain all of the directives and other contexts necessary to define how the program will handle HTTP or HTTPS connections.

Our main motive is to add the keepalive_timeout directive inside the “http” context and other supporting directives. So to do this, we do not actually change anything inside this file but we utilize what is already in there.

Noticed the include directive inside the “http” context? These directives tell the configuration to include all the .conf files inside /etc/nginx/conf.d and /etc/nginx/sites-enabled directory. So what we actually do is create a file inside /etc/nginx/conf.d using the .ebextension feature in Elastic Beanstalk.

You can read more about the structure of the configuration file here.

Creating the .ebextensions configuration file

We can use AWS Elastic Beanstalk Configuration files (.ebextensions) in our source code to configure the environment and customize the AWS resources. We create configuration files in YAML or JSON format with a .config file extension and place inside the .ebextensions directory. The .ebextensions folder resides in the root folder of the source code.

In this case, we need to add a new configuration file inside /etc/nginx/conf.d using the .ebextensions. Since we are getting 504 gateway timeout error, we need to add keepalive_timeout and other supporting directives to the “http” context of the main nginx configuration file.

To create the .ebextensions config file, follow the steps,

  1. Create a file with extension .config inside the .ebextension folder. You can choose any file name but you have to keep in mind that the config files will be processed in alphabetical order, so it is suggested to use numbers while naming. For eg. 01-timeout.config
  2. Inside the config file, use the files key to create files on the instance and the container_commands key to run system commands after the application and web server has been set up but before the application is deployed. The 01-timeout.config file looks like this,
files:
“/etc/nginx/conf.d/01-timeout.conf”:
mode: “000644”
owner: root
group: root
content: |
keepalive_timeout 120s;
proxy_connect_timeout 120s;
proxy_send_timeout 120s;
proxy_read_timeout 120s;
fastcgi_send_timeout 120s;
fastcgi_read_timeout 120s;
container_commands:
nginx_reload:
command: “sudo service nginx reload”

3. Now you can bundle the source code including the .ebextensions folder in the root directory and deploy the package to the Elastic Beanstalk environment. Elastic Beanstalk automatically creates the 01-timeout.conf file inside /etc/nginx/conf.d folder and is included in the main elastic beanstalk nginx configuration.

That is just a simple example of using the .ebextensions configuration file to configure our Elastic Beanstalk environment. Needless to say, EB Configuration files have so much to offer. Overall a great service of AWS, the Elastic Beanstalk.

--

--