AWS ALB with NGINX INGRESS CONTROLLER
Tags: aws, kubernetes, devops, cloud
Published: 2023-05-01 08:17:50

So if you are wondering how to integrate the AWS application load balancer with Nginx/Istio to get the traffic into the cluster so this is it.

You might ask why this article so let me tell you what I'm looking for when I say aws alb/nlb and ingress controller.

![Diagram showing 1 LB and and EKS Cluster](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7p92byyrx5w68119ula3.png)
I know there are bunch of components missing but you got the idea right!! only 1 ALB/NLB unless u have some other use case where you need bunch of LB

**LB: LoadBalancer; A: Application; N: Network**
just to avoid any confusions.

Before moving forward let's discuss why this setup

## Before

If you know Kubernetes(K8s) you know they support 3 type of networking, build natively we called them **service**
> ClusterIP
> NodePort
> LoadBalancer

you can read more about them from K8s official docs
We are not interested in above 2 only LoadBalancer so what it does is that when you are using cloud services in our case **EKS** we can directly provision a loadbalancer for our services to ingress the traffic.
But the problem with this is how many LB we can create until we ran out of money coz we use many services and according to this there's going to be a lot of LB.

So you get the problem right we can't create LB everytime we need to let the traffic inside, so the great guys at K8s decided we need something and they came up with **INGRESS** the whole idea was to save cost and reduce management this is what I think 😁 coz it sure does for me!

## AFTER

Moving on we can create the setup which showed in the starting only 1 LB is sufficient for K8s cluster we don't need to create different LB for different Services.

## PROCESS
There are 4 stage in this from creating the cluster to deploying the application and then opening it in browser.

### STAGE I

Spin Up the EKS cluster, you can do it from the aws console, cli. I love cli and there's a best tool to do this **[eksctl](https://eksctl.io/)** 
Setup this tool you need aws cli configure plus you must have the permissions.

`eksctl create cluster -f cluster.yaml`
```
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
  name: DevOps-Prod
  region: ap-south-1
  version: "1.26"
managedNodeGroups:
  - name: ng-1
    instanceType: m5.large
    desiredCapacity: 2
    volumeSize: 80
    labels: { role: workers }
```
Give it 15mins or so it will complete the creation and the cluster will be up then


### STAGE II

Now we'll install something called AWS LoadBalancer Controller.
I'm not going into details coz AWS blogs are great you just need to follow them here's the **[link](https://docs.aws.amazon.com/eks/latest/userguide/aws-load-balancer-controller.html)**
**TIP: I prefer the eksctl**


### STAGE III

Make sure the pods are running by running the command 
`kubectl get po -n kube-system`
If your namespace is kube-system

Now we need to install the Nginx Ingress Controller again not going into deep here's the **[link](https://docs.nginx.com/nginx-ingress-controller/installation/installation-with-manifests/)**

So we need to do some changes over here to achieve our noble goal of having 1 LB
**TIP: Install it with Helm**
make sure you change the service type of chart from **LoadBalancer to  NodePort**.
You find it in the values.yaml or if you're using manifest file the look for the service block just make sure you do this.

**NOTICE: It's important that you do this otherwise it won't work**

Now after successfully deploying this you need to check which NodePort is being utilized it's mostly in above **3000** make sure you wrote it down somewhere.
And check the `readiness-probe` for the deployment of nginx controller 
```
readinessProbe:
failureThreshold: 30
httpGet:
path: /healthz
```
something like this check it for yourself and now we are going to last phase.

### STAGE IV

After everything is deployed and you have the NodePort and Path of the health-check you going to apply the below file.

You also need the certificate imported in a service called ACM 
Amazon Certificate Manager from which you will get the arn of that certificate which you need to update in the file

```
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: alb-ingress-connect-nginx
  namespace: kube-system
  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: 30000 # Make sure you add the NodePort over here
    alb.ingress.kubernetes.io/healthcheck-path: /healthz # Put the path of readiness probe over here
    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:eu-west-2:122221113322:certificate/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx # make sure you update your certificate arn over here
    #alb.ingress.kubernetes.io/ssl-policy: ELBSecurityPolicy-TLS-1-1-2017-01 #Optional (Picks default if not used)
    # redirect all HTTP to HTTPS
    alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
spec:
  rules:
  - http:
      paths:
        - path: /*
          pathType: ImplementationSpecific
          backend:
            service:
              name: ssl-redirect
              port:
                name: use-annotation
        - path: /*
          pathType: ImplementationSpecific
          backend:
            service:
              name: ingress-nginx-controller # Make sure you name the service correctly by checking the name of it nginx ingress controller service nothing else
              port:
                number: 80

```
If you open the above file in vscode or text-editor you'll find the comment that I wrote for you guys where you need to supply the NodePort and Health-check path and name of the service of ingress controller, arn of the certificate after doing all the changes apply with following

`kubectl apply -f ingress.yaml`

After running this command you'll see that there's a ALB is provisioning and target group is created to check the instance health check once it's checked and alb is fully provisioned you can hit the url of the alb see the **404 NOT FOUND from nginx**
and this confirm that response is coming from nginx.

### ENDING

You can deploy the application and expose the service with ingress and try to hit the url mentioned in the ingress file before this you need to update the records too if using ROUTE53 or any other domain registrar and that's it

## CONCLUSION
I hope this works for you if not plz reach out to me I'm happy to help make sure the to update the values which I commented and it will work for you.