AWS ALB-Ingress-Controller Guide

Image for post

Hey everyone! It’s me again, always finding ways to save money and time and this time it is the latter!

This is a guide to provision an AWS ALB Ingress Controller on your EKS cluster with steps to configure HTTP > HTTPS redirection.

After collecting a huge amount of solutions and dealing with many tickets, I’ve decided to build this guide to help you provision this wonderful ALB, clarify the AWS official documentation and automate 99% of everything.

You may change anything you want according to your needs but it is important to follow the roles and policies a 100%. Just make sure that if you do change the namespace for example, change it in every single file or you will get a huge “OOPS!” and even a larger headache.

Make sure the following tags are correct on your EKS subnets

  • All subnets in your VPC should be tagged accordingly so that Kubernetes can discover them:

Key: kubernetes.io/cluster/<cluster-name> Value: shared

  • Public subnets in your VPC should be tagged accordingly so that Kubernetes knows to use only those subnets for external load balancers:

Key: kubernetes.io/role/elb Value: 1

  • Private subnets must be tagged in the following way so that Kubernetes knows it can use the subnets for internal load balancers:

Key: kubernetes.io/role/internal-elb Value: 1

Install eksctl

https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.html

Create IAM OIDC provider (can create manually in IAM > Identity Providers

eksctl utils associate-iam-oidc-provider \
    --region <region> \
    --cluster <eks cluster name> \
    --approve

Create an IAM policy called ALBIngressControllerIAMPolicy and attach the iam-policy.yaml

curl -o iam-policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.8/docs/examples/iam-policy.jsonaws iam create-policy \
    --policy-name ALBIngressControllerIAMPolicy \
    --policy-document file://iam-policy.json

Create a Kubernetes service account named alb-ingress-controller in the kube-system namespace, a cluster role, and a cluster role binding for the ALB Ingress Controller to use with the following command

curl -o rbac-role-alb-ingress-controller.yaml https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.8/docs/examples/rbac-role.yamlkubectl apply -f rbac-role-alb-ingress-controller.yaml

Create role, add trust relationship and annotate

A. Create a document trust.json and add:

  • Replace Federated with the OIDC ARN and StringEquals with OIDC URL Those can be found in IAM > Identity Provider
{
   "Version":"2012-10-17",
   "Statement":[
      {
         "Effect":"Allow",
         "Principal":{
            "Federated":"arn:aws:iam::<AWS account ID>:oidc-provider/<OIDC url>"
         },
         "Action":"sts:AssumeRoleWithWebIdentity",
         "Condition":{
            "StringEquals":{
               "<OIDC url>:sub":"system:serviceaccount:kube-system:alb-ingress-controller"
            }
         }
      }
   ]
}

B. Create IAM role and attach the trust relationship:

aws iam create-role --role-name eks-alb-ingress-controller --assume-role-policy-document file://trust.json

C. Attach the ALBIngressControllerIAMPolicy to the alb role

aws iam attach-role-policy --role-name eks-alb-ingress-controller --policy-arn=<ARN of the created policy>

D. Annotate the controller pod to use the role:

kubectl annotate serviceaccount -n kube-system alb-ingress-controller \
eks.amazonaws.com/role-arn=arn:aws:iam::535518648590:role/eks-alb-ingress-controller

E. Add the following policies to the alb role:

aws iam attach-role-policy --role-name eks-alb-ingress-controller --policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicyaws iam attach-role-policy --role-name eks-alb-ingress-controller --policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy

Deploy alb-ingress-controller

A. Download the alb controller yaml locally

curl -o alb-ingress-controller.yaml https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.8/docs/examples/alb-ingress-controller.yaml https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.8/docs/examples/alb-ingress-controller.yaml

Edit alb-ingress-controller and add values

A. Edit the alb-ingress-controller.yaml and add the following if not in:

spec:
  containers:
  - args:
    - --ingress-class=alb
    - --cluster-name=<name of eks cluster>

B. If you are using Fargate:

spec:
  containers:
  - args:
    - --ingress-class=alb
    - --cluster-name=<name of eks cluster>
    - --aws-vpc-id=<vpcID>
    - --aws-region=<region-code>

D. Apply the yaml:

kubectl apply -f alb-ingress-controller.yaml

Check that the ALB is up

kubectl get pods -n kube-system

Image for post

Deploy sample app with ingress

A. To use the public files:

kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.8/docs/examples/2048/2048-namespace.yamlkubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.8/docs/examples/2048/2048-deployment.yamlkubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.8/docs/examples/2048/2048-service.yamlkubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.8/docs/examples/2048/2048-ingress.yaml
  • This will deploy an ingress object that will be picked up by the alb-ingress-controller and an ALB will be deployed

B. Store the files locally for customisation: (recommended)

curl -o <fileName.yaml> <URL from the previous steps>kubectl apply -f <fileName>.yaml

Verify ingress

kubectl get ingress/2048-ingress -n 2048-game

Image for post

Troubleshoot alb-ingress-controller

Check Logs:

kubectl logs -n kube-system deployment.apps/alb-ingress-controller

Check the app

Open a browser and navigate to the ADDRESS URL from the previous command output to see the sample application.

  • If there is no address, check the logs of the controller with the command above and troubleshoot (should not happen)

HTTP to HTTPS Redirect

A. Add the following annotations to your ingress object and insert the arn of your certificate from AWS ACM:

alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig":
{ "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
alb.ingress.kubernetes.io/certificate-arn: <certificate arn from ACM>
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'

B. Add the following spec:

  • Replace your serviceName and Port accordingly:
spec:
  rules:
    - http:
        paths:
          - path: /*
            backend:
              serviceName: ssl-redirect
              servicePort: use-annotation
          - path: /*
            backend:
              serviceName: <"serviceName">
              servicePort: <servicePort>
  • Best way is to recreate the ingress

Check the redirection

Open a browser and navigate to the ADDRESS URL of the Load Balancer

Good Luck!
Contact me for more questions 🙂
evgenibi@cloudzone.io