I'm developing with django on elastic beanstalk and I want to make two changes to apache configuration:
1. redirect www.domain.com to domain.com
2. redirect http://domain.com to https://domain.com
I don't have experience with apache configuration, googling it gave me the idea that I should put RewriteRules in .htaccess file.
example: How to force https on amazon elastic beanstalk without failing the health check
I couldn't find instructions on how to do it with elastic beanstalk configuration (.ebextensions), I tried to simply put a .htaccess file in my root filder and deploy but it didn't work.
Does anyone know how it's possible to add the RewriteRules in elastic beanstalk?
For example, an Elastic Beanstalk environment with an Apache Tomcat container uses the Amazon Linux operating system, Apache web server, and Apache Tomcat software. For a list of supported container types, see Elastic Beanstalk supported platforms.
AWS Elastic Beanstalk is an easy-to-use service for deploying and scaling web applications and services developed with Java, . NET, PHP, Node. js, Python, Ruby, Go, and Docker on familiar servers such as Apache, Nginx, Passenger, and IIS.
Having www.example.com
go to example.com
can be done with a CNAME in DNS if you don't care about having it actually being a redirect. If you need a redirect, you can add it to the Apache config below. The primary point of this answer is to detail how you modify Apache config on Elastic Beanstalk (because doing this properly is not very straight forward).
This answer assumes you have already enabled https in the load balancer security group, added the SSL certificate to the load balancer, added 443 to the ports forwarded by the load balancer, and pointed your domain name at the Elastic Beanstalk environment with Route 53 (or equivalent DNS service).
Most AWS Linux version 2 based platforms have the option to pick Apache as your proxy host. This can be done by going to "Configuration" > "Software" > "Container Options" and setting "Proxy Server" to "Apache", or adding the following to one of your .config
files in .ebextensions
:
option_settings: aws:elasticbeanstalk:environment:proxy: ProxyServer: apache
On AWS Linux 2, Apache is configured exclusively through adding files to your codebase in .plaform/httpd/conf.d/
, from which they will get added to the server's Apache config. You can no longer edit Apache files through .ebextensions
.
To do an HTTP to HTTPS redirect using Apache, add a configuration file named .platform/httpd/conf.d/ssl_rewrite.conf
to your codebase (relevant AWS docs) with the following contents:
RewriteEngine On <If "-n '%{HTTP:X-Forwarded-Proto}' && %{HTTP:X-Forwarded-Proto} != 'https'"> RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L] </If>
Note that nginx can be configured in a similar way, namely by adding a .conf
file to .platform/nginx/conf.d/
(though the contents of this file will obviously be different).
All you need to do is add the following to one of your .config
files in the .ebextensions
directory of your project:
files: "/etc/httpd/conf.d/ssl_rewrite.conf": mode: "000644" owner: root group: root content: | RewriteEngine On <If "-n '%{HTTP:X-Forwarded-Proto}' && %{HTTP:X-Forwarded-Proto} != 'https'"> RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L] </If>
This is moderately straight forward outside of Elastic Beanstalk. One usually adds an Apache rewrite rule like the following:
RewriteCond %{HTTPS} off RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
Or, if behind a load balancer, like we are in this case:
RewriteCond %{HTTP:X-Forwarded-Proto} !https RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
However, these configurations only work within a <VirtualHost>
block. Changing the RewriteCond
to an <If>
block allows it to work properly outside of a <VirtualHost>
block, allowing us to put in in a standalone Apache config file. Note that standard Apache setup on CentOS (including the setup on ElasticBeanstalk) inculdes all files matching /etc/httpd/conf.d/*.conf
, which matches the file path where we are storing this file.
The -n '%{HTTP:X-Forwarded-Proto}'
part of the condition prevents it from redirecting if you are not behind a load balancer, allowing you to have shared configuration between a production evironment with a load balancer and https, and a staging environment that is single instance and does not have https. This is not necessary if you are using load balancers and https on all of your environments, but it doesn't hurt to have it.
I have seen a lot of bad solutions to this problem, and it is worth going through them to understand why this solution is necessary.
Use Cloudfront: Some people suggest using non-cached Cloudfront setup in front of Elastic Beanstalk to do the HTTP to HTTPS redirect. This adds a whole new service (thus adding complexity) that isn't exactly appropriate (Cloudfront is a CDN; it's not the right tool for forcing HTTPS on inherantly dynamic content). Apache config is the normal solution to this problem and Elastic Beanstalk uses Apache, so that's the way we should go.
SSH into the server and...: This is completely antithetical to the point of Elastic Beanstalk and has so many problems. Any new instances created by autoscaling won't have the modified configuration. Any cloned environments won't have the configuration. Any number of a reasonable set of environment changes will wipe out the configuration. This is just such a bad idea.
Overwrite the Apache config with a new file: This is getting into the right realm of solution but leaves you with a maintenance nightmare if Elastic Beanstalk changes aspects of the server setup (which they very well may do). Also see the problems in the next item.
Dynamically edit the Apache config file to add a few lines: This is a decent idea. The problems with this is that it won't work if Elastic Beanstalk ever changes the name of their default Apache config file, and that this file can get overwritten when you least expect: https://forums.aws.amazon.com/thread.jspa?threadID=163369
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With