|
| 1 | +## Certificate issuance with LetsEncrypt.org |
| 2 | + |
| 3 | +This section configures your AKS to leverage [LetsEncrypt.org](https://letsencrypt.org/) and automatically obtain a |
| 4 | +TLS/SSL certificate for your domain. The certificate will be installed on Application Gateway, which will perform |
| 5 | +SSL/TLS termination for your AKS cluster. The setup described here uses the |
| 6 | +[cert-manager](https://github.com/jetstack/cert-manager) Kubernetes add-on, which automates the creation and management of |
| 7 | +certificates. |
| 8 | + |
| 9 | +Follow the steps below to install [cert-manager](https://docs.cert-manager.io) on your existing AKS cluster. |
| 10 | + |
| 11 | +##### 1. Helm Chart |
| 12 | + |
| 13 | +Run the following script to install the `cert-manager` helm chart. This will: |
| 14 | + - create a new `cert-manager` namespace on your AKS |
| 15 | + - create the following CRDs: Certificate, Challenge, ClusterIssuer, Issuer, Order |
| 16 | + - install cert-manager chart (from [docs.cert-manager.io)](https://docs.cert-manager.io/en/latest/getting-started/install/kubernetes.html#steps) |
| 17 | + |
| 18 | + |
| 19 | +```bash |
| 20 | +#!/bin/bash |
| 21 | + |
| 22 | +# Install the CustomResourceDefinition resources separately |
| 23 | +kubectl apply -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.8/deploy/manifests/00-crds.yaml |
| 24 | + |
| 25 | +# Create the namespace for cert-manager |
| 26 | +kubectl create namespace cert-manager |
| 27 | + |
| 28 | +# Label the cert-manager namespace to disable resource validation |
| 29 | +kubectl label namespace cert-manager certmanager.k8s.io/disable-validation=true |
| 30 | + |
| 31 | +# Add the Jetstack Helm repository |
| 32 | +helm repo add jetstack https://charts.jetstack.io |
| 33 | + |
| 34 | +# Update your local Helm chart repository cache |
| 35 | +helm repo update |
| 36 | + |
| 37 | +# Install the cert-manager Helm chart |
| 38 | +helm install \ |
| 39 | + --name cert-manager \ |
| 40 | + --namespace cert-manager \ |
| 41 | + --version v0.8.0 \ |
| 42 | + jetstack/cert-manager |
| 43 | +``` |
| 44 | + |
| 45 | +##### 2. ClusterIssuer Resource |
| 46 | + |
| 47 | +Create a `ClusterIssuer` resource. It is required by `cert-manager` to represent the `Lets Encrypt` certificate |
| 48 | +authority where the signed certificates will be obtained. |
| 49 | + |
| 50 | +By using the non-namespaced `ClusterIssuer` resource, cert-manager will issue certificates that can be consumed from |
| 51 | +multiple namespaces. `Let’s Encrypt` uses the ACME protocol to verify that you control a given domain name and to issue |
| 52 | +you a certificate. More details on configuring `ClusterIssuer` properties |
| 53 | +[here](https://docs.cert-manager.io/en/latest/tasks/issuers/index.html). `ClusterIssuer` will instruct `cert-manager` |
| 54 | +to issue certificates using the `Lets Encrypt` staging environment used for testing (the root certificate not present |
| 55 | +in browser/client trust stores). |
| 56 | + |
| 57 | +The default challenge type in the YAML below is `http01`. Other challenges are documented on [letsencrypt.org - Challenge Types](https://letsencrypt.org/docs/challenge-types/) |
| 58 | + |
| 59 | +**IMPORTANT:** Update `<YOUR.EMAIL@ADDRESS>` in the YAML below |
| 60 | + |
| 61 | +```bash |
| 62 | +#!/bin/bash |
| 63 | +kubectl apply -f - <<EOF |
| 64 | +apiVersion: certmanager.k8s.io/v1alpha1 |
| 65 | +kind: ClusterIssuer |
| 66 | +metadata: |
| 67 | + name: letsencrypt-staging |
| 68 | +spec: |
| 69 | + acme: |
| 70 | + # You must replace this email address with your own. |
| 71 | + # Let's Encrypt will use this to contact you about expiring |
| 72 | + # certificates, and issues related to your account. |
| 73 | + email: <YOUR.EMAIL@ADDRESS> |
| 74 | + # ACME server URL for Let’s Encrypt’s staging environment. |
| 75 | + # The staging environment will not issue trusted certificates but is |
| 76 | + # used to ensure that the verification process is working properly |
| 77 | + # before moving to production |
| 78 | + server: https://acme-staging-v02.api.letsencrypt.org/directory |
| 79 | + privateKeySecretRef: |
| 80 | + # Secret resource used to store the account's private key. |
| 81 | + name: example-issuer-account-key |
| 82 | + # Enable the HTTP-01 challenge provider |
| 83 | + # you prove ownership of a domain by ensuring that a particular |
| 84 | + # file is present at the domain |
| 85 | + http01: {} |
| 86 | +EOF |
| 87 | +``` |
| 88 | + |
| 89 | +##### 3. Deploy App |
| 90 | + |
| 91 | +Create an Ingress resource to Expose the `guestbook` application using the Application Gateway with the Lets Encrypt Certificate. |
| 92 | + |
| 93 | +Ensure you Application Gateway has a public Frontend IP configuration with a DNS name (either using the |
| 94 | +default `azure.com` domain, or provision a `Azure DNS Zone` service, and assign your own custom domain). |
| 95 | +Note the annotation `certmanager.k8s.io/cluster-issuer: letsencrypt-staging`, which tells cert-manager to process the |
| 96 | +tagged Ingress resource. |
| 97 | + |
| 98 | +**IMPORTANT:** Update `<PLACEHOLDERS.COM>` in the YAML below with your own domain (or the Application Gateway one, for example |
| 99 | +'kh-aks-ingress.westeurope.cloudapp.azure.com') |
| 100 | + |
| 101 | +```bash |
| 102 | +kubectl apply -f - <<EOF |
| 103 | +apiVersion: extensions/v1beta1 |
| 104 | +kind: Ingress |
| 105 | +metadata: |
| 106 | + name: guestbook-letsencrypt-staging |
| 107 | + annotations: |
| 108 | + kubernetes.io/ingress.class: azure/application-gateway |
| 109 | + certmanager.k8s.io/cluster-issuer: letsencrypt-staging |
| 110 | +spec: |
| 111 | + tls: |
| 112 | + - hosts: |
| 113 | + - <PLACEHOLDERS.COM> |
| 114 | + secretName: guestbook-secret-name |
| 115 | + rules: |
| 116 | + - host: <PLACEHOLDERS.COM> |
| 117 | + http: |
| 118 | + paths: |
| 119 | + - backend: |
| 120 | + serviceName: frontend |
| 121 | + servicePort: 80 |
| 122 | +EOF |
| 123 | +``` |
| 124 | + |
| 125 | +After a few seconds, you can access the `guestbook` service through the Application Gateway HTTPS url using the automatically issued **staging** `Lets Encrypt` certificate. |
| 126 | +Your browser may warn you of an invalid cert authority. The staging certificate is issued by `CN=Fake LE Intermediate X1`. This is an indication that the system worked as expected and you are ready for your production certificate. |
| 127 | + |
| 128 | + |
| 129 | +##### 4. Production Certificate |
| 130 | +Once your staging certificate is setup successfully you can switch to a production ACME server: |
| 131 | + 1. Replace the staging annotation on your Ingress resource with: `certmanager.k8s.io/cluster-issuer: letsencrypt-prod` |
| 132 | + 2. Delete the existing staging `ClusterIssuer` you created in the previous step and create a new one by replacing the ACME server from the ClusterIssuer YAML above with `https://acme-v02.api.letsencrypt.org/directory` |
| 133 | + |
| 134 | +##### 5. Certificate Expiration and Renewal |
| 135 | +Before the `Lets Encrypt` certificate expires, `cert-manager` will automatically update the certificate in the Kubernetes secret store. At that point, Application Gateway Ingress Controller will apply the updated secret referenced in the ingress resources it is using to configure the Application Gateway. |
0 commit comments