Skip to content

AWS ALB Ingress Controller - Implement HTTP to HTTPS Redirect

  • Redirect from HTTP to HTTPS
  • Provides a method for configuring custom actions on a listener, such as for Redirect Actions.
  • The action-name in the annotation must match the serviceName in the ingress rules, and servicePort must be use-annotation.
  • Reference for Custom Actions: https://kubernetes-sigs.github.io/aws-alb-ingress-controller/guide/ingress/annotation/#actions

Image

Kubernetes Manifests

#01-MySQL-externalName-Service.yml
apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  type: ExternalName
  externalName: usermgmtdb.cxojydmxwly6.us-east-1.rds.amazonaws.com
#02-UserManagementMicroservice-Deployment-Service.yml
apiVersion: apps/v1
kind: Deployment 
metadata:
  name: usermgmt-microservice
  labels:
    app: usermgmt-restapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: usermgmt-restapp
  template:  
    metadata:
      labels: 
        app: usermgmt-restapp
    spec:
      initContainers:
        - name: init-db
          image: busybox:1.31
          command: ['sh', '-c', 'echo -e "Checking for the availability of MySQL Server deployment"; while ! nc -z mysql 3306; do sleep 1; printf "-"; done; echo -e "  >> MySQL DB Server has started";']      
      containers:
        - name: usermgmt-restapp
          image: stacksimplify/kube-usermanagement-microservice:1.0.0  
          ports: 
            - containerPort: 8095           
          env:
            - name: DB_HOSTNAME
              value: "mysql"            
            - name: DB_PORT
              value: "3306"            
            - name: DB_NAME
              value: "usermgmt"            
            - name: DB_USERNAME
              value: "dbadmin"        # RDS DB Username is dbadmin     
            - name: DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-db-password
                  key: db-password           
          livenessProbe:
            exec:
              command: 
                - /bin/sh
                - -c 
                - nc -z localhost 8095
            initialDelaySeconds: 60
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /usermgmt/health-status
              port: 8095
            initialDelaySeconds: 60
            periodSeconds: 10          
#03-Kubernetes-Secrets.yml
apiVersion: v1
kind: Secret
metadata:
  name: mysql-db-password
type: Opaque
data: 
  db-password: ZGJwYXNzd29yZDEx
#04-UserManagement-NodePort-Service.yml
apiVersion: v1
kind: Service
metadata:
  name: usermgmt-restapp-nodeport-service
  labels:
    app: usermgmt-restapp
  annotations:
#Important Note:  Need to add health check path annotations in service level if we are planning to use multiple targets in a load balancer  
    alb.ingress.kubernetes.io/healthcheck-path: /usermgmt/health-status    
spec:
  type: NodePort
  selector:
    app: usermgmt-restapp
  ports:
    - port: 8095
      targetPort: 8095
#05-Nginx-App1-Deployment-and-NodePortService.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app1-nginx-deployment
  labels:
    app: app1-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app1-nginx
  template:
    metadata:
      labels:
        app: app1-nginx
    spec:
      containers:
        - name: app1-nginx
          image: stacksimplify/kube-nginxapp1:1.0.0
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: app1-nginx-nodeport-service
  labels:
    app: app1-nginx
  annotations:
#Important Note:  Need to add health check path annotations in service level if we are planning to use multiple targets in a load balancer    
    alb.ingress.kubernetes.io/healthcheck-path: /app1/index.html
spec:
  type: NodePort
  selector:
    app: app1-nginx
  ports:
    - port: 80
      targetPort: 80
#06-Nginx-App2-Deployment-and-NodePortService.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app2-nginx-deployment
  labels:
    app: app2-nginx 
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app2-nginx
  template:
    metadata:
      labels:
        app: app2-nginx
    spec:
      containers:
        - name: app2-nginx
          image: stacksimplify/kube-nginxapp2:1.0.0
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: app2-nginx-nodeport-service
  labels:
    app: app2-nginx
  annotations:
#Important Note:  Need to add health check path annotations in service level if we are planning to use multiple targets in a load balancer
    alb.ingress.kubernetes.io/healthcheck-path: /app2/index.html
spec:
  type: NodePort
  selector:
    app: app2-nginx
  ports:
    - port: 80
      targetPort: 80
#07-ALB-Ingress-SSL-Redirect.yml
# Annotations Reference:  https://kubernetes-sigs.github.io/aws-alb-ingress-controller/guide/ingress/annotation/
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-usermgmt-restapp-service
  labels:
    app: usermgmt-restapp
  annotations:
    # Ingress Core Settings  
    kubernetes.io/ingress.class: "alb"
    alb.ingress.kubernetes.io/scheme: internet-facing
    # Health Check Settings
    alb.ingress.kubernetes.io/healthcheck-protocol: HTTP 
    alb.ingress.kubernetes.io/healthcheck-port: traffic-port
    #Important Note:  Need to add health check path annotations in service level if we are planning to use multiple targets in a load balancer    
    #alb.ingress.kubernetes.io/healthcheck-path: /usermgmt/health-status
    alb.ingress.kubernetes.io/healthcheck-interval-seconds: '15'
    alb.ingress.kubernetes.io/healthcheck-timeout-seconds: '5'
    alb.ingress.kubernetes.io/success-codes: '200'
    alb.ingress.kubernetes.io/healthy-threshold-count: '2'
    alb.ingress.kubernetes.io/unhealthy-threshold-count: '2'
    ## SSL Settings
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-east-1:180789647333:certificate/9f042b5d-86fd-4fad-96d0-c81c5abc71e1
    #alb.ingress.kubernetes.io/ssl-policy: ELBSecurityPolicy-TLS-1-1-2017-01 #Optional (Picks default if not used)    
    # SSL Redirect Setting
    alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'   
spec:
  rules:
    #- host: ssldemo.kubeoncloud.com    # SSL Setting (Optional only if we are not using certificate-arn annotation)
    - http:
        paths:
          - path: /* # SSL Redirect Setting
            backend:
              serviceName: ssl-redirect
              servicePort: use-annotation            
          - path: /app1/*
            backend:
              serviceName: app1-nginx-nodeport-service
              servicePort: 80                        
          - path: /app2/*
            backend:
              serviceName: app2-nginx-nodeport-service
              servicePort: 80            
          - path: /*
            backend:
              serviceName: usermgmt-restapp-nodeport-service
              servicePort: 8095              
# Important Note-1: In path based routing order is very important, if we are going to use  "/*", try to use it at the end of all rules.         

Change-1: Add the Custom Action Annotation

     # SSL Redirect Setting
    alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'   
- SSL Redirect JSON
{
   "Type":"redirect",
   "RedirectConfig":{
      "Protocol":"HTTPS",
      "Port":"443",
      "StatusCode":"HTTP_301"
   }

Change-2: Add the following Path as first ingress rule in the Rules section

          - path: /* # SSL Redirect Setting
            backend:
              serviceName: ssl-redirect
              servicePort: use-annotation     

Step-02: Deploy all manifests and test

  • Deploy
    # Deploy
    kubectl apply -f kube-manifests/
    
  • Verify
    • Load Balancer - Listeneres (Verify both 80 & 443)
    • Load Balancer - Rules (Verify both 80 & 443 listeners)
    • Target Groups - Group Details (Verify Health check path)
    • Target Groups - Targets (Verify all 3 targets are healthy)
    • Verify ingress controller from kubectl
      kubectl get ingress 
      

Step-04: Access Application using newly registered DNS Name

  • Access Application
    # HTTP URLs (Should Redirect to HTTPS)
    http://ssldemo.kubeoncloud.com/app1/index.html
    http://ssldemo.kubeoncloud.com/app2/index.html
    http://ssldemo.kubeoncloud.com/usermgmt/health-status
    
    # HTTPS URLs
    https://ssldemo.kubeoncloud.com/app1/index.html
    https://ssldemo.kubeoncloud.com/app2/index.html
    https://ssldemo.kubeoncloud.com/usermgmt/health-status
    

AWS EKS - Elastic Kubernetes Service - Masterclass

Image

Step-05: Clean Up

Delete Manifests

kubectl delete -f kube-manifests/

Delete Route53 Record Set

  • Delete Route53 Record we created (ssldemo.kubeoncloud.com)

Step-06: Annotation Reference

  • Discuss about location where that Annotation can be placed (Ingress or Service)
  • https://kubernetes-sigs.github.io/aws-alb-ingress-controller/guide/ingress/annotation/