cert-manager and Exoscale DNS - Manage SSL certificates with ease
Predrag Janoseviccert-manager is a powerful and extensible X.509 certificate controller for Kubernetes. It can manage certificates in the SKS environment and in combination with our cert-manager-webhook it integrates with Exoscale DNS for issuing certificates using ACME DNS01 challenge.
In this short article we will show you how to add a cert-manager to an SKS cluster and configure it to generate a Let’s Encrypt certificate for a domain managed by Exoscale DNS service.
- SKS cluster (check our SKS Quick Start Guide for instructions on how to create a new cluster using Exoscale CLI)
- kubectl
- helm
- A valid Exoscale DNS domain
- An Exoscale API access key
Installing cert-manager and cert-manager-webhook
The easiest way to add cert-manager to an SKS cluster is using static manifest as described in the official cert-manager installation page:
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.10.0/cert-manager.yamlBy default cert-manager will be in its own namespace inside a cluster:
$ kubectl get pods -n cert-manager
NAME READY STATUS RESTARTS AGE
cert-manager-646dddd544-sxz24 1/1 Running 0 22s
cert-manager-cainjector-8676c4b7-q7s9w 1/1 Running 0 22s
cert-manager-webhook-557fb758cf-989db 1/1 Running 0 22scert-manager-webhook is installed using Helm and a Helm Chart in the official cert-manager webhook repository:
git clone https://github.com/exoscale/cert-manager-webhook-exoscale.git
cd cert-manager-webhook-exoscale
helm install exoscale-webhook ./deploy/exoscale-webhookNow we can see cert-manager-webhook running in the default namespace:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
cert-manager-webhook-exoscale-d7dccb674-9czqw 1/1 Running 0 31sIssuing a certificate for a domain
With cert-manager and cert-manager-webhook in place, we can proceed to create a new certificate for our domain. In this example we will generate a certificate for example.com.
cert-manager-webhook requires Exoscale API credentials to manage a DNS record used in the ACME DNS01 challenge. We can generate a restricted access key using Exoscale CLI:
$ exo iam access-key create \
--operation list-dns-domains \
--operation list-dns-domain-records \
--operation get-dns-domain-record \
--operation get-operation \
--operation create-dns-domain-record \
--operation delete-dns-domain-record \
cert-manager-webhook-key
┼────────────────┼─────────────────────────────────────────────┼
│ IAM ACCESS KEY │ │
┼────────────────┼─────────────────────────────────────────────┼
│ Name │ cert-manager-webhook-key │
│ Type │ restricted │
│ API Key │ EXOabcdefghijklmnopqrstuvwx │
│ API Secret │ ABCDEFGIJKLMNOPQRSTUVWXYZabcdefgijklmnopqrs │
│ Operations │ list-dns-domain-records │
│ │ get-dns-domain-record │
│ │ get-operation │
│ │ list-dns-domains │
│ │ create-dns-domain-record │
│ │ delete-dns-domain-record │
┼────────────────┼─────────────────────────────────────────────┼The recommended way to provide API credentials to cert-manager-webhook is using the Kubernetes secret resource. We can create a secret.yaml file with the following content:
apiVersion: v1
stringData:
EXOSCALE_API_KEY: EXOabcdefghijklmnopqrstuvwx
EXOSCALE_API_SECRET: ABCDEFGIJKLMNOPQRSTUVWXYZabcdefgijklmnopqrs
kind: Secret
metadata:
name: exoscale-secret
type: OpaqueAdding the resource is as simple as running:
kubectl create -f secret.yamlNow we can reference our secret when creating an Issuer resource (issuer.yaml):
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: exoscale-issuer
spec:
acme:
email: my-user@example.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: exoscale-private-key-secret
solvers:
- dns01:
webhook:
groupName: acme.exoscale.com
solverName: exoscale
config:
apiKeyRef:
key: EXOSCALE_API_KEY
name: exoscale-secret
apiSecretRef:
key: EXOSCALE_API_SECRET
name: exoscale-secretIssuers are Kubernetes resources representing certificate authorities (CAs), that are able to generate signed certificates by honoring certificate signing requests. We can add the resource as before:
kubectl create -f issuer.yamlThe final piece of the puzzle is the Certificate resource. A Certificate resource specifies fields that are used to generate certificate signing requests, including domain name and which issuer they want to obtain the certificate from. Our new resource (certificate.yaml) will look like this:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: example-com
spec:
dnsNames:
- example.com
issuerRef:
name: exoscale-issuer
secretName: example-com-tlsAnd to add a resource:
kubectl create -f certificate.yamlIt may take a minute or two but eventually we will see our new certificate in the ready state:
$ kubectl get certificate example-com
NAME READY SECRET AGE
example-com True example-com-tls 0m52sThat’s it, now we have a valid certificate in our cluster!

