This repo contains three Terraform modules to provision a GKE cluster (with VPC and subnet), then deploy Helm charts and Kubernetes manifests.
The included deployments are designed for a fully-functioning Ingress controller that works with Cloudflare.
Note: the GCP module in this repo is a modified fork of learn-terraform-provision-gke-cluster; the MPL 2.0 license is adhered to.
- Secret Management: Sealed Secrets
- Ingress Controller: Ingress NGINX Controller
- TLS Certificate: cert-manager & Let's Encrypt
- Authoritative DNS: ExternalDNS & Cloudflare DNS
- GitOps: Argo CD
The deploy.sh
script does everything needed in order to deploy the full environment in the correct order. In order to use this script, you need a Unix shell (the script is written for POSIX shell - designed to have wide compatibility in Linux, macOS and WSL environments).
In addition, you will need to have the following packages installed:
- gcloud CLI (configured with
gcloud init
) - kubectl
- kubeseal
- Terraform
For Cloudflare, you should own a domain and register it in Cloudflare. Then generate an API token with the permissions described here: https://cert-manager.io/docs/configuration/acme/dns01/cloudflare/#api-tokens
-
In your shell, run
gcloud init
-
Enable billing for the GCP project you're using: see Google Cloud documentation on enabling billing for a project. GCP free trial can be used (if eligible).
-
Edit the
terraform.tfvars.example
file:
- Use the command:
cp "terraform.tfvars.example" "terraform.tfvars"
- Edit
terraform.tfvars
using a text editor. Make sure to add an appropriate GCP project ID (according to what you configured in step 1).
-
Run the
deploy.sh
script -
When running the script, the GKE cluster would be provisioned first, together with a sealed-secrets controller. You would then be asked to provide your Cloudflare API token which will be configured as a sealed secret and used for the DNS-01 challange and ExternalDNS.
-
When the script completes, run
kubectl get pods -A
to ensure everything deployed correctly.
Destroying is much simpler. Just run terraform destroy
from the project directory.
Yes, but you will need to modify the cluster issuers and ExternalDNS to work with a different DNS provider.
In theory yes but it will require the modules to be heavily rewritten.
This is not recommended. These modules are designed only for learning (e.g. using a GCP free trial).
Yes, in the "helm_releases" folder, add any additional Helm chart as a tf file containing a "helm_release" resource.
Yes, in the "kubernetes_manifests" folder, add any additional Kubernetes manifest as a tf file containing a "kubernetes_manifest" resource. Make sure the manifest is formatted as JSON, not YAML.
Apply an approriate Ingress resource for your service (see Kuberenets documentation) and add the following annotations:
annotations:
external-dns.alpha.kubernetes.io/hostname: "your.domain,*.your.domain" # MODIFY THIS
cert-manager.io/cluster-issuer: letsencrypt-prod # or letsencrypt-staging
The first annotation updates the DNS records using ExternalDNS. The second annotation uses cert-manager to provision a Let's Encrypt certificate (use either prod or staging).
I am getting an SSL/TLS error or redirect error while accessing my domain after applying the ingress resource. How can I solve this?
See Cloudflare Docs: ERR_TOO_MANY_REDIRECTS
It is recommended to set the SSL/TLS encryption mode in Cloudflare to Full
or Full (strict)
; if using a staging or self-signed certificate, use Full
. With a prod certificate, both modes can be used. If not using any certificate, use Cloudflare's "Flexible" mode.