diff --git a/content/en/v3/admin/guides/infra/tls_dns.md b/content/en/v3/admin/guides/infra/tls_dns.md index 846adc96a3c..338224152f1 100644 --- a/content/en/v3/admin/guides/infra/tls_dns.md +++ b/content/en/v3/admin/guides/infra/tls_dns.md @@ -10,11 +10,27 @@ aliases: This section will describe how to enable automated TLS and DNS for your Jenkins X installation. -To achive this we will use a couple of open source projects to help enable automated DNS for your applications. +To achieve this we will use a couple of open source projects to help enable automated DNS for your applications. For this guide we are going to assume you own a domain called `foo.io` which is managed by Google Cloud DNS, if it is not see [configure cloud dns to manage a domain](/docs/v3/guides/infra/google_cloud_dns). -Jenkins X services will have URLs like `https://hook-jx.bar.foo.io`. The jx-requirements.yml `namespaceSubDomain:` of `-jx` refers to the Kubernetes namespace the service is running in, this helps avoid clashes of the same application running in different namespaces in the same cluster. + +A common requirement for domains is to have production services accessed using a parent / [apex domain](https://docs.github.com/en/free-pro-team@latest/github/working-with-github-pages/about-custom-domains-and-github-pages#using-an-apex-domain-for-your-github-pages-site) +for example: + +https://foo.com + +Many organisations have extra requirements for development and test multi cluster environments to access services at + +https://dev.foo.com +and +https://staging.foo.com + +These use subdomains. + +In this guide below there is a prerequisite that you must already have a domain which is managed by GCP, this is so that you can choose whichever of the scenarios above you need. It also means the dns management of the apex domain happens outside of a single cluster installation and can be shared by multiple installations using a subdomain. + +Jenkins X services will have URLs like `https://hook-jx.dev.foo.io`. The jx-requirements.yml `namespaceSubDomain:` of `-jx` which is in the cluster git repository refers to the Kubernetes namespace the service is running in, this avoids clashes of the same application running in different namespaces in the same cluster. To start with we are focussed on GCP but will expand to other cloud providers. @@ -23,7 +39,7 @@ To start with we are focussed on GCP but will expand to other cloud providers. ## Prerequisites - cluster created using Jenkins X [GCP Terraform getting started](/docs/v3/getting-started/gke/) -- own a domain, we will use [Google Domains](https://domains.google.com/registrar/) in this guide but any provider will work +- own a domain and have GCP manage it, [configure cloud dns to manage a domain](/docs/v3/guides/infra/google_cloud_dns) - latest Jenkins X CLI, Infrastructure and Cluster git repository updates [upgrade](/docs/v3/guides/upgrade) ### Cloud Infrastructure @@ -43,7 +59,7 @@ Most people prefer to use a subdomain for a specific installation rather than pu To use a subdomain for this cluster add the following configuration: ```yaml -subdomain = "bar" +subdomain = "dev" ``` Now apply these changes: @@ -53,20 +69,24 @@ git add values.auto.tfvars git commit -m 'feat: enable DNS cloud resources' git push ``` - +You may want to set two environment variables here so that Terraform does not prompt for values +``` +export TF_VAR_jx_bot_username= +export TF_VAR_jx_bot_token= +``` +now run ```bash terraform plan terraform apply ``` -You can now see your managed zone in GCP [here](https://console.cloud.google.com/net-services/dns/zones) - +If using a subdomain you will now see your managed zone in GCP [here](https://console.cloud.google.com/net-services/dns/zones) ### Cluster Next we will configure the cluster requirements: -- Install [external-dns](https://github.com/kubernetes-sigs/external-dns#externaldns) - Kubernetes controller which watches for new Kubernetes Ingress resources and creates A records in Google Cloud DNS which will propogate globally across the internet +- Install [external-dns](https://github.com/kubernetes-sigs/external-dns#externaldns) - Kubernetes controller which watches for new Kubernetes Ingress resources and creates A records in Google Cloud DNS which will propagate globally across the internet - Install [cert-manager](https://cert-manager.io/docs/) - Kubernetes controller which watches for requests to ask [Let's Encrypt](https://letsencrypt.org/) to issue a new wildcard TLS certificate for your domain and will manage this including renewals To satisfy these requirements go to your cluster repository (contains helmfile.yaml) @@ -110,7 +130,7 @@ __NOTE__ this is the top level `ingress:` section and __NOT__ in the `environmen ```bash ingress: - domain: bar.foo.io + domain: dev.foo.io externalDNS: false # this is unused and will be deprecated namespaceSubDomain: -jx. tls: @@ -119,7 +139,9 @@ ingress: production: false ``` -When first installing set `tls.production=false` so you use the Lets Encrtpt staging serivce which allows for more API calls before rate limniting requests. They will issue a self-signed certificate so once happy everything is working change this to `tls.production=true` +When first installing set `tls.production=false` so you use the Lets Encrypt staging service which allows for more API calls before rate limiting requests. They will issue a self-signed certificate so once happy everything is working change this to `tls.production=true`. + +__NOTE__ Helmfile is not able to skip insecure TLS when adding helm repositories, therefore staging certificates will not work with chartmuseum that is running in the cluster. Therefore once you have verified cert-manager can issue certificates from staging, switch to the production service. Jenkins X uses a version stream to rollout tested versions of images, charts and default configuration. The `jx-boot` job will apply these versions to your helmfile but you can also run the step yourself to see the defaults. @@ -128,8 +150,8 @@ jx gitops helmfile resolve ``` ```bash -git add values.auto.tfvars -git commit -m 'feat: enable DNS cloud resources' +git add helmfile.yaml +git commit -m 'feat: enable DNS and TLS' git push ``` @@ -138,6 +160,68 @@ Now tail the admin logs and wait for the job to complete jx admin logs ``` +It can take a short while for DNS to propagate so you may need to wait for 5 - 10 minutes. https://dnschecker.org/ is a useful way to check the status of DNS propagating. + +You should be able to verify the TLS certificate from Lets Encrypt in your browser (beware of browser caching if you don't see any changes) + +![Working TLS](/images/v3/working_tls.png) + ## How to get TLS in my preview environment? -In your applications preview helm chart you can add a Kubernetes [Certificate](https://cert-manager.io/docs/concepts/certificate/) the same as in your `jx` namespace and cert-manager will create the secret needed by an Ingress rule for TLS. \ No newline at end of file +In your applications preview helmfile.yaml you can add the same acme helm chart used above however because your application git repository does not have the version stream your cluster git repository above has you will need to add the default values yourself. + +Add this to you applications `./preview/helmfile.yaml` + +``` +repositories: +- name: jx3 + url: https://storage.googleapis.com/jenkinsxio/charts +releases: +- chart: jx3/acme + name: tls + namespace: '{{ requiredEnv "PREVIEW_NAMESPACE" }}' + values: + - jx-values.yaml + - issuer: + cluster: true +``` + +_Note_ as this will request a certificate that matches your existing domain configured above, cert-manager will reuse a cached certificate rather than issue a new one which can cause rate limitting by Lets Encrypt. + +## What if I have a chartmuseum with charts running using nip.io? + +It is best to comment out your Jenkins X chartmuseum repository and charts from your helmfile until your new domain and ingress is working. Then uncomment and make sure you update the chartmuseum URL to your new one. + +## What if I use a subdomain with an apex domain in a different GCP project? + +When using a subdomain Terraform will create a managed zone in GCP, add the recordsets to your parent / apex domain. + +If the GCP managed zone for your apex domain is in a different GCP project than the project that your current installation the you will need to set in your infrastructure repository the terraform variable: + +``` +parent_domain_gcp_project: [your GCP project that is managing your apex domain] +``` + +If you do not have permission to update the recordset of the apex domain then you will need to manually update it after getting the nameservers created for your subdomain managed zone and disable the automatic way using: + +``` +apex_domain_integration_enabled: false +``` + +## How can I check if cert-manager has issued a certificate? + +You can check the status of the certificate by running + +``` +kubectl get cert -n jx +``` +``` +kubectl describe cert -n jx +``` +if `Ready` continues to be `false` after 10-15 mins you can check on the request using +``` +kubectl get certificaterequest -n jx +``` +``` +kubectl describe certificaterequest -n jx +``` diff --git a/static/images/v3/working_tls.png b/static/images/v3/working_tls.png new file mode 100644 index 00000000000..5f3c41c66f8 Binary files /dev/null and b/static/images/v3/working_tls.png differ