Terraform configuration for deploying a Kubernetes cluster in the Google Kubernetes Engine (GKE) in the Google Cloud Platform (GCP).
- Public cluster on GKE.
- Ability to use preemptible VM instances for cluster nodes. Note that you need to have at least 3 nodes (throughout all zones) to minimize cluster downtime.
gcloud auth login
gcloud config set account $ACCOUNT
gcloud projects create $PROJECT_ID [--name=$NAME] [--organization=$ORGANIZATION_ID]
gcloud alpha billing accounts list
gcloud alpha billing projects link $PROJECT_ID --billing-account $BILLING_ACCOUNT_ID
gcloud config set project $PROJECT_ID
gcloud services enable compute.googleapis.com
gcloud services enable container.googleapis.com
gcloud services enable storage-component.googleapis.com
gcloud iam service-accounts create terraform-sa --display-name "Terraform Service Account"
gcloud projects add-iam-policy-binding $PROJECT_ID --member serviceAccount:terraform-sa@$PROJECT_ID.iam.gserviceaccount.com --role roles/editor
gcloud iam service-accounts keys create ~/key.json --iam-account terraform-sa@$PROJECT_ID.iam.gserviceaccount.com
gsutil mb -l us-central1 gs://terraform-state-storage/
export GOOGLE_APPLICATION_CREDENTIALS="~/key.json"
terraform init -backend-config "bucket=terraform-state-storage" -backend-config "prefix=cluster/example"
terraform apply
gcloud container clusters get-credentials $CLUSTER_NAME
helm init
kubectl create serviceaccount --namespace kube-system tiller
kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
kubectl patch deploy --namespace kube-system tiller-deploy -p "{\"spec\":{\"template\":{\"spec\":{\"serviceAccount\":\"tiller\"}}}}"The following prerequisites need to be installed and configured:
- Terraform
- Google Cloud SDK (run
gcloud components updateto update SDK to the latest version if you have it already installed)
Make sure you are logged in to a correct Google account. To list all available accounts, run:
gcloud auth listTo login to a new account, run:
gcloud auth loginTo set the active account, run:
gcloud config set account $ACCOUNT$ACCOUNTshould be replaced with the account's e-mail.
Optionally create a new GCS project for your deployment:
gcloud projects create $PROJECT_ID [--name=$NAME] [--organization=$ORGANIZATION_ID]$PROJECT_IDshould be replaced with the ID of the project to create.$NAMEis an optional, and should be replaced with the name of the project to create.$ORGANIZATION_IDis an optional, and should be replaced with the ID of your organization.
Run the following command to check whether the project succesfully created:
gcloud projects listIn order to be able to use Compute Engine and/or Kubernetes Engine, you need to enable billing for a new project either via Google Cloud Console, or using the following command:
gcloud alpha billing projects link $PROJECT_ID --billing-account $BILLING_ACCOUNT_ID$PROJECT_IDshould be replaced with the ID of the project you created.$BILLING_ACCOUNT_IDshould be replaced with the ID of the billing account to link to the project.
Run following command to list all your billing accounts:
gcloud alpha billing accounts listNOTE To be able to run
gcloud alphacommand you need to have gcloud Alpha Commands component installed. Usegcloud components listto list all available components.gcloud components install alphato install Alpha Commands component.
Set the project you created as an active:
gcloud config set project $PROJECT_ID$PROJECT_IDshould be replaced with the ID of the project you've created.
Enable Compute, Kubernetes, and Cloud Storage engines for the project:
gcloud services enable compute.googleapis.com
gcloud services enable container.googleapis.com
gcloud services enable storage-component.googleapis.comCreate a Service Account for Terraform, and grant it the Editor role.
gcloud iam service-accounts create terraform-sa --display-name "Terraform Service Account"
gcloud projects add-iam-policy-binding $PROJECT_ID --member serviceAccount:terraform-sa@$PROJECT_ID.iam.gserviceaccount.com --role roles/editorCreate service account keys:
gcloud iam service-accounts keys create ~/key.json --iam-account terraform-sa@[$PROJECT_ID].iam.gserviceaccount.com$PROJECT_IDshould be replaced with the ID of the project you've created.
Set the value of GOOGLE_APPLICATION_CREDENTIALS environment variable to a path of the generated key file.
For example (Windows PowerShell):
$env:GOOGLE_APPLICATION_CREDENTIALS = "~/key.json"Create GCS bucket for storing the Terraform state in a central remote location:
gsutil mb -l $REGION gs://$BUCKET_NAME/$REGIONshould be replaced with a region name, for exampleus-central1. Refer to documentation for more information.$BUCKET_NAMEshould be replaced with a globally unique bucket name.
Copy terraform.tfvars.example file to terraform.tfvars and set input variables values as per your needs. Then initialize Terraform with init command:
terraform init -backend-config "bucket=$BUCKET_NAME" -backend-config "prefix=cluster/$CLUSTER_NAME" -backend-config "region=$REGION"$REGIONshould be replaced with a region name.$CLUSTER_NAMEshould be replaced with the name of a cluster.$BUCKET_NAMEshould be replaced with a GCS Terraform state storage bucket name.
To apply Terraform plan, run:
terraform applyAt the time of writing, Kubernetes Terraform provider has a problem of creating new StorageClass resource. There is no way to specify which cluster this resource should go in, and it gets created in the default cluster. Therefore you may get the following error message:
Error: storageclasses.storage.k8s.io "fast" already exists
on main.tf line 171, in resource "kubernetes_storage_class" "fast":
171: resource "kubernetes_storage_class" "fast" {In this case you need to switch to the newly created cluster first:
kubectl config use-context $CLUSTER_NAMEand run terraform apply again.
To authenticate to the newly created cluster, run:
gcloud container clusters get-credentials $CLUSTER_NAME$CLUSTER_NAMEshould be replaced with a name of the cluster.
To view general cluster information, run:
kubectl cluster-infoInstall Helm to the Kubernetes cluster:
helm initCreate service account and grant admin role to Tiller (Helm server component):
kubectl create serviceaccount --namespace kube-system tiller
kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
kubectl patch deploy --namespace kube-system tiller-deploy -p "{\"spec\":{\"template\":{\"spec\":{\"serviceAccount\":\"tiller\"}}}}"Happy Kuberneting!