---
# System prepended metadata

title: Traefik with Amazon ALB

---

# Traefik with Amazon ALB

###### tags: traefik.2.x 

The default k8s controller for AWS only provisions CLB or NLB. For deploying an ALB for web applications and securing them with WAF capabilites. We will need to use the latest the AWS controller.

The recommended approach would be to leave the platform ingress controller and create a secondary ingress controller for web-traffic. DKP creates roles for the k8s nodes to create aws resources. we are going to modify that role to ensure our nodes have privileges to create ALB resources. 

Once we have controller up we will deploy Traefik with NodePort and all the necessary configurations listed below 


## :memo: What do we need before get started ?

### Step 0: Prerequisites

- [ ] A DKP 2.x cluster in AWS 
- [ ] Helm 3.x client installed 
- [ ] Kubernetes Admin prvileges to the cluster

:rocket: 

### Step 1: Add the IAM policy needed for ALB 

By default DKP create a security group which is used by the nodes to deploy the load balancer. Let add a policy to the same role to ensure the nodes can now also provision ALB resources along with CLB. 

Here's the policy 
```bash=
{
    "Statement": [
        {
            "Action": [
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeInstances",
                "elasticloadbalancing:DescribeTargetGroups",
                "elasticloadbalancing:DescribeTargetHealth",
                "elasticloadbalancing:ModifyTargetGroup",
                "elasticloadbalancing:ModifyTargetGroupAttributes",
                "elasticloadbalancing:RegisterTargets",
                "elasticloadbalancing:DeregisterTargets"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ],
    "Version": "2012-10-17"
}
```

:::info
:bulb: **Hint:** You can create your own automations for this if you like and added new roles to all the instances as well if you like
:::



### Step 2: Install the controller

a. Add helm chart
```bash=
helm repo add eks https://aws.github.io/eks-charts
```
b. Install the CRD's required
```bash=
kubectl apply -k "github.com/aws/eks-charts/stable/aws-load-balancer-controller//crds?ref=master"
```
c. Install the contorller using the chart 
```bash=
helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=<cluster-name>
```

### Step 3: Create namespace for the Ingress controller.
Ingress controllers are cluster level objects so when you create it in a specific namespace all the other namespaces should be able to leverage it. Keeping it in a seperate namespace would just improve your security posture. You can also use an existing suitable namespace

```bash=
kubectl create namespace <your-namespace>
```
Once the namespace is created let's switch your context to our namespace. If you are using an exiting namespace you can skip the previous step and just run this command. 

```bash=2
kubectl config set-context --current --namespace=<your-namespace>
```


For all those cool kids using [kubectx](https://github.com/ahmetb/kubectx)
then you can instead use this command
```bash=2
kubens <your-namespace>
```
This prepares us for depoying traefik.


### Step 4 : Configure helm repo
Add Traefik's helm chart repository to your local environment
```bash=1
helm repo add traefik https://helm.traefik.io/traefik
```
Update the repo to ensure you have the lastest artifacts 
```bash=2
helm repo update
```
You can install the traefik using helm install command now. However we would do not want to use the default helm chart. Let's create a values files in which we can define overides for defaults. Use the below


Note: this is partial values file not the entirity. If can downloaded the complete values file from offical if you like from [here](https://github.com/traefik/traefik-helm-chart/blob/master/traefik/values.yaml)
```bash
cat << 'EOF' > custom-values.yaml

# This is just the service section of the default values.yaml file


# The AWS controller needs the service to be node-port so let's change the default
service:
  enabled: true
  type: NodePort


# We Enable the ingress class which defaults to false
# Use ingressClass. Ignored if Traefik version < 2.3 / kubernetes < 1.18.x
ingressClass:
  # true is not unit-testable yet, pending https://github.com/rancher/helm-unittest/pull/12
  enabled: true
  isDefaultClass: false


# Create an IngressRoute for the dashboard
ingressRoute:
  dashboard:
    enabled: true
    # Additional ingressRoute annotations (e.g. for kubernetes.io/ingress.class)
    annotations: 
      kubernetes.io/ingress.class: alb
      alb.ingress.kubernetes.io/scheme: internet-facing
      alb.ingress.kubernetes.io/target-type: ip
    #  alb.ingress.kubernetes.io/shield-advanced-protection: true
    #  alb.ingress.kubernetes.io/waf-acl-id: <>
      
    # Additional ingressRoute labels (e.g. for filtering IngressRoute by custom labels)
    labels: {}

rollingUpdate:
  maxUnavailable: 1
  maxSurge: 1

EOF
```
Please find the detailed list of all the annotations required [here](https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.3/guide/ingress/annotations/) 


This should bring up ALB instead of classic load balancer when you deploy traefik. You can also adjust the annotations above to get a SHIELD and WAF enabled. 

