Bob’s Journey to Auto-Renewing TLS Certs in Kubernetes

Oops… Bob forgot to renew his TLS cert. Again. With support breathing down his neck, it’s time to automate certs like a grown-up. A few annotations, a helping hand from cert-manager, and Bob’s back in padlock paradise.

Bob’s Journey to Auto-Renewing TLS Certs in Kubernetes

Bob was halfway through his coffee when Josie appeared with that "you're gonna love this" look.

"Hey Bob, just a heads-up. Support's had a few tickets come in… looks like the SSL cert on one of your services expired."

Bob's eyes narrowed. "The cert? Oh, that cert!"

The one he manually crafted with openssl, base64'd into a kubernetes.io/tls secret, and swore he'd replace “properly” one day.

That day never came.

"Alright, I guess it’s time I figured out a better way to do this."

Bob wasn’t exactly new to deployments... he'd Helm'd his app, got it exposed via Traefik, and even added a proper domain. But keeping SSL certs alive? That had always been a background worry he’d filed under "future Bob's problem."

So, he did what any smart dev would do: he Slacked Alex.

Bob: Hey, quick one—how do I get HTTPS working properly without babysitting certs all the time?
Alex: Oh hey! That’s already sorted. You just need a few annotations and to set the ingress class to 'traefik'. We’ve got cert-manager wired up for auto certs.
Bob: Wait... that’s it?
Alex: Yeah, it's mostly taken care off, here's the annotations and ingressClassName settings you need to add to your ingress....
Alex: I'd also recommend changing the name of your cert so that cert-manager creates a new one before you clean up the old one

Alex sent over a YAML snippet like it was no big deal:

metadata:
  annotations:
    traefik.ingress.kubernetes.io/router.entrypoints: websecure
    traefik.ingress.kubernetes.io/router.tls: "true"
    cert-manager.io/cluster-issuer: letsencrypt-issuer
...
spec:
  ingressClassName: traefik
💡

If you're not familiar with creating ingresses, check out Bob's Journey to Secure Ingress where Bob learned to secure his ingress.

Making the Change

Bob pulled up his Ingress file. No Helm chart tweaks, no scripting, no cert renewal job this time, just a few lines of YAML magic.

  1. Add an ingressClassName for Traefik.
  2. Drop in a few annotations.
  3. Set up a TLS section.

Here’s what he added:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kelcode-ingress
  annotations:
    traefik.ingress.kubernetes.io/router.entrypoints: websecure
    traefik.ingress.kubernetes.io/router.tls: "true"
    cert-manager.io/cluster-issuer: letsencrypt-issuer
spec:
  ingressClassName: traefik
  rules:
  - host: my-todo-list.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-todo-svc
            port:
              name: http
  tls:
  - hosts:
      - my-todo-list.example.com
    secretName: todo-my-todo-list-tls

He saved, applied, and checked the cert status:

$ helm upgrade --namespace=mytodoapp my-todo . -f values.yaml
... 
$ kubectl get certificate
NAME                    READY   SECRET                  AGE
todo-my-todo-list-tls   False   todo-my-todo-list-tls   10s

Sure enough, a new certificate resource had been created. Logs showed cert-manager requesting and provisioning a cert from Let's Encrypt. Bob waited a few mins until the "Ready" status of the certificate was "True"

Bob hit refresh... the padlock was there... shining green like a tiny badge of honour.

Key takeaways:

  • Automate TLS in Kubernetes using Ingress annotations and `cert-manager`
  • Automation helps avoid downtime and keeps you secure
  • Focus on the minimal config: ingressClassName, issuer, and TLS block
  • Use `kubectl describe certificate` or logs for troubleshooting

Just Enough Infrastructure

The best part? Bob didn’t have to install cert-manager. He didn't configure TLS termination or open any ports. He didn’t debug HTTP-01 failures or worry about renewals. That was Alex's domain.

All Bob needed was three annotations and the right ingress class.

"I could get used to this DevOps thing" he muttered, admiring the little padlock in the address bar... "future Bob deserves better defaults".

That's it. cert-manager handles provisioning and renewal, and Traefik serves your app over HTTPS.

Bob's got his padlock.... have you got yours?