> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Ec2 beanstalk lb https remediation

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        Below are console-only steps to enforce HTTPS for an Elastic Beanstalk (EC2) environment load balancer.

        ***

        ## 1. Get/Validate an SSL Certificate in ACM

        1. Go to **AWS Management Console** → **Certificate Manager (ACM)**.
        2. Choose **Request a certificate** → **Request a public certificate**.
        3. Enter your domain(s), e.g. `example.com` and `www.example.com`.
        4. Choose validation method:
           * **DNS validation** (recommended): ACM gives you CNAME records to add to your DNS (e.g., Route 53 or external).
           * Or **Email validation** if DNS isn’t an option.
        5. Complete validation. Wait until status is **Issued**.

        Keep the **ARN** of this certificate handy (you’ll select it in Elastic Beanstalk).

        ***

        ## 2. Confirm Your EB Environment Uses a Load Balancer

        1. Go to **Elastic Beanstalk** → select your **Application** → select your **Environment**.
        2. In the **Environment overview**, check the **Environment type**:
           * Must be **Load balanced** (either ALB or Classic ELB).
           * If it’s **Single instance**, you’ll need to create a new **Load balanced** environment (you can clone config).

        ***

        ## 3. Attach the SSL Certificate & Add HTTPS Listener

        ### For an Application Load Balancer (ALB) environment (most newer EB envs)

        1. In your environment page, choose **Configuration** from the left menu.
        2. Under **Load balancer**, click **Edit**.
        3. Look at the **Listeners** section:
           * You should see a listener on **Port 80, Protocol HTTP**.
        4. Add HTTPS listener:
           1. Click **Add listener** (or equivalent).
           2. Set:
              * **Port**: `443`
              * **Protocol**: `HTTPS`
           3. Under **SSL certificate**, choose:
              * **Choose from ACM** → select the certificate you created (ARN).
           4. Under **Default rules / Target group**, select the existing target group that your HTTP listener uses (so 443 forwards to the same instances/targets as 80).
        5. Save the configuration (e.g., **Apply** or **Save** on the page).
        6. Wait for Elastic Beanstalk to update the environment.

        ### For a Classic Load Balancer environment (older EB envs)

        1. From your EB environment **Configuration** page → under **Load balancer**, click **Edit**.
        2. Under **Listeners**, check existing:
           * You should see a listener `HTTP : 80 → HTTP : 80` (front-end to back-end).
        3. Add HTTPS listener:
           1. Add a new listener with:
              * **Load Balancer Protocol**: `HTTPS`
              * **Load Balancer Port**: `443`
              * **Instance Protocol**: `HTTP`
              * **Instance Port**: `80`
           2. For **SSL Certificate**, select your ACM certificate.
        4. Save and let EB update the environment.

        ***

        ## 4. Redirect HTTP (80) to HTTPS (443)

        You’ve now enabled HTTPS, but you should force redirect all HTTP traffic to HTTPS.

        ### Option A – At application level (simplest, recommended)

        Redirect in your app code / web server configuration:

        * **For a typical Node.js / Express app**, add middleware:
          ```js theme={null}
          app.use((req, res, next) => {
            if (req.headers['x-forwarded-proto'] !== 'https') {
              return res.redirect(301, 'https://' + req.headers.host + req.url);
            }
            next();
          });
          ```
        * **For Apache (PHP, etc.)** in `.htaccess`:
          ```apache theme={null}
          RewriteEngine On
          RewriteCond %{HTTP:X-Forwarded-Proto} !https
          RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
          ```
        * **For Nginx** in a config file in `.ebextensions` (if you control Nginx):

          `.ebextensions/https-redirect.config`:

          ```yaml theme={null}
          files:
            "/etc/nginx/conf.d/https_redirect.conf":
              mode: "000644"
              owner: root
              group: root
              content: |
                server {
                  listen 80;
                  return 301 https://$host$request_uri;
                }
          ```

        Deploy the updated application to EB.

        ### Option B – ALB listener rule (if using ALB)

        1. From the environment’s **Configuration** → **Load balancer** → find the **HTTP:80 listener**.
        2. Open **View rules** or **Edit rules** for the HTTP listener.
        3. Add a rule before the default:
           * Condition: `If` (e.g., `Path` is `/` or `/*` – or no condition if you want all).
           * Action: **Redirect**:
             * **Protocol**: `HTTPS`
             * **Port**: `443`
             * **Status code**: `HTTP_301`.
        4. Save the rules.

        ***

        ## 5. Test

        1. Browse to: `http://your-domain.com`.
        2. Confirm:
           * It redirects to `https://your-domain.com`.
           * The browser shows a valid padlock/secure connection.
        3. Also test direct `https://your-domain.com`.

        This fully enforces HTTPS for your Elastic Beanstalk EC2 environment using the AWS console.
      </Accordion>

      <Accordion title="Using CLI">
        Below are concise, CLI‑only steps to enforce HTTPS on an Elastic Beanstalk environment fronted by an Elastic Load Balancer (ALB / CLB) on EC2.

        ***

        ## 1. Get your environment & region info

        ```bash theme={null}
        ENV_NAME="my-eb-env"
        REGION="us-east-1"
        ```

        Verify:

        ```bash theme={null}
        aws elasticbeanstalk describe-environments \
          --region "$REGION" \
          --environment-names "$ENV_NAME"
        ```

        ***

        ## 2. Get / create an ACM certificate

        ```bash theme={null}
        DOMAIN_NAME="app.example.com"
        ```

        Request a public certificate (DNS validation):

        ```bash theme={null}
        aws acm request-certificate \
          --region "$REGION" \
          --domain-name "$DOMAIN_NAME" \
          --validation-method DNS \
          --idempotency-token "eb-https-$ENV_NAME"
        ```

        Note the `CertificateArn` from the output. Wait until its status is `ISSUED`:

        ```bash theme={null}
        CERT_ARN="arn:aws:acm:REGION:ACCOUNT:certificate/xxxx"
        aws acm describe-certificate \
          --region "$REGION" \
          --certificate-arn "$CERT_ARN" \
          --query "Certificate.Status"
        ```

        ***

        ## 3. Identify whether your EB environment uses ALB or Classic ELB

        ```bash theme={null}
        aws elasticbeanstalk describe-configuration-settings \
          --region "$REGION" \
          --environment-name "$ENV_NAME" \
          --query "ConfigurationSettings[0].OptionSettings[?Namespace=='aws:elasticbeanstalk:environment'].Value"
        ```

        Or simply:

        ```bash theme={null}
        aws elasticbeanstalk describe-configuration-settings \
          --region "$REGION" \
          --environment-name "$ENV_NAME" \
          --output json > config.json
        ```

        Look inside for:

        * `aws:elasticbeanstalk:environment` → `LoadBalancerType = application` → ALB
        * Or no such setting / default → usually Classic.

        ***

        ## 4A. For ALB (recommended): enforce HTTPS + redirect HTTP

        Use Elastic Beanstalk option settings to:

        * Configure HTTPS listener (443) with your ACM certificate
        * Keep HTTP (80) but redirect it to HTTPS

        Create a JSON file `alb-https-config.json`:

        ```json theme={null}
        [
          {
            "Namespace": "aws:elbv2:listener:443",
            "OptionName": "ListenerEnabled",
            "Value": "true"
          },
          {
            "Namespace": "aws:elbv2:listener:443",
            "OptionName": "Protocol",
            "Value": "HTTPS"
          },
          {
            "Namespace": "aws:elbv2:listener:443",
            "OptionName": "SSLCertificateArns",
            "Value": "CERT_ARN_REPLACE_ME"
          },
          {
            "Namespace": "aws:elbv2:listener:80",
            "OptionName": "ListenerEnabled",
            "Value": "true"
          },
          {
            "Namespace": "aws:elbv2:listener:80",
            "OptionName": "Protocol",
            "Value": "HTTP"
          },
          {
            "Namespace": "aws:elbv2:listener:80",
            "OptionName": "DefaultProcess",
            "Value": "default"
          },
          {
            "Namespace": "aws:elbv2:listener:80",
            "OptionName": "Rules",
            "Value": "RedirectToHTTPS"
          },
          {
            "Namespace": "aws:elbv2:listener-rule:RedirectToHTTPS",
            "OptionName": "PathPatterns",
            "Value": "/*"
          },
          {
            "Namespace": "aws:elbv2:listener-rule:RedirectToHTTPS",
            "OptionName": "Priority",
            "Value": "1"
          },
          {
            "Namespace": "aws:elbv2:listener-rule:RedirectToHTTPS",
            "OptionName": "Actions",
            "Value": "redirect"
          },
          {
            "Namespace": "aws:elbv2:listener-rule:RedirectToHTTPS",
            "OptionName": "RedirectConfig",
            "Value": "{\"Protocol\":\"HTTPS\",\"Port\":\"443\",\"StatusCode\":\"HTTP_301\"}"
          }
        ]
        ```

        Replace:

        ```bash theme={null}
        sed -i "s|CERT_ARN_REPLACE_ME|$CERT_ARN|" alb-https-config.json
        ```

        Apply to the environment:

        ```bash theme={null}
        aws elasticbeanstalk update-environment \
          --region "$REGION" \
          --environment-name "$ENV_NAME" \
          --option-settings file://alb-https-config.json
        ```

        Wait for the environment to finish updating, then test:

        * `http://app.example.com` → should 301 redirect to `https://app.example.com`
        * `https://app.example.com` → should work with a valid cert

        ***

        ## 4B. For Classic Load Balancer: HTTPS listener + (optional) HTTP→HTTPS

        ### 4B.1 Get the underlying ELB name

        From EB:

        ```bash theme={null}
        aws elasticbeanstalk describe-environment-resources \
          --region "$REGION" \
          --environment-name "$ENV_NAME" \
          --query "EnvironmentResources.LoadBalancers[0].Name" \
          --output text
        ```

        ```bash theme={null}
        ELB_NAME="output-from-above"
        ```

        ### 4B.2 Create/modify HTTPS listener on Classic ELB

        Add HTTPS (443) listener using your ACM cert (same region):

        ```bash theme={null}
        aws elb create-load-balancer-listeners \
          --region "$REGION" \
          --load-balancer-name "$ELB_NAME" \
          --listeners "Protocol=HTTPS,LoadBalancerPort=443,InstanceProtocol=HTTP,InstancePort=80,SSLCertificateId=$CERT_ARN"
        ```

        If HTTPS already exists, you can update the cert:

        ```bash theme={null}
        aws elb set-load-balancer-listener-ssl-certificate \
          --region "$REGION" \
          --load-balancer-name "$ELB_NAME" \
          --load-balancer-port 443 \
          --ssl-certificate-id "$CERT_ARN"
        ```

        ### 4B.3 (Optional but recommended) Redirect HTTP→HTTPS at the app

        Classic ELB does not support redirect rules; so either:

        * Keep port 80 listener and configure your app/web server to redirect to HTTPS, **or**
        * Remove the HTTP listener (forcing HTTPS only):

        ```bash theme={null}
        aws elb delete-load-balancer-listeners \
          --region "$REGION" \
          --load-balancer-name "$ELB_NAME" \
          --load-balancer-ports 80
        ```

        ***

        ## 5. Confirm security group allows 443 and (optionally) restricts 80

        Get the LB’s security group(s):

        ```bash theme={null}
        aws elb describe-load-balancers \
          --region "$REGION" \
          --load-balancer-names "$ELB_NAME" \
          --query "LoadBalancerDescriptions[0].SecurityGroups" \
          --output text
        ```

        ```bash theme={null}
        SG_ID="sg-xxxxx"
        ```

        Allow HTTPS from the internet:

        ```bash theme={null}
        aws ec2 authorize-security-group-ingress \
          --region "$REGION" \
          --group-id "$SG_ID" \
          --ip-permissions IpProtocol=tcp,FromPort=443,ToPort=443,IpRanges='[{\"CidrIp\":\"0.0.0.0/0\"}]'
        ```

        Optionally remove HTTP (80) if you’re not using it:

        ```bash theme={null}
        aws ec2 revoke-security-group-ingress \
          --region "$REGION" \
          --group-id "$SG_ID" \
          --protocol tcp \
          --port 80 \
          --cidr 0.0.0.0/0
        ```

        ***

        If you tell me whether your EB environment is using ALB or Classic ELB, I can trim this down to only the exact commands you need.
      </Accordion>

      <Accordion title="Using Python">
        Below are practical, step‑by‑step instructions to enforce HTTPS for an Elastic Beanstalk environment (EC2) and a minimal Python (boto3) example to apply it programmatically.

        ***

        ## 1. Prerequisites

        1. **Elastic Beanstalk environment** already running (Web Server, EC2).
        2. **Application Load Balancer (ALB)** or Classic ELB created by EB.
        3. **ACM certificate** in the same region as your Beanstalk environment:
           * Request via console: ACM → Request a certificate → Public → add domain → validate.
           * Note the certificate ARN, e.g.:
             ```
             arn:aws:acm:us-east-1:123456789012:certificate/...
             ```

        ***

        ## 2. Enforce HTTPS via Elastic Beanstalk configuration

        ### Option A – Configuration files (`.ebextensions` / `.platform`)

        **For ALB (most modern EB environments):**\
        Create `.ebextensions/https-alb.config` in your app root:

        ```yaml theme={null}
        option_settings:
          aws:elbv2:listener:443:
            ListenerEnabled: 'true'
            Protocol: HTTPS
            SSLCertificateArns: arn:aws:acm:us-east-1:123456789012:certificate/your-cert-id

          aws:elbv2:listener:80:
            ListenerEnabled: 'true'
            Protocol: HTTP
            DefaultProcess: default

          aws:elasticbeanstalk:environment:process:default:
            Port: '80'
            Protocol: HTTP
        ```

        Then add an HTTP→HTTPS redirect via ALB rules. For EB’s new ALB model, use a platform hook:

        Create `.platform/hooks/postdeploy/01-redirect-http-to-https.sh`:

        ```bash theme={null}
        #!/bin/bash
        set -e

        # Get environment name and region
        ENV_NAME=$(curl -s http://169.254.169.254/latest/meta-data/tags/instance/elasticbeanstalk:environment-name)
        REGION=$(curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | jq -r .region)

        # Get load balancer ARN
        LB_ARN=$(aws elasticbeanstalk describe-environment-resources \
          --environment-name "$ENV_NAME" \
          --region "$REGION" \
          --query "EnvironmentResources.LoadBalancers[0].Name" \
          --output text | xargs -I{} aws elbv2 describe-load-balancers \
            --names {} \
            --region "$REGION" \
            --query "LoadBalancers[0].LoadBalancerArn" \
            --output text)

        # Get HTTP listener ARN (port 80)
        HTTP_LISTENER_ARN=$(aws elbv2 describe-listeners \
          --load-balancer-arn "$LB_ARN" \
          --region "$REGION" \
          --query "Listeners[?Port==\`80\`].ListenerArn" \
          --output text)

        # Get HTTPS listener ARN (port 443)
        HTTPS_LISTENER_ARN=$(aws elbv2 describe-listeners \
          --load-balancer-arn "$LB_ARN" \
          --region "$REGION" \
          --query "Listeners[?Port==\`443\`].ListenerArn" \
          --output text)

        # Overwrite HTTP listener rule to redirect to HTTPS
        aws elbv2 modify-listener \
          --listener-arn "$HTTP_LISTENER_ARN" \
          --region "$REGION" \
          --default-actions Type=redirect,RedirectConfig="{Protocol=https,Port=443,StatusCode=HTTP_301}"
        ```

        Make it executable:

        ```bash theme={null}
        chmod +x .platform/hooks/postdeploy/01-redirect-http-to-https.sh
        ```

        Deploy the app (`eb deploy`); EB will:

        * Enable HTTPS listener 443 with your cert.
        * Keep HTTP listener 80 only for redirection.
        * Install redirect rule via the hook script.

        ***

        ## 3. Python (boto3) – Programmatically enforce HTTPS

        Below is an example to:

        1. Find the ALB used by your EB environment.
        2. Ensure HTTPS listener (443) exists with your ACM cert.
        3. Modify HTTP (80) listener to always redirect to HTTPS.

        ```python theme={null}
        import boto3

        REGION = "us-east-1"
        ENV_NAME = "my-beanstalk-env"
        ACM_CERT_ARN = "arn:aws:acm:us-east-1:123456789012:certificate/your-cert-id"

        eb = boto3.client("elasticbeanstalk", region_name=REGION)
        elbv2 = boto3.client("elbv2", region_name=REGION)

        def get_alb_arn_for_env(env_name: str) -> str:
            # Get ELB name from EB
            res = eb.describe_environment_resources(EnvironmentName=env_name)
            lbs = res["EnvironmentResources"].get("LoadBalancers", [])
            if not lbs:
                raise RuntimeError("No load balancer found for environment")
            lb_name = lbs[0]["Name"]

            # Map name to ALB ARN
            res2 = elbv2.describe_load_balancers(Names=[lb_name])
            return res2["LoadBalancers"][0]["LoadBalancerArn"]

        def ensure_https_and_redirect(lb_arn: str):
            listeners = elbv2.describe_listeners(LoadBalancerArn=lb_arn)["Listeners"]

            http_listener_arn = None
            https_listener_arn = None

            for l in listeners:
                if l["Port"] == 80 and l["Protocol"] == "HTTP":
                    http_listener_arn = l["ListenerArn"]
                if l["Port"] == 443 and l["Protocol"] == "HTTPS":
                    https_listener_arn = l["ListenerArn"]

            # 1) Create HTTPS listener if missing
            if not https_listener_arn:
                print("Creating HTTPS listener on 443...")
                # Use same default target group as HTTP
                default_actions = []
                if http_listener_arn:
                    http_details = elbv2.describe_listeners(ListenerArns=[http_listener_arn])[
                        "Listeners"
                    ][0]
                    default_actions = http_details["DefaultActions"]
                else:
                    raise RuntimeError("No HTTP listener found to copy target group from")

                resp = elbv2.create_listener(
                    LoadBalancerArn=lb_arn,
                    Protocol="HTTPS",
                    Port=443,
                    Certificates=[{"CertificateArn": ACM_CERT_ARN}],
                    DefaultActions=default_actions,
                )
                https_listener_arn = resp["Listeners"][0]["ListenerArn"]
                print("Created HTTPS listener:", https_listener_arn)

            # 2) Force HTTP → HTTPS redirect on port 80
            if not http_listener_arn:
                print("No HTTP listener found on port 80; creating one for redirect...")
                resp = elbv2.create_listener(
                    LoadBalancerArn=lb_arn,
                    Protocol="HTTP",
                    Port=80,
                    DefaultActions=[
                        {
                            "Type": "redirect",
                            "RedirectConfig": {
                                "Protocol": "HTTPS",
                                "Port": "443",
                                "StatusCode": "HTTP_301",
                            },
                        }
                    ],
                )
                http_listener_arn = resp["Listeners"][0]["ListenerArn"]
            else:
                print("Updating HTTP listener to redirect to HTTPS...")
                elbv2.modify_listener(
                    ListenerArn=http_listener_arn,
                    DefaultActions=[
                        {
                            "Type": "redirect",
                            "RedirectConfig": {
                                "Protocol": "HTTPS",
                                "Port": "443",
                                "StatusCode": "HTTP_301",
                            },
                        }
                    ],
                )

            print("HTTPS enforced for load balancer.")

        if __name__ == "__main__":
            lb_arn = get_alb_arn_for_env(ENV_NAME)
            ensure_https_and_redirect(lb_arn)
        ```

        Run this from a machine/CI with:

        * IAM permissions for `elasticbeanstalk:*`, `elasticloadbalancingv2:*`, `acm:ListCertificates` (or at least describe/modify for ALB and EB).
        * Credentials configured (env vars, `~/.aws/credentials`, or instance role).

        ***

        ## 4. Security group check (optional but recommended)

        Ensure the **load balancer security group**:

        * Allows inbound **80/tcp** (only if you need redirect) and **443/tcp** from the internet.
        * Your EC2 instances’ security group allows inbound from the LB SG on port **80** (if your app listens on 80).

        ***

        If you tell me your environment type (ALB vs Classic) and platform (e.g., Python 3.12 on AL2), I can adjust the config snippets exactly to that.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        # Application Load Balancer in front of your Elastic Beanstalk EC2 instances
        resource "aws_lb" "app_alb" {
          name               = "APP_ALB_NAME"                 # replace with your ALB name
          load_balancer_type = "application"
          subnets            = [SUBNET_ID_1, SUBNET_ID_2]     # replace with your subnet IDs
          security_groups    = [ALB_SECURITY_GROUP_ID]        # replace with SG that allows 80/443
        }

        # Target group for your Elastic Beanstalk EC2 instances
        resource "aws_lb_target_group" "app_tg" {
          name     = "APP_TG_NAME"                            # replace with your target group name
          port     = 80
          protocol = "HTTP"
          vpc_id   = VPC_ID                                   # replace with your VPC ID
        }

        # HTTP listener: redirects all HTTP requests to HTTPS (enforce HTTPS)
        resource "aws_lb_listener" "http_redirect" {
          load_balancer_arn = aws_lb.app_alb.arn
          port              = 80
          protocol          = "HTTP"

          default_action {
            type = "redirect"

            redirect {
              port        = "443"
              protocol    = "HTTPS"
              status_code = "HTTP_301"
            }
          }
        }

        # HTTPS listener: terminates TLS and forwards to the target group
        resource "aws_lb_listener" "https" {
          load_balancer_arn = aws_lb.app_alb.arn
          port              = 443
          protocol          = "HTTPS"
          ssl_policy        = "ELBSecurityPolicy-2016-08"     # or another approved policy
          certificate_arn   = ACM_CERTIFICATE_ARN            # replace with your ACM certificate ARN

          default_action {
            type             = "forward"
            target_group_arn = aws_lb_target_group.app_tg.arn
          }
        }
        ```

        This change does not force replacement of the load balancer itself, but adding/modifying listeners momentarily affects how traffic on those ports is handled; plan and apply during a maintenance window if your environment is sensitive.

        For verification, `terraform plan` should show:

        * creation (or update) of an HTTP listener on port 80 whose `default_action` is a `redirect` to HTTPS on port 443 with status `HTTP_301`.
        * creation (or confirmation) of an HTTPS listener on port 443 with a valid `certificate_arn` that forwards to your target group.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
