Kubernetes: Host Rule order

(Hakan Lindestaf) #1

When using ssl-redirect with AWS ALB as ingress controller the order of the Ingress Host Rules is important, the ssl-redirect has to be on top at all times to do the HTTP to HTTPS redirect. Right now there doesn’t seem to be a way to change the order of these in a step.
Also I noticed that the standalone Ingress step allows me to specify a service name for the ingress, but the ingress settings on a regular Kubernetes deploy step auto-populates the service name (so I can’t use the ssl-redirect feature when configuring ingress on this type of step).

(Matthew Casperson) #3

Hi Hakan,

The UI doesn’t expose an easy way to place Ingress rules in a particular order, so for this use case where a rule must be at the top, your best bet is to use the Run a kubectl CLI Script step. The usual process here would be a script like:

Set-Content -Path ingress.yaml -Value @"
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  namespace: default
  name: ingress
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-west-2:xxxx:certificate/xxxxxx
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
    alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
spec:
  rules:
    - http:
        paths:
         - path: /*
           backend:
             serviceName: ssl-redirect
             servicePort: use-annotation
         - path: /users/*
           backend:
             serviceName: user-service
             servicePort: 80
         - path: /*
           backend:
             serviceName: default-service
             servicePort: 80
"@
kubectl apply -f ingress.yaml

The ability to generate an ingress alongside a deployment resource is a convenience (by making assumptions about the service names), but all of the functionality can be replicated with a custom script step. You may use variables for service names in the script above to ensure the service created alongside the deployment is the same one referenced in the raw yaml e.g.

Set-Content -Path ingress.yaml -Value @"
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  namespace: default
  name: ingress
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-west-2:xxxx:certificate/xxxxxx
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
    alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
spec:
  rules:
    - http:
        paths:
         - path: /*
           backend:
             serviceName: ssl-redirect
             servicePort: use-annotation
         - path: /users/*
           backend:
             serviceName: "#{ServiceName}"
             servicePort: 80
         - path: /*
           backend:
             serviceName: default-service
             servicePort: 80
"@
kubectl apply -f ingress.yaml

Having said that I’ll bring this issue up with the team and discuss the ability to properly order rules via the UI to make this easier.

Regards
Matt C

(Hakan Lindestaf) #4

Thanks Matt. Yea, I realize it can be done with a script, but one of the advantages of using Octopus Deploy is that I don’t have to script everything, that there is a nice UI to set up new ports, etc. So I try to stay away from custom scripts/steps as much as possible.

(Matthew Casperson) #5

Hi Hakan, we’ve added am item to the backlog to allow host rules to be reordered. Unfortunately I couldn’t give you a timeframe for this to be implemented, so using a script will be the best workaround in the meantime. But your feedback has been very valuable.

Regards
Matt C

1 Like