Using .ebextensions to extend nginx default configuration in AWS Elastic Beanstalk
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,
- 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
- 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.