<p>I'm working on an application that deploys kubernetes resources dynamically, and I'd like to be able to provision a shared SSL certificate for all of them. At any given time, all of the services have the path <code>*.*.*.example.com</code>. </p>

<p>I've heard that cert-manager will provision/re-provision certs automatically, but I don't necessarily need auto-provisioning if its too much overhead. The solution also needs to be able to handle these nested url subdomains.</p>

<p>Any thoughts on the easiest way to do this? </p>

<p>Have a look at <a href="https://kubernetes.github.io/ingress-nginx/" rel="noreferrer">nginx-ingress</a>, which is a Kubernetes Ingress Controller that essentially makes it possible to run <a href="https://www.nginx.com/" rel="noreferrer">Nginx</a> reverse proxy/web server/load balancer on Kubernetes.</p>

<p>nginx-ingress is built around the <a href="https://kubernetes.io/docs/concepts/services-networking/ingress/" rel="noreferrer">Ingress</a> resource. It will watch Ingress objects and manage nginx configuration in config maps. You can define powerful traffic routing rules, caching, url rewriting, and a lot more via the Kubernetes Ingress resource rules and <a href="https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/" rel="noreferrer">nginx specific annotations</a>.</p>

<p>Here's an example of an Ingress with some routing. There's a lot more you can do with this, <a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#ingressrule-v1beta1-extensions" rel="noreferrer">and it does support wildcard domain routing</a>.</p>

<pre class="lang-yaml prettyprint-override"><code>apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /$1
    cert-manager.io/cluster-issuer: letsencrypt-prod
  name: my-ingress
spec:
  rules:
  - host: app1.domain.com
    http:
      paths:
      - backend:
          serviceName: app1-service
          servicePort: http
        path: /(.*)

  - host: app2.sub.domain.com
    http:
      paths:
      - backend:
          serviceName: app2-service
          servicePort: http
        path: /(.*)
  tls:
  - hosts:
    - app1.domain.com
    secretName: app1.domain.com-tls-secret
  - hosts:
    - app2.sub.domain.com
    secretName: app2.sub.domain.com-tls-secret
</code></pre>

<p>The annotations section is really important. Above indicates that nginx-ingress should manage this Ingress definition. This annotations section allows to specify additional nginx configuration, in the above example it specifies a url rewrite target that can be used to rewrite urls in the rule section.</p>

<p>See <a href="https://cloud.google.com/community/tutorials/nginx-ingress-gke" rel="noreferrer">this community post</a> for installing nginx-ingress on GKE.</p>

<p>You'll notice the annotations also have a cert manager specific annotation which, if installed will instruct cert manager to issue certificates based on the hosts and secrets defined under the <code>tls</code> section.</p>

<p>Using <a href="https://cert-manager.io/docs/concepts/" rel="noreferrer">cert-manager</a> in combination with nginx-ingress, which isn't that complicated, you can set up automatic certificate creation/renewals.</p>

<p>It's hard to know the exact nature of your setup with deploying dynamic applications. But some possible ways to achieve the configuration are:</p>

<ul>
<li>Have each app define it's own Ingress with it's own routing rules and TLS configuration, which gets installed/updated each time your the application is deployed</li>
<li>Have an Ingress per domain/subdomain. You could then specify a wild card subdomain and tls section with routing rules for that subdomain</li>
<li>Or possibly you could have one uber Ingress which handles all domains and routing.</li>
</ul>

<p>The more fine grained the more control, but a lot more moving parts. I don't see this as a problem. For the last two options, it really depends on the nature of your dynamic application deployments.</p>
