application-gateway-kubernetes-ingress icon indicating copy to clipboard operation
application-gateway-kubernetes-ingress copied to clipboard

What's a proper way to manage ssl certificates in app gw?

Open rlevchenko opened this issue 2 years ago • 8 comments

Describe the bug

I'm trying to update a ssl certificate by using this:

az network application-gateway ssl-cert update `
  --resource-group <rg name> `
  --gateway-name <gw name> `
  -n <name here> `
  --cert-file <path to pfx file> `
  --cert-password <password here>

and getting the following error:

Two Http Listeners of Application Gateway are using the same Frontend Port

  • IDs of those two listeners belong to HTTP listeners (used for SSL Redirection actually)
  • HTTP and HTTPS listeners are all managed by ingress.
  • All listeners are using a private frontend ip,
  • Public frontend ip is enabled, no listeners associated to this ip
  • All listeners use the app gw certificate (not a cert in k8s or somewhere else).

Possible workarounds:

  • delete applications, update the cert, do a new release
  • /upload a cert with a new name, update helm templates, do a new release/ just tried and no luck :)

What's the best solution in this case? Can we just update an existing certificate without extra actions?

Ingress Controller details

Ingress 1.4.0 Application Gateway in a private mode k8s 1.19.11, private cluster

rlevchenko avatar Aug 05 '21 17:08 rlevchenko

I am unsure on what is best practice, however the way I do it is to create a TLS secret resource in the same namespace as the ingress. Here's what a sample YAML might look like:

Ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    kubernetes.io/ingress.class: azure/application-gateway
spec:
  tls:
  - hosts: 
    - website.com
    secretName: website-tls-secret
  rules:
  - host: website.com
    http:
      paths:
        - path: /
          pathType: Exact
          backend:
            service:
              name: website-service
              port:
                number: 80

Then you just create a TLS secret however you would like, making sure the name is the same as secretName and the namespace is the same as where your ingress is located. AGIC should automagically figure the rest out, though, YMMV.

I hope this helps :)

fatpowaranga avatar Aug 10 '21 08:08 fatpowaranga

@fatpowaranga thanks for the response. a bit out of topic though) I'm asking about SSL certs on appgw itself (in such cases, appgw.ingress.kubernetes.io/appgw-ssl-certificate annotation is used)

rlevchenko avatar Aug 10 '21 08:08 rlevchenko

@rlevchenko Ah, yes, sorry for misunderstanding. I couldn't get those working when I first started using AGIC and never re-tried.

fatpowaranga avatar Aug 12 '21 01:08 fatpowaranga

@rlevchenko I suspect that you are using an older version of Az CLI which is missing a new "Hostnames" property introduced in the HTTP listener of the gateway config. That is causing the property to not serialize and fail with a validation error.

akshaysngupta avatar Aug 12 '21 08:08 akshaysngupta

@rlevchenko I suspect that you are using an older version of Az CLI which is missing a new "Hostnames" property introduced in the HTTP listener of the gateway config. That is causing the property to not serialize and fail with a validation error.

Possibly. I don't have access to the env, so can't test right now. Will forward the suggestion to the team. Thanks.

rlevchenko avatar Aug 12 '21 09:08 rlevchenko

Resolved by upgrading the azure cli to the latest version. thanks @akshaysngupta

rlevchenko avatar Aug 12 '21 15:08 rlevchenko

after updating the cert, some of our listeners started to use the wrong cert. will check the ingress logs, keep this issue opened.

rlevchenko avatar Aug 15 '21 10:08 rlevchenko

I was doing some research on TLS termination using AGIC and came across this thread.

I'm not sure if this will solve your issue, but I think "ingress.yaml" posted by @fatpowaranga is valid, and it will mean that TLS is terminated by the application gateway, not by the AKS cluster.

To be specific, in the ingress yaml, I think both:

  annotations:
    ...
    appgw.ingress.kubernetes.io/appgw-ssl-certificate: mykvsslcert

and

spec:
  tls:
    - secretName: mykvsslcert

Mean that the application gateway is configured to do the TLS termination (it will then forward onto the cluster using standard HTTP). The difference is where the certificate is stored. In the former, I think it is stored on the AG (uploaded when you run the az network application-gateway ... command), and in the latter, it is stored as a kubernetes secret within the AKS cluster. (I ran some testing using self-signed certificates, and both yaml extracts above allowed for TLS termination and let me reach the pods in the cluster).

Please shout if you think I'm wrong!

semajson avatar Jan 15 '23 22:01 semajson