Creating & using custom SSL Certificate
For TLS you need to have certificates against your domain. In this day and age it's mandatory to secure your website with HTTPS. There are multiple ways of creating certificates, we use Let's Encrypt as our certificate authority.
Create certificates using terraform
We create certificate through terraform and LetsEncrypt using Acme, only con is that the certificate will have an expiry of 90 days. For that refer to terraform-aws-certificate repo. Generate LetsEncrypt certificates for AWS(Route 53) hosted domain using Terraform.!
Install Terraform v11.6
Create a user on AWS with the set of permissions attached AmazonRoute53FullAccess, AWSCertificateManagerFullAccess, Route53CreateHostedZone
Install and setup AWS CLI, ensure AWS credentials are in place
Update DOMAIN and domain ADMINISTRATOR_EMAIL in
terraform initto initialize the working directory, run
terraform planto create an execution plan and finally run
terraform applyto generate desired output.
terraform init terraform plan terraform apply
It will take a few minutes to create certificates. Once complete, your certificates will be stored in
This output can be mapped to the following fields in a secret that would contain your certificate:
- ca.crt -> public_certificate_intermediate_pem
- tls.crt -> public_certificate_pem
- tls.key -> public_certificate_key
Note: If you are using Azure as DNS provider use terraform-azure-openshift repo and follow the same steps.
Create certificates using https://www.sslforfree.com/
You can visit https://www.sslforfree.com/ and generate your certificates from there, this requires manual labour unlike terraform. It supports FTP verification, and verification against DNS & HTTP challenges.
Using custom certificates
Create a secret file by running the following command and replace ca.crt, tls.crt and tls.key with your certificate values, generated in the above step or if you already have the certificate generated use those values.
cat <<-EOF > cert-secret.yaml apiVersion: v1 data: ca.crt: "$(cat ca.crt | base64 --wrap=0)" tls.crt: "$(cat tls.crt | base64 --wrap=0)" tls.key: "$(cat tls.key | base64 --wrap=0)" kind: Secret metadata: name: tls-cert type: Opaque EOF
It will create a file cert-secret.yaml which contains k8s secret
tls-cert for your certificates.
Now apply this secret in the namespace you want to have your ingress.
You can add this secret to tls section of your ingress.
apiVersion: extensions/v1beta1 kind: Ingress metadata: annotations: ingress.kubernetes.io/force-ssl-redirect: "true" ingress.kubernetes.io/rewrite-target: / kubernetes.io/ingress.class: nginx name: ingress-name namespace: ingress-namespace spec: backend: serviceName: svc-name servicePort: 80 rules: - host: svc-name.namespace.domain http: paths: - backend: serviceName: svc-name servicePort: 80 path: / tls: - hosts: - svc-name.namespace.domain secretName: secret-name
When you open the host, you can see the certificate.
You can also set the nginx-ingress-controller to use this cert by default, you need to add following args to nginx-ingress controller,
extraArgs: annotations-prefix: ingress.kubernetes.io enable-dynamic-certificates: "false" enable-ssl-chain-completion: true default-ssl-certificate: "<namespace>/<tls-secret-name>"
If you have a wildcard certificate, you can add the same secret in all namespaces and refer that in the ingresses.