Working with Microservices-12: Setting Domain Name and TLS certificate for Production Pipeline using Route 53, Let’s Encrypt and Cert Manager

We will set “Domain Name”, create an “A record” in our hosted zone by using AWS Route 53 domain registrar for the microservices app, and then, bind it to our the “Kubernetes cluster of the app”. We will configure a TLS (Transport Layer Security) certificate for HTTPS connection to the domain name using Let’s Encrypt and Cert Manager. Thus, we will be able to provide a secure connection to our application on the Internet. We will do it all step by step.

Cumhur Akkaya
9 min readAug 7, 2023

1. About Route 53, Let’s Encrypt, Cert Manager, and AWS Certificate Manager

Figure 1

Amazon Route53, as a Domain Name System (DNS) service (for domain registration, DNS forwarding, and health checking without coding requirements), as shown in Figure 1. (1)

Figure 2

Let’s Encrypt, in order to enable HTTPS on your website, you need to get a certificate (a type of file) from a Certificate Authority (CA). Let’s Encrypt is a CA. Let’s Encrypt uses the ACME protocol in order to control your domain. The objective of Let’s Encrypt and the ACME protocol is to make it possible to set up an HTTPS server and obtain a browser-trusted certificate, without any human intervention. This is accomplished by running a certificate management agent on the web server, as shown in Figure 2. (2)

Figure 3

Cert Manager, it can give certificates from supported sources such as Let’s Encrypt. Cert-manager adds certificates and certificate issuers as resource types in Kubernetes clusters and simplifies the process of obtaining, renewing, and using those certificates, as shown in Figure 3. (3)

Figure 4

AWS Certificate Manager, as a public and private SSL/TLS(Secure Sockets Layer/Transport Layer Security) certificate provider (for connecting to the web page of the microservices application via HTTPS protocol), as shown in Figure 4. (4) It is AWS cloud’s own solution for creating certificates and I find it much more practical compared to similar others.

2. Create an “A” record

Create an “A” record in your hosted zone for the microservices-app cluster, for example, “micoservices-app.cmakkaya-awsdevops.link” (in this article “cmakkaya-awsdevops.link” is my hosted zone, “micoservices-app” is my subdomain), as shown in Figures 5–6–7. For this, we will use AWS Route 53 domain registrar and bind it to our “petclinic cluster”. (5)

Figure 5
Figure 6

Enter the following values in the relevant places in the Quick create recordwindow, as shown in Figure 7.

Choose load balancer values: is the value of the Load balancer you created before for the cluster and when you click here it will automatically appear. Make sure you choose the right Load balancer.

Record name : micoservices-app 
Record type: A Routes
Alias: Open
Route traffic to: Alias to Aplication and Classic Load Balancer
Choose region: us-east-1
Choose load balancer: dualstack.a5c7431acf1c54cc884cbc6f3a0ced44–691005446.us-east-1.elb.amazonaws.com
Routing policy: Simple
Figure 7

3. Configure TLS(SSL) certificate

Figure 8

The diagram in Figure 8 shows the workflow and architecture components for this article.

Configure TLS(SSL) certificate for “micoservices-app.cmakkaya-awsdevops.link” using “cert-manager” on petclinic K8s cluster with the following steps. Install the “cert-manager” on petclinic cluster (6) (7). For this;

a. Create the namespace for cert-manager.

Note: Enter commands in Jenkins User, under var/lib/Jenkins folder, as shown in Figure 9. Since the commands we will give here, it sees the “.kube” folder, and so it will create the namespace in Amozon-EKS-cluster.

kubectl create namespace cert-manager
Figure 9

b. Add the Jetstack Helm repository. Then, update your local Helm chart repository with the following command, as shown in Figure 10. (8)

helm repo add jetstack https://charts.jetstack.io
helm repo update
Figure 10

c. Install the “Custom Resource Definition” resources separately with the following command, as shown in Figure 11.

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.11.0/cert-manager.crds.yaml
Figure 11

d. Install the cert-manager Helm chart with the following command, as shown in Figure 12. This process takes about one minute to complete. (8)

helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--version v1.11.0
Figure 12

Note: Those who get errors here can use the delete commands below to repeat the last two steps again. If you don’t get an error do not enter the following commands.

kubectl delete -f https://github.com/cert-manager/cert-manager/releases/download/v1.11.0/cert-manager.crds.yaml
helm delete cert-manager --namespace cert-manager

e. Verify that the cert-manager is deployed correctly with the following command, as shown in Figure 13.

kubectl get pods --namespace cert-manager -o wide
Figure 13

f. Create “ClusterIssuer” with name of “tls-cluster-issuer-prod.yml” for the production certificate through “Let’s Encrypt” ACME (Automated Certificate Management Environment) with the following content. Save it under the “k8s” folder (We have determined this folder’s name for our project, but you can assign its name to any value you want in different projects.) with the following values, as shown in Figures 14–15–16. We will import YAML file on Ranhcer in the next steps.

Note: That certificate will only be created after updating the “Ingress” resource. (9)

email: just enter your own e-mail address and leave other values as default.

server: If it will create for the staging phase, you should change this value as well. (9)

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
namespace: cert-manager
spec:
acme:
# The ACME server URL
server: https://acme-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: cmakkaya.aws@gmail.com
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-prod
# Enable the HTTP-01 challenge provider
solvers:
- http01:
ingress:
class: nginx
Figure 14
Figure 15

Check that the file is created correctly using the cat command, as shown in Figure 16.

Figure 16

Note: We use this yaml file in production, there is a different yaml file for staging. Production usage is limited. The following line shows that this file is for production;

server: https://acme-v02.api.letsencrypt.org/directory

g. Install and check, whether the “ClusterIssuer” resource is created with the following command, as shown in Figure 17. You have to give the command in the folder where the tls-cluster-issuer-prod.yml file was created.

kubectl apply -f tls-cluster-issuer-prod.yml
kubectl get clusterissuers letsencrypt-prod -n cert-manager -o wide
Figure 17

Finally, we need to make a change in the “ingress yaml” file. We will do this by using Rancher as well, as the Rancher makes it easier.

4. Modifying ingress.yaml file

Issue production Let’s Encrypt Certificate by annotating and adding the “api-gateway” ingress resource with the following values.

We will change the following values in “api-gateway” Ingress file, as shown in Figure 19.

metadata:
name: api-gateway
annotations:
...
...
cert-manager.io/cluster-issuer: "letsencrypt-prod"

and

spec:
tls:
- hosts:
- micoservices-app.cmakkaya-awsdevops.link
secretName: petclinic-tls

In order to find the name and edit it, use the following commands, as shown in Figure 18.

-bash-4.2$ kubectl get ing -n petclinic-prod-ns
NAME CLASS HOSTS ADDRESS PORTS AGE
api-gateway nginx micoservices-app.cmakkaya-awsdevops.link a5c7431acf1c54cc884cbc6f3a0ced44-691005446.us-east-1.elb.amazonaws.com 80 3h11m
-bash-4.2$ kubectl edit ing api-gateway -n petclinic-prod-ns
Figure 18

Change the wanted places in the opened window and save it with :qw command, as shown in Figure 19 a-b.

Figure 19-a
Figure 19-b

Note: We will do the same editing process in Rancher. We’ll see how easy this is to do in Rancher.

5. Checking output on the browser

Check and verify that the TLS(SSL) certificate created and successfully issued to “micoservices-app.cmakkaya-awsdevops.link” by checking URL of “https://micoservices-app.cmakkaya-awsdevops.link”, as shown in Figures 20.

Figure 20

Check that the certificate is issued, as shown in Figures 21–22–23 and Gif-1.

Figure 21
Figure 22

We can check that we have received our 3-month valid certificate from Let’s Encrypt, as shown in Figure 23.

Figure 23
Gif 1

6. Pushing created files to the remote repo (GitHub)

Commit the change, then push created files (the tls-cluster-issuer-prod.yml file, etc) to the remote repo (GitHub). Run the commands below, as shown in Figure 24. (10)

git add .
git commit -m 'added tls-cluster-issuer-prod.yml for production pipeline'
git push --set-upstream origin production
Figure 24

The best practice is to create a different branch and continue from the new branch in the next stage (5).

7. As a result

We successfully created an “A record” in our hosted zone by using AWS Route 53 domain registrar for the microservices app, and then, binded it to the “Kubernetes cluster of the app”. We configured a TLS (Transport Layer Security) certificate for HTTPS connection to the domain name using Let’s Encrypt and Cert Manager. Thus, we provided a secure connection to our application on the Internet.

We are preparing a sample production CI/CD process that can be used in similar projects.

You can find the necessary files in my GitHub repo.

Share this article with friends in your network and help others to upskill.
I frequently share articles about Cloud and DevOps tools and resources. Follow me on Medium so you don’t miss future articles.

For more info and questions, please contact me on Linkedin.

8. Next post

In the next post, “Working with Microservices-13: Setting Domain Name and TLS Certificate using About Route 53 and AWS Certificate Manager. in Figure 25. This time, we will get a TLS certificate by using AWS Certificate Manager.

Figure 25 - “Working with Microservices-13: Setting Domain Name and TLS Certificate using About Route 53 and AWS Certificate Manager”.

Happy Clouding…

Don’t forget to follow my LinkedIn or Medium account to be informed about new articles.

--

--

Cumhur Akkaya

✦ DevOps/Cloud Engineer, ✦ Believes in learning by doing, ✦ Dedication To Lifelong Learning, ✦ Tea and Coffee Drinker. ✦ Linkedin: linkedin.com/in/cumhurakkaya