Skip to content

How can I configure HTTPS for my Elastic Beanstalk environment?

7 minute read
1

I want to configure HTTPS for my AWS Elastic Beanstalk environment to encrypt data from my load balancer to my Amazon Elastic Compute Cloud (Amazon EC2) instance.

Short description

If you configured a custom domain name for your Elastic Beanstalk environment, then use HTTPS to allow users to securely connect to your website. If you don't own a domain name, then use HTTPS with a self-signed certificate for development and testing purposes.

For single-instance environments, you must locally create the private key and certificate. Then, upload the certificate to AWS Identity and Access Management (IAM).

It's a best practice to use load balancers with AWS Certificate Manager (ACM) to programmatically provision, manage, and deploy your server certificates. You can also use the AWS Command Line Interface (AWS CLI) to upload a third-party or self-signed certificate and private key to IAM. If ACM isn't available in your AWS Region, then use the AWS CLI.

Resolution

Prepare your Elastic Beanstalk environment

Use Amazon Route 53 to register a new domain or another domain provider to route traffic to your Elastic Beanstalk environment.

If your environment's URL includes a Region, then create an alias name. If your environment's URL doesn't include a Region, then create a CNAME record.

Important: You can use CNAME records for environments that you created before 2016. You can't use a CNAME record with a zone apex domain, also known as a root domain or naked domain. For more information, see Comparison of alias and CNAME records.

Then, create a certificate in ACM, or upload a third-party or self-signed certificate and private key to IAM.

Add listeners to your load balancers

Complete the following steps:

  1. Open the Elastic Beanstalk console.
  2. Select your environment.
  3. In the navigation pane, choose Configuration.
  4. In the Load balancer category, choose Modify.
  5. To add the listener for port 443, complete the steps for the load balancer in your Elastic Beanstalk environment.
    Note: It's a best practice to use an Application Load Balancer or Network Load Balancer.

For Application Load Balancer

Complete the following steps:

  1. Choose Add Listener.
  2. For Port, enter the incoming traffic port. For example, 443.
  3. For Protocol, choose HTTPS.
  4. For SSL certificate, choose your certificate, and then select the SSL policy from the dropdown list.
  5. Choose Add, and then choose Apply.

For Network Load Balancer

Complete the following steps:

  1. Choose Add Listener.
  2. For Port, enter the incoming traffic port. For example, 443.
  3. Choose Add, and then choose Apply.

For Classic Load Balancer

Complete the following steps:

  1. Choose Add Listener.
  2. For Port, enter the incoming traffic port. For example, 443.
  3. For Protocol, choose HTTPS.
  4. For Instance Port, enter 80.
  5. For Instance Protocol, choose HTTP.
  6. For SSL certificate, choose your certificate, and then select the SSL policy from the dropdown list.
  7. Choose Add, and then choose Apply.

Configure your instances to stop HTTPS connections

To configure your instances to stop HTTPS connections, use the .ebextensions configuration file to modify the software that runs on the instances. For more information, see Terminating HTTPS on Amazon EC2 instances running .NET Core on Linux. Also, you can use configuration files to modify security groups to allow secure connections.

Important: If you use a single-instance environment, then skip the following steps. Complete the steps in the Stop HTTPS on the instance (end-to-end HTTPS) in a single-instance environment section.

To configure your instances to stop HTTPS connections, complete the following steps:

  1. Add a secure listener to your load balancer. Use one of the following configuration files based on the type of load balancer in your Elastic Beanstalk environment.
    For a Classic Load Balancer, use the .ebextensions/https-reencrypt-clb.config file:

    option_settings:
      aws:elb:listener:443:
        InstancePort: 443
        InstanceProtocol: HTTPS
      aws:elasticbeanstalk:application:
        Application Healthcheck URL: HTTPS:443/

    For an Application Load Balancer, use the .ebextensions/https-reencrypt-alb.config file:

    option_settings:
      aws:elbv2:listener:443:
        DefaultProcess: https
        ListenerEnabled: 'true'
        Protocol: HTTPS
      aws:elasticbeanstalk:environment:process:https:
        Port: '443'
        Protocol: HTTPS

    For a Network Load Balancer, use the .ebextensions/https-reencrypt-nlb.config file:

    option_settings:
      aws:elbv2:listener:443:
        DefaultProcess: https
        ListenerEnabled: 'true'
      aws:elasticbeanstalk:environment:process:https:
        Port: '443'
  2. Update the load balancer to receive traffic on port 443.
    You can create a new security group, and then have Elastic Beanstalk use the security group to receive traffic on port 443. For example, the following .ebextensions/https-lbsecuritygroup.config file creates a security group and attaches the security group to the load balancer:

    option_settings:
      # Use the custom security group for the load balancer
      aws:elb:loadbalancer:
        SecurityGroups: '`{ "Ref" : "loadbalancersg" }`'
        ManagedSecurityGroup: '`{ "Ref" : "loadbalancersg" }`'
    Resources:
      loadbalancersg:
        Type: AWS::EC2::SecurityGroup
        Properties:
          GroupDescription: load balancer security group
          VpcId: vpc-#######
          SecurityGroupIngress:
            - IpProtocol: tcp
              FromPort: 443
              ToPort: 443
              CidrIp: 0.0.0.0/0
            - IpProtocol: tcp
              FromPort: 80
              ToPort: 80
              CidrIp: 0.0.0.0/0
          SecurityGroupEgress:
            - IpProtocol: tcp
              FromPort: 80
              ToPort: 80
              CidrIp: 0.0.0.0/0

    Note: Replace VpcId with the value for your environment. The preceding example includes input and output over port 80 to allow HTTP connections. To allow only secure connections, remove the configuration for port 80 in the SecurityGroupIngress section.

  3. Add input and output rules that allow communication over port 443 between the load balancer's security group and the instances' security group.
    For example, use the following .ebextensions/https-backendsecurity.config file:

    Resources:
    # Add 443-inbound to instance security group (AWSEBSecurityGroup)
    httpsFromLoadBalancerSG:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
    GroupId: {"Fn::GetAtt" : ["AWSEBSecurityGroup", "GroupId"]}
    IpProtocol: tcp
    ToPort: 443
    FromPort: 443
    SourceSecurityGroupId: {"Fn::GetAtt" : ["loadbalancersg", "GroupId"]}
    balancer security group (loadbalancersg)
      httpsToBackendInstances: 
        Type: AWS::EC2::SecurityGroupEgress
        Properties:
          GroupId: {"Fn::GetAtt" : ["loadbalancersg", "GroupId"]}
          IpProtocol: tcp
          ToPort: 443
          FromPort: 443
          DestinationSecurityGroupId: {"Fn::GetAtt" : ["AWSEBSecurityGroup", "GroupId"]}
  4. Add the following snippet to your configuration file, and then save it in the .ebextensions directory:

    files:
      /etc/pki/tls/certs/server.crt:
        content: |
          -----BEGIN CERTIFICATE-----
          certificate file contents
          -----END CERTIFICATE-----
          
      /etc/pki/tls/certs/server.key:
        content: |      
          -----BEGIN RSA PRIVATE KEY-----
          private key contents 
          -----END RSA PRIVATE KEY-----

    Note: Replace certificate file contents with your certificate file content and private key contents with your private key content.

    The HTTPS Termination configuration varies depending on your solution stack. The .ebextensions for any solution stack hard codes the value of the private key and server certificate in the .ebextensions. To further secure these files, upload the file contents to Amazon Simple Storage Service (Amazon S3), and then use S3Auth to pull them to Amazon EC2.

  5. Use the files key to create the following files on the instance /etc/pki/tls/certs/server.crt.

  6. Use the following certificate file to create the certificate file on the instance: 

         -----BEGIN CERTIFICATE-----
      certificate file contents
      -----END CERTIFICATE-----
      -----BEGIN CERTIFICATE-----
      first intermediate certificate
      -----END CERTIFICATE-----
      -----BEGIN CERTIFICATE-----
      second intermediate certificate
      -----END CERTIFICATE----- 

    Note: Replace certificate file contents with the contents of your certificate. If you have intermediate certificates, then include them in server.crt after your site certificate.

  7. Use /etc/pki/tls/certs/server.key to create the private key file on the instance.
    Note: Replace private key contents with the contents of the private key used to create the certificate request or self-signed certificate.

  8. Configure the proxy server that runs on the instance to terminate HTTPS. All platforms start proxy server configuration in a uniform way.

  9. Add the configuration files to a directory that's named .ebextensions at the root of your application bundle to deploy configuration files to your environment.

  10. Deploy the source code that includes the configuration files.

Stop HTTPS on the instance (end-to-end HTTPS) in a single-instance environment

Use the .ebextensions file to allow incoming traffic on port 443 to the instance that your Elastic Beanstalk application runs on. 

Example:

Resources:
  sslSecurityGroupIngress: 
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      GroupId: {"Fn::GetAtt" : ["AWSEBSecurityGroup", "GroupId"]}
      IpProtocol: tcp
      ToPort: 443
      FromPort: 443
      CidrIp: 0.0.0.0/0

Then, configure the proxy server that runs on the instance to terminate HTTPS.

Note: The HTTPS Termination configuration varies depending on your solution stack. The .ebextensions for any solution stack hard codes the value of the private key and server certificate in the .ebextensions. To further secure these files, upload the file contents to Amazon Simple Storage Service (Amazon S3) and use S3Auth to pull them to Amazon EC2.

To deploy configuration files to your environment, add the configuration files to a directory that's named .ebextensions at the root of your application bundle. Then, deploy the source code that includes the configuration files.

AWS OFFICIALUpdated 6 months ago
6 Comments

Hello Another amazing day for all of Us :)

I have a single instance elastic beanstalk env (Ruby 2.7 running on 64bit Amazon Linux 2/3.6.8) and I want to enable https I must use configuration files https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/https-singleinstance-ruby.html but I need the certificate and the private key I created a public certificate in ACM I can get the certificate with the command aws acm get-certificate --certificate-arn arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012 but I cannot find how can I get the private key

How can I get the private key of my ACM public certificate? What is the suggested way for my issue?

Thank you in advance for your kind help and support

With my warmest regards for all the World

replied 2 years ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

AWS
MODERATOR
replied 2 years ago

I am struggling to determine whether my .ebextensions configuration files are being read properly. Any help in debugging this? The .ebextensions folder and the yaml files ending in .config are definitely included in the archive.

replied 2 years ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

AWS
EXPERT
replied 2 years ago

Thanks for the article.

There's one small typo:

The preceding example includes ingress and egress over port 80 to allow HTTPS connections. To allow only secure connections, remove the configuration for port 80 in the SecurityGroupIngress section. I think there should be "to allow HTTP connections" instead.

replied 8 months ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

AWS
MODERATOR
replied 8 months ago