# Manage TLS Certificates using IONOS Cloud DNS Webhook for cert-manager

This tutorial will guide you through managing TLS certificates using the IONOS Cloud DNS Webhook for [<mark style="color:blue;">cert-manager</mark>](https://cert-manager.io/). Following these steps, you can secure your Kubernetes cluster workloads with valid TLS certificates that are automatically renewed before they expire.

## Target audience

This tutorial is intended to help both developers and technical decision-makers.

## What you will learn

You will learn how to automate the issuance and renewal of TLS certificates for your Kubernetes workloads using cert-manager and the IONOS Cloud DNS Webhook. This tutorial covers the complete setup process, including configuring DNS zones, secrets, and certificate resources for secure application deployment.

## Before you begin

You must have the following:

* An IONOS Cloud account.
* A domain name registered and managed by IONOS Cloud DNS.
* A Kubernetes cluster set up. If you have not yet set up a Kubernetes cluster, follow the instructions in [<mark style="color:blue;">Set Up a Kubernetes Cluster</mark>](https://docs.ionos.com/cloud/containers/managed-kubernetes/how-tos/cluster_management) to create one.
* A `kubectl` installed and configured to interact with your Kubernetes cluster. If you have not downloaded the `kubeconfig` file yet, follow the instructions in [<mark style="color:blue;">Download Kubeconfig File</mark>](https://docs.ionos.com/cloud/containers/managed-kubernetes/download-kubeconfig-file) to download it.
* A `cert-manager` installed in your Kubernetes cluster. If not, you can install it by following the instructions on the [<mark style="color:blue;">cert-manager Installation guide</mark>](https://cert-manager.io/docs/installation/).

## Procedure

{% stepper %}
{% step %}

#### Install `cert-manager`

Ensure that `cert-manager` is installed in your Kubernetes cluster. For more information about the instructions, refer to the [<mark style="color:blue;">cert-manager Installation guide</mark>](https://cert-manager.io/docs/installation/).

{% hint style="info" %}
**Note:** This tutorial uses `cert-manager` version `v1.17.0`; please always use the latest version of `cert-manager`.
{% endhint %}

Execute the following command, if it is not already installed:

```bash
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.17.0/cert-manager.yaml
```

{% endstep %}

{% step %}

#### Create a secret for the IONOS Cloud API Token

Create a Kubernetes secret to store your IONOS Cloud API token. Run the following command to create the secret:

{% hint style="info" %}
**Note:** Replace `IONOS Cloud Token` with your actual IONOS Cloud token. For more information on managing authentication tokens, see [<mark style="color:blue;">Manage Authentication Tokens</mark>](https://docs.ionos.com/cloud/management/identity-access-management/token-manager). Ensure that the token is refreshed so that certificates can be renewed automatically.
{% endhint %}

```bash
kubectl create secret generic cert-manager-webhook-ionos-cloud  \
  -n cert-manager \
  --from-literal=auth-token=<IONOS Cloud Token>
```

{% endstep %}

{% step %}

#### Create a DNS Zone in IONOS Cloud DNS

If you have not yet created a primary zone in IONOS Cloud DNS, you need to create one. For more information, see [<mark style="color:blue;">Create a Primary Zone</mark>](https://docs.ionos.com/cloud/network-services/cloud-dns/dcd-how-tos/public-zone/primary-zone/create-primary-zone).
{% endstep %}

{% step %}

#### Add the Helm repository

 1. Add the Helm repository for the IONOS Cloud Cert Manager webhook:

```bash
helm repo add cert-manager-webhook-ionos-cloud https://ionos-cloud.github.io/cert-manager-webhook-ionos-cloud
```

 2. Next, update the Helm repositories using the following command:

```bash
helm repo update
```

{% endstep %}

{% step %}

#### Install the IONOS Cloud Cert Manager webhook

To use the IONOS Cloud Cert Manager webhook, you need to install it in your Kubernetes cluster using Helm. Run the following command to install the webhook:

{% hint style="info" %}
**Note:** As a standard practice, cert-manager is deployed within the `cert-manager` namespace. This chart operates under the assumption of this default namespace and leverages this setting to assign the necessary privileges to the cert-manager service account, thereby enabling the creation of resources classified as "ionos-cloud." If you are deploying the cert-manager chart in a different namespace, use the `certManager.namespace` chart value to specify the namespace where cert-manager is deployed. For example, use `--set certManager.namespace=custom_namespace`.
{% endhint %}

```bash
helm upgrade cert-manager-webhook-ionos-cloud \
--namespace cert-manager \
--install cert-manager-webhook-ionos-cloud/cert-manager-webhook-ionos-cloud
```

For more information, refer to the [<mark style="color:blue;">IONOS Cloud DNS Webhook for cert-manager</mark>](https://github.com/ionos-cloud/cert-manager-webhook-ionos-cloud?tab=readme-ov-file#readme) documentation.
{% endstep %}

{% step %}

#### Create a `ClusterIssuer` resource

Create a `ClusterIssuer` resource in your Kubernetes cluster to configure the IONOS Cloud Cert Manager webhook. Save the following YAML content to a file named `clusterissuer.yaml`:

{% hint style="info" %}
**Note:** Replace `your_email@example.com` with your actual email address.
{% endhint %}

```bash
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: ionos-cloud-issuer
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: your_email@example.com
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
    - dns01:
        webhook:
          groupName: acme.ionos.com
          solverName: ionos-cloud
```

{% endstep %}

{% step %}

#### Apply the `ClusterIssuer` resource

Apply the `ClusterIssuer` resource to your Kubernetes cluster by running the following command:

```bash
kubectl apply -f clusterissuer.yaml
```

{% endstep %}

{% step %}

#### Create a `Certificate` resource

Create a `Certificate` resource to request a TLS certificate for your domain. Save the following YAML content to a file named `certificate.yaml`:

{% hint style="info" %}
**Note:** Replace `yourdomain.com` with your actual domain name.
{% endhint %}

```bash
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: yourdomain-com
  namespace: default
spec:
  secretName: yourdomain-com-tls
  issuerRef:
    name: ionos-cloud-issuer
    kind: ClusterIssuer
  commonName: '*.yourdomain.com' # project must be the owner of this primary zone
  duration: 8760h0m0s
  dnsNames:
    - yourdomain.com
    - '*.yourdomain.com'
```

{% endstep %}

{% step %}

#### Apply the `Certificate` resource

Apply the `Certificate` resource to your Kubernetes cluster by running the following command:

{% hint style="info" %}
**Note:** The certificate resource will create a certificate request and order a certificate from the ACME server. The webhook will create a DNS record of TXT type in the IONOS Cloud primary zone. Depending on the issuer, approval of the certificate request might take several minutes.
{% endhint %}

```bash
kubectl apply -f certificate.yaml
```

{% endstep %}

{% step %}

#### Create an `Ingress` resource

Create an `Ingress` resource to expose your application using the TLS certificate. Save the following YAML content to a file named `ingress.yaml`:

{% hint style="info" %}
**Note:** Replace `yourdomain.com` with your actual domain name.
{% endhint %}

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  namespace: default
  annotations:
    ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: "nginx"
  rules:
    - host: "app.yourdomain.com"
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: webapp
                port:
                  number: 80
  tls:
    - hosts:
        - "app.yourdomain.com"
      secretName: yourdomain-com-tls
```

{% endstep %}

{% step %}

#### Apply the `Ingress` resource

Apply the `Ingress` resource to your Kubernetes cluster using the following command:

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

{% endstep %}

{% step %}

#### Verify the Certificate

Verify if the certificate has been issued and stored in the specified secret. Run the following command to check the status of the certificate:

```bash
kubectl describe certificate yourdomain-com-tls
```

{% endstep %}
{% endstepper %}

### Final result

You should see the certificate details and the status indicating that the certificate has been successfully issued. The output should look similar to the following:

```bash
Name:         yourdomain-com
Namespace:    default
Labels:       <none>
Annotations:  <none>
API Version:  cert-manager.io/v1
Kind:         Certificate
Metadata:
  Creation Timestamp:  2025-03-24T16:01:05Z
  Generation:          1
  Resource Version:    37314086452
  UID:                 00354607-ab4c-4654-b7ad-941e1c945abe
Spec:
  Common Name:  *.yourdomain.com
  Dns Names:
    yourdomain.com
    *.yourdomain.com
  Duration:  8760h0m0s
  Issuer Ref:
    Kind:       ClusterIssuer
    Name:       letsencrypt-prod
  Secret Name:  yourdomain-com-tls
Status:
  Conditions:
    Last Transition Time:  2025-03-24T16:03:32Z
    Message:               Certificate is up to date and has not expired
    Observed Generation:   1
    Reason:                Ready
    Status:                True
    Type:                  Ready
  Not After:               2025-06-22T15:05:00Z
  Not Before:              2025-03-24T15:05:01Z
  Renewal Time:            2025-05-23T15:05:00Z
  Revision:                1
Events:
  Type    Reason     Age   From                                       Message
  ----    ------     ----  ----                                       -------
  Normal  Issuing    29m   cert-manager-certificates-trigger          Issuing certificate as Secret does not exist
  Normal  Generated  29m   cert-manager-certificates-key-manager      Stored new private key in temporary Secret resource "yourdomain-com-wjmmm"
  Normal  Requested  29m   cert-manager-certificates-request-manager  Created new CertificateRequest resource "yourdomain-com-1"
  Normal  Issuing    26m   cert-manager-certificates-issuing          The certificate has been successfully issued
```

## Conclusion

You have successfully set up and managed TLS certificates using the IONOS Cloud `cert-manager` widget and IONOS Cloud DNS service. This ensures that your web server is secure and your data is protected. For more information, refer to the cert-manager official documentation and the IONOS [<mark style="color:blue;">Cloud DNS</mark>](https://docs.ionos.com/cloud/network-services/cloud-dns) documentation.
