SSL termination, sometimes so easy, sometimes so hard… If you ended up reading this article you probably are in the second group. Welcome to the brotherhood, mate.

SSL Termination, that thing

 

Our problem

China! No, not China as a whole. We are talking about getting SSL certificates inside China Mainland, as the Chinese Cybersecurity Law is quite strict and not every company complaints with it or know how to.

For us, in this case, means that services like Let’s Encrypt or others are not reliable enough to be used as source of our much-needed encryption certificate.

So, just to clarify, this affects to services running inside China Mainland, not to the services running outside it. It also assumes you already have a valid certificate to use, either by buying it on Alibaba Cloud or other platforms. Psst, the Aliyun site (Chinese Alibaba Cloud) has lots of good offers!

 

Give me a solution

Fine, lets get into the tldr-ish section!

As the title of the post suggests, this article will expose a solution on how to terminate SSL connections by using only-and-only Alibaba Cloud products and services on a Kubernetes cluster (or k8s, depending on how cool you are). This guarantees this solution as something applicable to any other region in this cloud provider.

Kubernetes Logo, a ship’s wheel. All about containers and boats!

 

As usual, my deployments are managed by Terraform, something I find very convenient even for being used with Kubernetes clusters, as you can mix-and-match several providers and your assets will get the attention and visibility they deserve.

 

Terraform configs

resource "alicloud_slb_server_certificate" "__example_cn" {
  name               = "__example_cn"
  server_certificate = file("${path.module}/certs/__example.cn.pem")
  private_key        = file("${path.module}/certs/__example.cn.key")
}

resource "kubernetes_service" "backend" {
  metadata {
    name = "app-service"
    annotations = {
      "service.beta.kubernetes.io/alibaba-cloud-loadbalancer-protocol-port" : "https:443,http:80"
      "service.beta.kubernetes.io/alibaba-cloud-loadbalancer-forward-port" : "80:443"
      "service.beta.kubernetes.io/alibaba-cloud-loadbalancer-cert-id" : alicloud_slb_server_certificate.__example_cn.id
    }
  }

  spec {
    port {
      name        = "https"
      port        = 443
      target_port = 80
    }

    port {
      name        = "http"
      port        = 80
      target_port = 80
    }

    type = "LoadBalancer"

    selector = "app"
  }

  wait_for_load_balancer = false
}

 

Explanation of the above

If you are fluent in HCL, you can see how the magic in this example goes:

  1. Import the certificates we locally have by using the resource type “alicloud_slb_server_certificate”.
  2. Leveraging the existing “kubernetes_service” you should already have in your project, adding some annotations to let Alibaba Cloud know you need an SLB with some specific requirements.

Data flow in our example

 

Conclusion

As usual when mixing Cloud Providers with Kubernetes, annotations are key in talking between your cluster and the built-in integrations with all the managed services exposed to Kubernetes. In our case we were able to create a whole SLB and selecting an specific certificate.