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 you can use HTTPS to allow users to securely connect to your website. If you don't own a domain name, then you can 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 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.

Note: If you receive errors when you run AWS Command Line Interface (AWS CLI) commands, then see Troubleshoot AWS CLI errors. Also, make sure that you're using the most recent AWS CLI version.

Resolution

Prepare your Elastic Beanstalk environment

  1. To route traffic to your Elastic Beanstalk environment, use Amazon Route 53 to register a new domain or another domain provider.
  2. 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 Choosing between alias and non-alias records.
  3. 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

  1. Open the Elastic Beanstalk console, and then select your environment.
  2. In the navigation pane, choose Configuration.
  3. In the Load balancer category, choose Modify.
  4. To add the listener for port 443, complete the steps for the load balancer that's in your Elastic Beanstalk environment.

Classic Load Balancer

Complete the following steps:

  1. Choose Add Listener.
  2. For Port, enter the incoming traffic port, typically 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 choose the SSL policy from the dropdown list.
  7. Choose Add, and then choose Apply.

Application Load Balancer

Complete the following steps:

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

Network Load Balancer

Complete the following steps:

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

Configure your instances to terminate HTTPS connections

To configure your instances to terminate HTTPS connections, use configuration files to modify the software that's running on the instances. Also, use configuration files to modify security groups so that they allow secure connections.

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

  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:
    
  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 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.

  3. Add ingress and egress 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"]}
      # Add 443-outbound to load 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"]}

    The load balancer now uses HTTPS to securely connect to your backend instances. The load balancer accepts any certificate from the instance, such as a self-signed certificate or one that a trusted certificate authority issues.

    Note: You can add policies to the load balancer that tell that load balancer to trust only a specific certificate. For example, the following .ebextensions/https-backendauth.config file creates two policies. One policy specifies a public certificate, and the other policy tells the load balancer to trust only the public certificate for connections to port 443.

    option_settings:
      # Backend Encryption Policy
      aws:elb:policies:backendencryption:
        PublicKeyPolicyNames: backendkey
        InstancePorts:  443
      # Public Key Policy
      aws:elb:policies:backendkey:
        PublicKey: |
          -----BEGIN CERTIFICATE-----
          ################################################################
          ################################################################
          ################################################################
          ################################################################
          ################################################
          -----END CERTIFICATE-----
  4. Configure the proxy server that runs on the instance to terminate HTTPS.

    Note: The 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, you can upload the contents to Amazon Simple Storage Service (Amazon S3) and use S3Auth to pull them to Amazon EC2.

  5. 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.

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

  1. Allow incoming traffic on port 443 to the instance that your Elastic Beanstalk application is running on.

    The following example uses .ebextensions to allow incoming traffic on port 443:

    Resources:
      sslSecurityGroupIngress: 
        Type: AWS::EC2::SecurityGroupIngress
        Properties:
          GroupId: {"Fn::GetAtt" : ["AWSEBSecurityGroup", "GroupId"]}
          IpProtocol: tcp
          ToPort: 443
          FromPort: 443
          CidrIp: 0.0.0.0/0
  2. Configure the proxy server that runs on the instance to terminate HTTPS.

    Note: The 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, you can upload the contents to Amazon S3 and use S3Auth to pull them to Amazon EC2.

  3. 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 OFFICIAL
AWS OFFICIALUpdated 6 months ago
4 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

aaon
replied 10 months ago

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

profile pictureAWS
MODERATOR
replied 10 months 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 8 days ago

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

profile pictureAWS
MODERATOR
replied 8 days ago