Skip to content

epiphone/gke-terraform-example

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Google Kubernetes Engine full-stack example

CircleCI

An example of deploying a web app on GKE. Consists of

  • GKE cluster with a single node pool
  • Cloud SQL Postgres instance with private networking
    • connects to GKE through a private IP, ensuring traffic is never exposed to the public internet
  • Cloud Storage and Cloud CDN for serving static assets
  • Cloud Load Balancing routing /api/* to GKE and the rest to the static assets bucket
  • Cloud DNS for domain management
    • check ROOT_DOMAIN_NAME_<ENV> below
  • Terraform-defined infrastructure
  • CircleCI pipeline
    • push to any non-master branch triggers dev deployment & push to master branch triggers test deployment
    • prod deployment triggered by an additional approval step at CircleCI UI

architecture sketch

Setup

The following steps need to be completed manually before automation kicks in:

  1. Create a new Google Cloud project per each environment
  2. For each Google Cloud project,
    • set up a Cloud Storage bucket for storing remote Terraform state
    • set up a service IAM account to be used by Terraform. Attach the Editor and Compute Network Agent roles to the created user
  3. Set environment variables in your CircleCI project (replacing ENV with an uppercase DEV, TEST and PROD):
    • GOOGLE_PROJECT_ID_<ENV>: env-specific Google project id
    • GCLOUD_SERVICE_KEY_<ENV>: env-specific service account key
    • DB_PASSWORD_<ENV>: env-specific password for the Postgres user that the application uses
    • ROOT_DOMAIN_NAME_<ENV>: env-specific root domain name, e.g. dev.example.com
    • K8S_MASTER_ALLOWED_IP: IP from which to access cluster master's public endpoint, i.e. the IP where you run kubectl at (read more)
      • In CircleCI we temporarily whitelist the test host IP in order to run kubectl
  4. Enable the following Google Cloud APIs:
    • cloudresourcemanager.googleapis.com
    • compute.googleapis.com
    • container.googleapis.com
    • containerregistry.googleapis.com
    • dns.googleapis.com
    • servicenetworking.googleapis.com
    • sqladmin.googleapis.com

You might also want to acquire a domain and update your domain registration to point to Google Cloud DNS name servers.

Manual deployment

You can also sidestep CI and deploy locally:

  1. Install terraform, gcloud and kubectl
  2. Login to Google Cloud: gcloud auth application-default login
  3. Update infra: cd terraform/dev && terraform init && terraform apply
  4. Follow instructions on building and pushing a Docker image to GKE:
    • cd app
    • export PROJECT_ID="$(gcloud config get-value project -q)"
    • docker build -t gcr.io/${PROJECT_ID}/gke-app:v1 .
    • gcloud docker -- push gcr.io/${PROJECT_ID}/gke-app:v1
  5. Authenticate kubectl: gcloud container clusters get-credentials $(terraform output cluster_name) --zone=$(terraform output cluster_zone)
  6. Render Kubernetes config template: terraform output k8s_rendered_template > k8s.yml
  7. Update Kubernetes resources: kubectl apply -f k8s.yml

Read here on how to connect to the Cloud SQL instance with a local psql client.

Further work

  • Cloud SQL high availability & automated backups
  • regional GKE cluster
  • GKE autoscaling
  • Cloud Armor DDoS protection
  • SSL
  • tune down service accounts privileges
  • possible CI improvements: