Close

SSL On Single Instance Elastic Beanstalk Tutorial

In this tutorial, I am going to show you how to deploy free SSL on Elastic Beanstalk Single Instance by deploy SSL via ebextension without using other services such as Route53, CloudFront and etc.

Objective of this tutorial is very simple : I just want a free SSL for my website without extra cost from other AWS services!

AWS Certificate Manager (ACM) is an easy solution to provision, manage, and deploy SSL certificate within AWS services such as:

  • Elastic Load Balancing
  • Amazon CloudFront
  • AWS Elastic Beanstalk
  • Amazon API Gateway
  • AWS CloudFormation

Although AWS claimed that Elastic Beanstalk is supported but there are many users still having difficulty to deploy ACM Certificate into Elastic Beanstalk single instance due to the certificate is ONLY WORK ON Elastic Beanstalk Load Balancer environment!

However, we are going to deploy a free SSL on Elastic Beanstalk Single Instance by using LetsEncrypt because it is a FREE and Trusted Certificate Authority!

In this tutorial, we are using the following settings:

  • AWS Elastic Beanstalk (PHP Environment)
  • index.php

Step 1: Create .ebextensions folder in your application root folder.

Step 2: Create https-instance-securitygroup.config file inside .ebextensions folder.
This is how it look like: .ebextensions/https-instance-securitygroup.config

Step 3: edit https-instance-securitygroup.config with any editor and paste the following code:

packages:
  yum:
    mod24_ssl : []

files:
  "/etc/httpd/conf.d/ssl_rewrite.conf":
    mode: "000644"
    owner: root
    group: root
    content: |
        RewriteEngine On
        RewriteCond %{HTTP:X-Forwarded-Proto} !https
        RewriteRule . https://%{SERVER_NAME}%{REQUEST_URI} [L,R=301]

  /etc/httpd/conf.d/ssl.conf:
    mode: "000644"
    owner: root
    group: root
    content: |
      LoadModule ssl_module modules/mod_ssl.so
      Listen 443
      <VirtualHost *:443>
        <Proxy *>
          Order deny,allow
          Allow from all
        </Proxy>

        SSLEngine             on
        SSLCertificateFile "/etc/letsencrypt/live/LETSENCRYPT_DOMAIN/fullchain.pem"
        SSLCertificateKeyFile "/etc/letsencrypt/live/LETSENCRYPT_DOMAIN/privkey.pem"
        SSLCipherSuite        EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
        SSLProtocol           All -SSLv2 -SSLv3
        SSLHonorCipherOrder   On
        SSLSessionTickets     Off

        Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
        Header always set X-Frame-Options DENY
        Header always set X-Content-Type-Options nosniff
        
        ProxyPass / http://localhost:80/ retry=0
        ProxyPassReverse / http://localhost:80/
        ProxyPreserveHost on
        RequestHeader set X-Forwarded-Proto "https" early
        
      </VirtualHost>
  "/opt/elasticbeanstalk/tasks/taillogs.d/letsencrypt.conf":
    mode: "000755"
    owner: root
    group: root
    content: |
      /var/log/letsencrypt/letsencrypt.log

container_commands:
# installs certbot
  10_stop_apache:
    command: "killall httpd ; sleep 3"
  10_replace_placeholders:
    command: |
      source /opt/elasticbeanstalk/support/envvars
      SED_EXPRESSION='s/LETSENCRYPT_DOMAIN/'$LETSENCRYPT_DOMAIN'/g'
      echo $SED_EXPRESSION
      sed -i -e $SED_EXPRESSION /etc/httpd/conf.d/ssl.conf
  20_install_certbot:
    command: "mkdir -p /opt/certbot &amp;&amp; wget https://dl.eff.org/certbot-auto -O /opt/certbot/certbot-auto &amp;&amp; chmod a+x /opt/certbot/certbot-auto"
  30_install_certificate:
    command: |
      source /opt/elasticbeanstalk/support/envvars
      sudo /opt/certbot/certbot-auto certonly --debug --non-interactive --email ${LETSENCRYPT_EMAIL} --agree-tos --standalone -d "$LETSENCRYPT_DOMAIN" -d "www.$LETSENCRYPT_DOMAIN" --renew-by-default
  40_start_apache:
    command: |
      source /opt/elasticbeanstalk/support/envvars
      sudo httpd -k start

Step 4: Zip your application with .ebextensions folder
Yout folder structure will look like
_ _ _ .ebextensions
         |_ _ https-instance-securitygroup.config
_ _ _ index.php
_ _ _ config.php

Step 5: Go to AWS Console -> Elastic Beanstalk and select your environment and click Configuration

Step 6: Scroll to the bottom and add two environment properties and fill up your own value:
1) LETSENCRYPT_DOMAIN
2) LETSENCRYPT_EMAIL

Step 7: Click Apply button

Step 8: Go to Dashboard -> Upload and Deploy -> Upload the your application zip file that contains .ebextensions folder just now. That’s it!


Hit Enter