A containerised Hello World! application created and deployed into GCP using Cloud Native services
Forked from GoogleCloudPlatform/gke-gitops-tutorial-cloudbuild
This repository contains the code used in the GitOps-style Continuous Delivery with Cloud Build tutorial.
Directory | Purpose |
---|---|
/application | Python HelloWorld application, and the CloudBuild build file that containerises it and upload the resulting image to Google Container Registry |
/application/test/unit/ | A basic unit test example that is run during application deployment |
/builders | Code to build a CloudBuild Builder for Terraform |
/infrastructure | Infrastructure definition in Terraform language, and CloudBuild build files to create and destroy |
/infrastructure/tfvars | Environment-specific variables |
/images | Screenshots of the build process |
This repository contains the Infrastructure-as-Code definition for a containerised HelloWorld application.
Using cloud-native GCP services has been a main priority. I've tried to create a solid infrastructure as code repository using as many GCP cloud-native technologies as possible. This is the reason why I have chosen CloudBuild over Jenkins and Groovy pipelines.
However instead of using Deployment Manager (Google's IaC Service), I have implemented the infrastructure in Terraform for now. The infrastructure has been defined in Terraform files with the remote state for each built project stored in a Storage Bucket in GCS in the orchestrating project, with versioning enabled.
There are three environment definitions for the infrastructure (dev,test,and prod) which in turn will be three separate GCP projects.
The application and infrastructure are built from a central orchestrating GCP project using Google Cloud Build. CloudBuild is connected to Github via the Google Cloud Build App which handles the CloudBuild Triggers. At present builds are kicked off when changes are detected to specific files within the three main directories. In each case the corresponding cloudbuild*.yaml file is executed.
The build process uses many predefined builders but also includes a Community Terraform Cloud Builder which has been built in the orchestrating project, using Terraform 0.12.20 and the code in the /builders directory.
Pipelines are defined in cloudbuild*.yaml files are comprised of steps run in "builders" which purpose-specific containers. These pipelines are triggered when certain changes are detected on the repository. These rules are specified in CloudBuild Triggers.
The application and Terraform builder have been built beforehand so the infrastructure build can pull them from the Container Registry in the orchestrating project.
The GCP Free account does not create an Organization which prevents you from creating folders and also from having the projectCreator permission. Due to this limitation, despite the projects being defined in IaC, I had to manually create them and then import them into the terraform state.
The CloudBuild account in the orchestrator project has, by default, limited permissions, and it has been necessary to add additional permissions on the projects that were created by the Orchestrator project.
docker run -it --entrypoint /bin/bash gcr.io/grb-gcp-devops/terraform:latest
git clone https://github.com/gustavoromerobenitez/grb-gcp-devops-helloworld.git
cd grb-gcp-devops-helloworld/infrastructure/
terraform init -input=false -var-file=tfvars/dev.tfvars -backend-config=bucket=grb-gcp-devops-terraform -backend-config=prefix=terraform/k8s-tf-dev/state/
terraform import -var-file=tfvars/dev.tfvars google_project.current-project projects/k8s-tf-dev
var.environment
The environment this project belongs to
Enter a value: dev
var.project-base-name
GCP Project Common Name without the environment suffix
Enter a value: k8s-tf
google_project.current-project: Importing from ID "projects/k8s-tf-dev"...
google_project.current-project: Import prepared!
Prepared google_project for import
google_project.current-project: Refreshing state... [id=projects/k8s-tf-dev]
Import successful!
The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.
I registered a domain called grbdevops.net and added CNAMEs but it does not seem to have worked and I haven't been able to troubleshoot this yet.
The GKE cluster should be changed into regional:
The Kubernetes cluster is not private at the moment. In order to be able to build from CLoudBuild, master_authorized_networks should be configured, and if that does not work, perhaps it would be required to use a Proxy as described in the following article:
https://cloud.google.com/kubernetes-engine/docs/how-to/private-clusters https://cloud.google.com/solutions/creating-kubernetes-engine-private-clusters-with-net-proxies
The GKE cluster creation could be converted into a terraform module