How do I use TLS certificates to activate HTTPS connections for my Amazon EKS applications?

4 minute read
0

I want to use TLS certificates to activate HTTPS connections for my Amazon Elastic Kubernetes Service (Amazon EKS) applications.

Short description

To activate HTTPS connections for your Amazon EKS applications, complete the following tasks:

  • Get a valid TLS certificate for your custom domain.
  • Use the load balancer service type to expose your Kubernetes service, or use AWS Load Balancer Controller to expose your Kubernetes ingress object.
  • Associate your custom domain with the DNS of the load balancer.

Resolution

Get a valid TLS certificate for your custom domain

To get a valid TLS certificate for your custom domain, complete the following steps:

  1. Request a public AWS Certificate Manager (ACM) certificate for your custom domain, or upload your own TLS certificate to ACM.

  2. Identify the ARN of the certificate that you want to use with the load balancer's HTTPS listener.

  3. To create a sample NGINX deployment, run the following command:

    $ kubectl create deploy web --image=nginx --port 80 --replicas=3
  4. To verify that Kubernetes pods are deployed on your Amazon EKS cluster, run the following command:

    $ kubectl get pods -l app=web

    Note: The pods are labeled app=web. Use this label as a selector for the service object to identify a set of pods.

Use the load balancer service type to expose your Kubernetes service

Note: To use the ingress object to expose your application, continue to the Expose your Kubernetes service using the ingress object section.

To use the load balancer service type to expose your Kubernetes service, complete the following steps:

  1. To create a service.yaml manifest file, use the service type LoadBalancer:

    cat <<EOF > loadbalancer.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: lb-service
      annotations:
        # Note that the backend talks over HTTP.
        service.beta.kubernetes.io/aws-load-balancer-type: external
        # TODO: Fill in with the ARN of your certificate.
        service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:{region}:{user id}:certificate/{id}
        # Run TLS only on the port named "https" below.
        service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https"
        # By default In-tree controller will create a Classic LoadBalancer if you require a NLB uncomment below annotation.
        # service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
    spec:
      selector:
        app: web
      ports:
      - name: http
        port: 80
        targetPort: 80
      - name: https
        port: 443
        targetPort: 80
      type: LoadBalancer
    EOF
  2. Edit the annotation service.beta.kubernetes.io/aws-load-balancer-tls-cert to include the ACM's ARN.

  3. To apply the loadbalancer.yaml file, run the following command:

    $ kubectl create -f loadbalancer.yaml
  4. Continue to the Associate your custom domain with the DNS of the load balancer section.

Use the ingress object to expose your Kubernetes service

Note: The following resolution assumes that you've installed AWS Load Balancer Controller in your Amazon EKS cluster. For more information, see aws-load-balancer-controller on the GitHub website.

To use the ingress object to expose your Kubernetes service, complete the following steps:

  1. Create a Kubernetes service of type NodePort based on the following example:
    cat  <<EOF  > ingressservice.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: web-nginx
    spec:
      ports:
        - port: 80
          targetPort: 80
          protocol: TCP
      type: NodePort
      selector:
        app: web
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: "web-nginx-ingress"
      annotations:
        # Below annotation is to specify if the loadbalancer is "internal" or "internet-facing"
        alb.ingress.kubernetes.io/scheme: internet-facing
        # TODO: Fill in with the ARN of your certificate.
        alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-west-2:xxxx:certificate/xxxxxx
        # TODO: Fill in the listening ports.
        alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
        # Set HTTP to HTTPS redirects. Every HTTP listener configured is redirected to below mentioned port over HTTPS.
        alb.ingress.kubernetes.io/ssl-redirect: '443'
      labels:
        app: web
    spec:
      ingressClassName: alb
      rules:
        - http:
            paths:
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: "web-nginx"
                    port:
                      number: 80
    EOF
    Note: The preceding ingress manifest listens on HTTP and HTTPS, then terminates TLS on Application Load Balancer, and then redirects HTTP to HTTPS.
  2. To apply the ingressservice.yaml file, run the following command:
    $ kubectl create -f ingressservice.yaml

Associate your custom domain with the DNS of the load balancer

To associate your custom domain with the DNS of the load balancer, complete the following steps:

  1. To return the DNS URL of the service of type LoadBalancer, run the following command:

    $ kubectl get service
  2. To return the DNS URL of the service of type Ingress, run the following command:

    $ kubectl get ingress/web-nginx-ingress
  3. Associate your custom domain name with your load balancer name.

  4. In a web browser, test your custom domain with the following HTTPS protocol:

    https://yourdomain.com
AWS OFFICIAL
AWS OFFICIALUpdated 7 months ago
8 Comments

Thank you for this documentation, it has been really helpful

Two questions:

On the section:

Expose your Kubernetes service using the ingress object

Is the annotation for tls-redirect the correct one or was it meant to be ssl-redirect?, see:

metadata:
  name: "web-nginx-ingress"
  annotations:
    ...
    # Set HTTP to HTTPS redirects. Every HTTP listener configured will be redirected to below mentioned port over HTTPS.
    alb.ingress.kubernetes.io/tls-redirect: '443'

I was digging to learn more about it, and I don't seem to find more about tls-redirect annotation anywhere, not even in the AWS ALB repo, only the ssl-redirect annotation appears:

I've been looking into this since I'm trying to fix an issue with "Can't verify CSRF token authenticity." on my setup after enabling TLS termination for my back-end through exposing it with an ingress object.

If those are not the proper repos, or if you know how to solve the "Can't verify CSRF token authenticity." issue, any pointers will be highly appreciated.

Regards

ddre54
replied 2 years ago

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

profile pictureAWS
MODERATOR
replied 2 years ago

Suggest to update the annotations with latest lb controller v2.6 https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.6/ sample annotations like:

    service.beta.kubernetes.io/aws-load-balancer-type: external
    service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
    service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
    service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "arn:aws:acm:{region}:{user id}:certificate/{id}"
    service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"
AWS
jjpe
replied a year ago

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

profile pictureAWS
MODERATOR
replied a year ago

Please update as the information on this page is out of date. Or at least attach relevant documentations where people can find the latest information

replied 8 months ago
apiVersion: v1
kind: Service
metadata:
  name: lb-service
  annotations:
    # Note that the backend talks over HTTP.
    service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http
    # TODO: Fill in with the ARN of your certificate.
    service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:us-east-1:905418170587:certificate/547f2290-974e-4c65-8859-4a5ef638ad80
    # Only run TLS on the port named "https" below.
    service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https"
    # By default In-tree controller will create a Classic LoadBalancer if you require a NLB uncomment below annotation.
    # service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
spec:
  selector:
    app: web
  ports:
  - name: http
    port: 80
    targetPort: 80
  - name: https
    port: 443
    targetPort: 80
  type: LoadBalancer
~
replied 8 months ago

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

profile pictureAWS
MODERATOR
replied 8 months ago