ArgoCD redirect loop when using a Ingress objects with HTTPS offloading

argocd kubernetes ci/cd AWS ALB Ingress

3 min read | by Jordi Prats

When enabling an Ingress for ArgoCD we might end up with a redirect loop: ArgoCD keeps redirecting to the main page using https, even tough it is already using https:

$ curl -I https://argocd.pet2cattle.com/

HTTP/2 307 
date: Wed, 23 Mar 2022 22:38:31 GMT
content-type: text/html; charset=utf-8
location: https://argocd.pet2cattle.com/

This issue happens because, by default, ArgoCD expects to handle the TLS termination by itself, always redirecting HTTP requests to HTTPS. If we try to offload the TLS termination to the ingress controller, from ArgoCD's perspective the connection is HTTP, so it keeps redirecting to HTTPS

This would be the helm values for configuring an Ingress that uses the ALB ingress controller, causing this redirect loop:

server:
  ingress:
    enabled: true

    annotations:
      kubernetes.io/ingress.class: alb
      alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
      alb.ingress.kubernetes.io/scheme: internal
      alb.ingress.kubernetes.io/target-type: ip
      alb.ingress.kubernetes.io/group.name: argocd
      alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80},{"HTTPS":443}]'

    hosts:
    - "argocd.pet2cattle.com"

We have two options:

  • Configure ArgoCD to ignore the HTTP to HTTPS redirect: The TLS connection will terminate at the ALB, using behind the scenes an HTTP connection between the ALB and the ** Pod**
  • Set an annotation to use HTTPS between the ALB and ArgoCD's Pod: This way the TLS connection would terminate in the ALB anyway, but a new TLS connection would be established to reach the actual Pod. This way ArgoCD won't try to redirect you to use HTTPS

For the fist option, disable the HTTPS redirect, we will have to add the --insecure flag to server.extraArgs:

server:
  extraArgs:
   - --insecure

On the other hand, to enable to use HTTPS behind the scenes (aka between the ALB and ArgoCD), we will have to tell we will need to set server.ingress.https to true and then add the alb.ingress.kubernetes.io/backend-protocol annotation to tell the ALB to use https instead of http. On the helm values it would look like this:

server:
  ingress:
    enabled: true
    https: true

    annotations:
      kubernetes.io/ingress.class: alb
      alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
      alb.ingress.kubernetes.io/scheme: internal
      alb.ingress.kubernetes.io/target-type: ip
      alb.ingress.kubernetes.io/group.name: argocd
      alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80},{"HTTPS":443}]'
      alb.ingress.kubernetes.io/backend-protocol: HTTPS

    hosts:
    - "argocd.pet2cattle.com"

Either way, once these changes are applied, we will be able to access ArgoCD:

$ curl -I https://argocd.pet2cattle.com/
HTTP/2 200 
date: Wed, 23 Mar 2022 22:49:37 GMT
content-type: text/html; charset=utf-8
content-length: 843
accept-ranges: bytes
x-frame-options: sameorigin
x-xss-protection: 1

Posted on 24/03/2022