<p>I have a kubernetes cluster and an express server serving a SPA. Currently if I hit the http version of my website I do not redirect to https, but I would like to.</p>

<p>This is what I've tried -</p>

<pre><code>import express from "express";
const PORT = 3000;
const path = require("path");
const app = express();
const router = express.Router();

const forceHttps = function(req, res, next) {
  const xfp =
    req.headers["X-Forwarded-Proto"] || req.headers["x-forwarded-proto"];
  if (xfp === "http") {
    console.log("host name");
    console.log(req.hostname);
    console.log(req.url);
    const redirectTo = `https:\/\/${req.hostname}${req.url}`;
    res.redirect(301, redirectTo);
  } else {
    next();
  }
};

app.get("/*", forceHttps);

// root (/) should always serve our server rendered page
// other static resources should be served as they are
const root = path.resolve(__dirname, "..", "build");
app.use(express.static(root, { maxAge: "30d" }));
app.get("/*", function(req, res, next) {
  if (
    req.method === "GET" &amp;&amp;
    req.accepts("html") &amp;&amp;
    !req.is("json") &amp;&amp;
    !req.path.includes(".")
  ) {
    res.sendFile("index.html", { root });
  } else {
    next();
  }
});

// tell the app to use the above rules
app.use(router);

app.listen(PORT, error =&gt; {
  console.log(`listening on ${PORT} from the server`);
  if (error) {
    console.log(error);
  }
});
</code></pre>

<p>This is what my kubernetes config looks like</p>

<pre><code>apiVersion: v1
kind: Service
metadata:
  name: &lt;NAME&gt;
  labels:
    app: &lt;APP&gt;
  annotations:
    # Note that the backend talks over HTTP.
    service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http
    service.beta.kubernetes.io/aws-load-balancer-ssl-cert: &lt;CERT&gt;
    # Only run SSL on the port named "https" below.
    service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https"
spec:
  type: LoadBalancer
  selector:
    app: &lt;APP&gt;
  ports:
    - port: 443
      targetPort: 3000
      protocol: TCP
      name: https
    - port: 80
      targetPort: 3000
      protocol: TCP
      name: http
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: &lt;DEPLOYMENT_NAME&gt;
  labels:
    app: &lt;APP&gt;
spec:
  replicas: 1
  selector:
    matchLabels:
      app: &lt;APP&gt;
  template:
    metadata:
      labels:
        app: &lt;APP&gt;
    spec:
      containers:
        - name: &lt;CONTAINER_NAME&gt;
          image: DOCKER_IMAGE_NAME
          imagePullPolicy: Always
          env:
            - name: VERSION_INFO
              value: "1.0"
            - name: BUILD_DATE
              value: "1.0"
          ports:
            - containerPort: 3000
</code></pre>

<p>I successfully hit the redirect...but the browser does not actually redirect. How do I get it to redirect from http to https?</p>

<p>Relatedly, from googling around I keep seeing that people are using an Ingress AND a Load Balancer - why would I need both?</p>

praks5432
<p>When you LoadBalancer type service in EKS it will either create a classic or a network load balancer.None of these support http to https redirection. You need an application load balancer(ALB) which supports http to https redirection.In EKS to use ALB you need to use <a href="https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html" rel="nofollow noreferrer">AWS ALB ingress controller</a>. Once you have ingress controller setup you can use <a href="https://kubernetes-sigs.github.io/aws-alb-ingress-controller/guide/tasks/ssl_redirect/" rel="nofollow noreferrer">annotation to redirect http to https</a></p>

<pre><code>apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  namespace: default
  name: ingress
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-west-2:xxxx:certificate/xxxxxx
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
    alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}
</code></pre>
