Reputation: 891
I am setting up AWS Elastic Beanstalk application and I want the traffic to it to be HTTPS.
I created a DNS CNAME record matching the beanstalk url and created and approved a certificate for that DNS name in AWS Certificate Manager.
Now I went to Elastic Beanstalk environment --> Configuration --> Network Tier / Load Balancer (Image below) in order to set the "Secure listener port" from OFF to 443 and choose my certificate.
But my certificate is not there to choose from ! So My question is how to get my certificate or a certificate into that selection list, or is that a bug in AWS?
Note - I was able to see my certificate when going to EC2 / Load balancers and was able to change the load balancer from HTTP to HTTPS and choose my certificate there. But this did not reflect on Elastic Beanstalk load balancer configuration that still shows port 80. Using HTTPS to the beanstalk did not work this way.
Help!
Upvotes: 0
Views: 1231
Reputation: 891
The answer by Brian FitzGerald and this blog helped me figure out a simple way to do that (set https on the Elastic beanstalk load balancer and use a CRM certificate for it).
The solution is simpler using AWS Elastic Beanstalk CLI (eb for short). After you set up the environment properly you can use eb config
command.
When the edit window opens up scroll down to aws:elb:loadbalancer
section.
Modify the load balancer section to be so (in my case I removed port 80 altogether, you may want to keep it):
aws:elb:loadbalancer:
CrossZone: 'true'
LoadBalancerHTTPPort: 'OFF'
LoadBalancerHTTPSPort: '443'
LoadBalancerPortProtocol: HTTP
LoadBalancerSSLPortProtocol: HTTPS
SSLCertificateId: PLACE HERE THE CRM CERTIFICATE ARN
SecurityGroups: '{"Fn::GetAtt":["AWSEBLoadBalancerSecurityGroup","GroupId"]},{"Ref":"AWSEBLoadBalancerSecurityGroup"}'
The arn of the certificate can be found in AWS > Certificate Manager. Open the certificate and copy the ARN number (on the bottom right).
I saved the configuration, waited for the environment to get updated and that was it.
Upvotes: 0
Reputation: 3109
Through the console, there is currently no way to assign your certificate you created in the Certificate Manager to your Beanstalk environment.
In order to accomplish this, you will need to use the AWS CLI. I was able to accomplish this, and luckily, it is easy.
In short, you need to:
update environment
command to apply your certificate to your environmentaws elasticbeanstalk update-environment --environment-name Your-Environment --option-settings file://PATH-TO-JSON/elb-acm.json
For me the path was simply file://elb-ecm.json
since (I believe the reason is because) I was running the command while in the web root and the file was in that same directory This article goes into detail (and worked for me). Good luck!
Please note, though you can, you should NOT assign the certificate directly through the Load Balancer console (EC2 > Load Balancers) because the load balancer will be blown away and recreated whenever you rebuild your Beanstalk Environment.
Also, make sure you have setup your certificate how you want it before you apply it to your Beanstalk environment. For example, if you want *.mydomain.com and the naked mydomain.com to both be secure, make sure that's fully configured first since there is no easy way to "de-associate" your certificate from your environment once your run these commands (you would basically need to terminate your environment altogether and create a new one if I'm not mistaken in this scenario).
Also, you will want to have some redirect code in your app to perform a 301 redirect on any non-secure request coming in once you have your certificate setup. To perform the redirect you will need to look for the X-Forwarded-Proto
header on the incoming request. If it's not secure, you should redirect to the secure port. For example, here is how my application code looks:
// in production, only allow secure requests (https)
public function performSecureRedirect(rc) {
// based on domain comparison
var isLive = myEnvironmentData.isLive;
// setting up the health check url is important for smooth beanstalk deployments
// beanstalk issues this healthcheck request via a non-secure port
var isAmazonHealthcheckUrl = rc.event eq "system.healthcheck";
if (isLive and not isAmazonHealthcheckUrl) {
var headerData = getHTTPRequestData().headers;
// x-forwarded-proto is a special header
// setup by Amazon ELB (Elastic Load Balancer)
var requestProtocol = getHttpRequestData().headers['x-forwarded-proto'];
var isSecureRequest = requestProtocol eq "https";
if (not isSecureRequest) {
location("https://" & cgi.server_name & cgi.path_info, false, 301);
}
}
}
Upvotes: 1