Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save hatembentayeb/7e6a0fc89b510004c6730ae2db401fc1 to your computer and use it in GitHub Desktop.
Save hatembentayeb/7e6a0fc89b510004c6730ae2db401fc1 to your computer and use it in GitHub Desktop.

Revisions

  1. @marcopaga marcopaga revised this gist Aug 22, 2018. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions lets-encrypt-wildcard-certs-using-azure-dns-on-aks.md
    Original file line number Diff line number Diff line change
    @@ -29,10 +29,10 @@ You need to feed the API with the client id and client secret of a [ServicePrini
    metadata:
    name: letsencrypt-prod
    spec:
    commonName: '*.dev.company.de'
    dnsNames:
    - "*.dev.company.de"
    acme:
    commonName: '*.dev.company.de'
    dnsNames:
    - "*.dev.company.de"
    acme:
    server: "https://acme-v02.api.letsencrypt.org/directory"
    email: [email protected]
    privateKeySecretRef:
  2. @marcopaga marcopaga revised this gist Aug 22, 2018. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions lets-encrypt-wildcard-certs-using-azure-dns-on-aks.md
    Original file line number Diff line number Diff line change
    @@ -53,13 +53,15 @@ You need to feed the API with the client id and client secret of a [ServicePrini
    tenantID: "###TENANT_ID###"

    Don’t forget to provide the client secret.

    kubectl -n kube-system create secret generic azuredns-config --from-literal=client-secret="$CLIENT_SECRET"

    Now you have configured how new tls certificates can be retrieved.

    ## Setup the wildcard certificate
    Now you can define a Certificate API object that describes the validity of the desired format. The format will be retrieved using the letsencrypt-prod ClusterIssuer defined by the issuerRef.
    The certificate will be placed in a secret named wildcard-domain-tls-secret that can be [wired up to an ingress resource](https://kubernetes.io/docs/concepts/services-networking/ingress/#tls).

    apiVersion: certmanager.k8s.io/v1alpha1
    kind: Certificate
    metadata:
    @@ -83,6 +85,7 @@ The certificate will be placed in a secret named wildcard-domain-tls-secret that

    ## Use the wildcard certificate
    And the final part is to use the wildcard certificate.

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
  3. @marcopaga marcopaga renamed this gist Aug 22, 2018. 1 changed file with 0 additions and 0 deletions.
  4. @marcopaga marcopaga created this gist Aug 22, 2018.
    119 changes: 119 additions & 0 deletions lets-encrypt-wildcard-certs-using-azure-dns-on-aks
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,119 @@
    This gist will guide you through the setup of a wildcard Let's encrypt TLS certificate.

    # Let's encrypt
    Let’s encrypt is one of a new kind of Certificate Authority. You can get a TLS certificate from them for your website free of charge and without any manual overhead. These certificates are trusted in most browsers that are out there and will show up as valid.
    Instead of sending Mails or even paper around you can call an API and prove your domain ownership with simple challenges. Basically you call the API with a hostname or domain name you need a TLS certificate for and you get back a challenge string that you need to put in a well known location on your [http host](https://ietf-wg-acme.github.io/acme/draft-ietf-acme-acme.html#rfc.section.8.3) or as a [txt record in your dns system](https://ietf-wg-acme.github.io/acme/draft-ietf-acme-acme.html#rfc.section.8.4).

    # The little helper for Kubernetes: Cert-Manager
    You can find [many clients](https://letsencrypt.org/docs/client-options/) that manage the process and keep your TLS certificates up to date. In the area of kubernetes I can highly recommend [cert-manager](https://github.com/jetstack/cert-manager) which is the successor of kube-lego.
    It’s quite easy to deploy via the [helm chart](https://cert-manager.readthedocs.io/en/latest/getting-started/2-installing.html#with-helm).

    # DNS01 Challenge with AzureDNS for a Wildcard Certificate
    If you have a bigger installation which is more dynamic - hostnames come and go - you will hit [rate limits](https://letsencrypt.org/docs/rate-limits/) pretty soon which will block your account from getting new TLS certificates for quite some time.
    If you for example want every developer to have a dedicated API endpoint in the cluster to test a micro service app you can create an isolated environment. So something like `marco.dev.company.de` and `feature-two.dev.company.de` should be deployable.
    If you are using the simple http proof you get the system up and running but you can’t scale the installation.

    The cert-manager has the ability to use the dns proof with Azure-DNS and will create the TXT record and maintain the certificates. You pretty much don’t have to worry about the details.

    # Installation and Configuration

    ## Cert-Manager via helm
    First make sure to install the cert-manager helm chart in your cluster. You can follow along the guide on the [cert-manager website](https://cert-manager.readthedocs.io/en/latest/getting-started/2-installing.html#with-helm).

    ## Setup the Cluster-Issuer
    Now it’s time to configure a [ClusterIssuer](https://cert-manager.readthedocs.io/en/latest/reference/clusterissuers.html) that can be used to create certificates. As mentioned you can find the config for azure DNS here.
    You need to feed the API with the client id and client secret of a [ServicePrinicipal](https://docs.microsoft.com/de-de/azure/azure-resource-manager/resource-group-create-service-principal-portal) that has the privilege to update DNS entries.

    apiVersion: certmanager.k8s.io/v1alpha1
    kind: ClusterIssuer
    metadata:
    name: letsencrypt-prod
    spec:
    commonName: '*.dev.company.de'
    dnsNames:
    - "*.dev.company.de"
    acme:
    server: "https://acme-v02.api.letsencrypt.org/directory"
    email: [email protected]
    privateKeySecretRef:
    name: letsencrypt-prod
    dns01:
    providers:
    - name: azure-dns
    domains:
    - '*.dev.company.de'
    azuredns:
    clientID: "###CLIENT_ID###"
    clientSecretSecretRef:
    key: client-secret
    name: azuredns-config
    hostedZoneName: "dev.company.de"
    resourceGroupName: "infrastructure"
    subscriptionID: "###SUBSCRIPTION_ID###"
    tenantID: "###TENANT_ID###"

    Don’t forget to provide the client secret.
    kubectl -n kube-system create secret generic azuredns-config --from-literal=client-secret="$CLIENT_SECRET"

    Now you have configured how new tls certificates can be retrieved.

    ## Setup the wildcard certificate
    Now you can define a Certificate API object that describes the validity of the desired format. The format will be retrieved using the letsencrypt-prod ClusterIssuer defined by the issuerRef.
    The certificate will be placed in a secret named wildcard-domain-tls-secret that can be [wired up to an ingress resource](https://kubernetes.io/docs/concepts/services-networking/ingress/#tls).
    apiVersion: certmanager.k8s.io/v1alpha1
    kind: Certificate
    metadata:
    name: wildcard-domain
    namespace: default
    spec:
    secretName: wildcard-domain-tls-secret
    issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
    commonName: '*.dev.company.de'
    dnsNames:
    - '*.dev.company.de'
    acme:
    config:
    - dns01:
    provider: azure-dns
    domains:
    - '*.dev.company.de'


    ## Use the wildcard certificate
    And the final part is to use the wildcard certificate.
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
    name: {{ template "my-app.fullname" . }}-ingress
    labels:
    type: infrastructure
    app: {{ template "my-app.fullname" . }}
    chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
    release: "{{ .Release.Name }}"
    heritage: "{{ .Release.Service }}"
    spec:
    rules:
    - host: {{ .Values.ingress.frontend.host }}
    http:
    paths:
    - path: /
    backend:
    serviceName: {{ template "my-app.fullname" $ }}-frontend
    servicePort: 80
    {{ if .Values.ingress.tls.enabled }}
    tls:
    - hosts:
    - {{ .Values.ingress.frontend.host }}
    {{ if .Values.ingress.tls.letsEncrypt }}
    secretName: wildcard-domain-tls-secret
    {{ else }}
    secretName: {{ template "my-app.fullname" $ }}-ingress-tls-frontend-secret
    {{ end }}
    {{ end }}

    You see that I simply reference the certificate in the TLS section of the manifest. I needed to distinguish between a Let’s Encrypt environment and a self provisioned secret so I made the whole part switchable using variables.

    # Enjoy
    Now you create new hosts in your environment without delays and any rate limits.