Create Automatic SSL and DNS from Cloudflare for Kubernetes Ingress Resources
Tags: kubernetes, ingress, ssl, cloudflare
Published: 2021-11-08 11:25:04

---
title: Create Automatic SSL and DNS from Cloudflare for Kubernetes Ingress Resources
published: true
date: 2021-08-26 00:00:00 UTC
tags: kubernetes, ingress, ssl, cloudflare
canonical_url: https://tech.serhatteker.com/post/2021-08/kubernetes-ingress-ssl-dns-cloudflare/
---


## 0. Entrée

There is an amazing post on software architecture named [The Architecture Behind A One-Person Tech Startup] which you should check it out. I'm almost using same tech architecture for my projects.

There is one thing however that I want to tweak:

Since Cloudflare proxying all external traffic to my Load Balancer(Ingress controlled Load Balancer) with default *browser* side SSL ceritificate;

![cloudflare-full-ssl](https://images.ctfassets.net/slt3lc6tev37/AVQoALCTVYbAL2sYeBfl6/01dd917f7e6c2b386f542dc936db99bd/hc-import-ssl_tls_flexible.png)

I only need **Origin Server** TLS certificate for a full SSL tunnel:

![cloudflare-full-ssl](https://images.ctfassets.net/slt3lc6tev37/1ZEJtXrDQElYtSt0ds4eHN/d42b6f5c6d62d66b4379d6a1c152a42e/hc-import-ssl_tls_full.png)

As Cloudflare mentioned in [End-to-end HTTPS with Cloudflare - Part 3: SSL options], you can provide your self-signed certificate for **Full** mode or you can provide a **Cloudflare Origin CA certificate** (or a valid certificate purchased from a [CA]) to enable **Full (strict)** mode:

![cloudflare-full-ssl](https://images.ctfassets.net/slt3lc6tev37/71zk4biNrzl8eSIwz12Ok9/ac3c63dcb55e4448dc047bca5d59ff63/hc-import-ssl_tls_full_strict.png)

So I don't need [Let's Encrypt] to grant me SSL certificate for my site. Yes, I am grateful for their free ACME certificates but in our case it's better to not load extra work to Lets' Encrypt while Cloudflare is also a [CA].

## 1. Origin CA

OK, We saw what we need but how we're going to issue and add an **Origin CA** ceritificate to our origin server?

The default way is like this: [Managing Cloudflare Origin CA certificates]. Although it's manual, rquires a lot effort and we need to regenerate and revoke our own certificates.  We don't like to use this way for our kubernetes clusters for sure.

### 1.0. origin-ca-issuer

The solution comes from Cloudflare team: [origin-ca-issuer].

**Origin CA Issuer** is a [cert-manager] CertificateRequest controller for Cloudflare’s Origin CA feature. It handles above mentioned default way by itself.


#### 1.1. Installing

Clone the github repo and apply manifests to install Origin CA Issuer to your cluster:

```bash
$ kubectl apply \
    -f deploy/crds \
    -f deploy/rbac \
    -f deploy/manifests
```

By default the Origin CA Issuer will be deployed in the `origin-ca-issuer` namespace.

#### 1.2. Adding an OriginIssuer

Get your **Origin CA Key** from *API Token* section of your Cloudflare dashboard and create a secret yaml for it:

```bash
$ kubectl create secret generic \
    origin-ca-key \
    -n default \
    --from-literal key=v1.0-FFFFFFF-FFFFFFFF \
    --dry-run=client \
    -o yaml > origin-ca-key.yaml
```

Change `default` namespace according to your need, then create `issuer.yaml` like below:

```yaml
# issuer.yaml
apiVersion: cert-manager.k8s.cloudflare.com/v1
kind: OriginIssuer
metadata:
  name: prod-issuer
  namespace: default
spec:
  requestType: OriginECC
  auth:
    serviceKeyRef:
      name: origin-ca-key
      key: key
```

Apply these manifests to your cluster:

```bash
$ kubectl apply \
    -f origin-ca-key.yaml \
    -f issuer.yaml
```

OriginIssuer resource will be updated once the Origin CA Issuer is ready.

After that create your Ingress resource like below:

```yaml
# example-ingress.yaml
apiVersion: networking/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    # ssl certificate
    cert-manager.io/issuer: prod-issuer
    cert-manager.io/issuer-kind: OriginIssuer
    cert-manager.io/issuer-group: cert-manager.k8s.cloudflare.com
    # dns record
    external-dns.alpha.kubernetes.io/hostname: example.com
    external-dns.alpha.kubernetes.io/cloudflare-proxied: "true"
  name: example-ingress
  namespace: default
spec:
  rules:
    - host: example.com
      http:
        paths:
         - pathType: Prefix
           path: /
           backend:
              service:
                name: example-svc
                port:
                  number: 80
  tls:
    # specifying a host in the TLS section will tell cert-manager what
    # DNS SANs should be on the created certificate.
    - hosts:
        - example.com
      # cert-manager will create this secret
      secretName: example-tls
```

Apply it as well:

```bash
$ kubectl apply -f example-ingress.yaml
```

Now you got:
- DNS record for example.com proxied by Cloudflare
- SSL certificate for your origin server signed by Cloudflare
- Full (strict) mode enabled
- *Orange Cloud* enabled

and you're ready to go.


All done!

---

P.S:

- I wish [origin-ca-issuer] had a `Helm Repo` so we can install it via `helm install`, and they had 
ClusterOriginIssuer` instead of namespace scoped `OriginIssuer`. Fortunately there are related issues on the repo and they are already working on them.
- How much I tried I couldn't make [origin-ca-issuer] work by `ingress-traefik`. If someone achieves that I'll be happy to learn.




[The Architecture Behind A One-Person Tech Startup]: https://anthonynsimon.com/blog/one-man-saas-architecture/
[Managing Cloudflare Origin CA certificates]: https://developers.cloudflare.com/ssl/origin-configuration/origin-ca
[Let's Encrypt]: https://letsencrypt.org
[CA]: https://en.wikipedia.org/wiki/Certificate_authority
[End-to-end HTTPS with Cloudflare - Part 3: SSL options]: https://support.cloudflare.com/hc/en-us/articles/200170416-End-to-end-HTTPS-with-Cloudflare-Part-3-SSL-options
[origin-ca-issuer]: https://github.com/cloudflare/origin-ca-issuer
[cert-manager]: https://github.com/jetstack/cert-manager