Azure Application Gateway and Traefik with AKS

While Traefik is sufficient on its own, Azure Application Gateway may already be present in your environment and has great Web Application Firewall capabilities. It could make sense to use both. Following up on my previous post, I’ll extend the Traefik implementation with an Azure Application Gateway in front.

First, we need to alter the Traefik helm deployment to use (and create) an Azure Internal Load Balancer and to expose a health endpoint. Assuming you have Traefik already deployed using helm, you need to add the following to the values file.

service:
  annotations:
    service.beta.kubernetes.io/azure-load-balancer-internal: "true"

additionalArguments:
  - "--ping"

On the Traefik helm deployment, the “service.spec.loadBalancerIP” value must be changed from the public IP to an unused IP from the AKS subnet. You can also remove the “service.annotations.service\.beta\.kubernetes\.io/azure-load-balancer-resource-group” value you probably used before.

Additionally, we need an IngressRoute to route traffic to the health endpoint. $DNS is your public domain name, for example eldar.cloud.

ping="apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: traefik-ping
  namespace: traefik
spec:
  entryPoints:
    - web
  routes:
    - match: Host(\`traefik.$DNS\`) && PathPrefix(\`/ping\`)
      kind: Rule
      services:
        - name: ping@internal
          kind: TraefikService"
echo "$ping" | kubectl apply -f -

Finally, we need to configure the Azure Application Gateway to route all requests to Traefik, and to probe our health endpoint. The following example shows the relevant configurations using Azure Bicep — it’s not a complete AppGW implementation. The variables are the same as previously, ${dns} being your public domain and traefikip being an unused IP in the AKS subnet.

var appgwid = resourceId('Microsoft.Network/applicationGateways', appgwname)

resource appgw 'Microsoft.Network/applicationGateways@2021-05-01' = {    
    probes: [ 
      {
        name: 'traefikHttpProbe'
        properties: {
          protocol: 'Http'
          path: '/ping'
          host: 'traefik.${dns}'
          interval: 30
          timeout: 30
          unhealthyThreshold: 3
          pickHostNameFromBackendHttpSettings: false
          minServers: 0
        }
      }
    ]
    backendAddressPools: [
      {
        name: 'traefik'
        properties: {
          backendAddresses: [
            {
              ipAddress: traefikip
            }
          ]
        }
      }
    ]
    backendHttpSettingsCollection: [
      {
        name: 'traefikHttpSetting'
        properties: {
          port: 80
          protocol: 'Http'
          probe: {
            id: '${appgwid}/probes/traefikHttpProbe'
          }
        }
      }
    ]
    httpListeners: [
      {
        name: 'traefik_80'
        properties: {
          frontendIPConfiguration: {
            id: '${appgwid}/frontendIPConfigurations/appGwPublicFrontendIp'
          }
          protocol: 'Http'
          frontendPort: {
            id: '${appgwid}/frontendPorts/port_80'
          }
          hostNames: [
            '*.${dns}'
          ] 
        }
      }
    ]
    requestRoutingRules: [
      {
        name: 'traefik_http'
        properties: {
          ruleType: 'Basic'
          httpListener: {
            id: '${appgwid}/httpListeners/traefik_80'
          }
          backendAddressPool: {
            id : '${appgwid}/backendAddressPools/traefik'
          }
          backendHttpSettings: {
            id: '${appgwid}/backendHttpSettingsCollection/traefikHttpSetting'
          }
        }
      }
    ]
}

One Reply to “Azure Application Gateway and Traefik with AKS”

Leave a Reply

Your email address will not be published.