Continuous Delivery in Google Cloud Platform — Cloud Build with App Engine
By: Ricardo Mendes
Tags: DevOps, Continuous Delivery, Google Cloud Platform, Cloud Build, App Engine

Agile and DevOps continue spreading among IT projects — and I would say: at a pace that we have never seen before! As the interest in these matters increases, the set of processes and tools which make it possible to deliver better software also increases.

At the end of the software development lifecycle is the delivery “phase”. And if the delivery is not fast, the whole Agile development process may be broken. Modern software should be designed to be fast delivered, using appropriate automation tools. In this context, I’ll write about Continuous Delivery in the Google Cloud Platform. It's a series of 3 articles, covering deployment to App Engine, Compute Engine, and Kubernetes Engine.

Starting with App Engine, GCP’s fully managed serverless application platform, I will show the steps to set up a development + automated build +continuous delivery pipeline. To keep it practical, we’ll create a very simple front-end application and deploy it to App Engine Standard Environment. Please remember we will focus on delivery and not on app development itself.

Before proceeding, make sure you have created a GCP Project and installed Google Cloud SDK in your machine if you wish to run the examples. Don’t forget to run gcloud auth login and gcloud config set project <your-project-id> for proper gcloud CLI usage.

A simple way to create a front-end web application is by using Angular CLI. The steps to install this tool are out of the scope of this article and can be found here. Once installed, cd to your preferred folder and type ng new <app-name> . Wait a few seconds. After the app is created, type cd <app-name> and ng serve . Point your browser to http://localhost:4200 and make sure the app is running. As we have a fully running app, we stop the development here ;). It’s time to think about delivery!

An Angular app is a set of HTML, CSS, JS, images, and other web-related static files. So, what we need to do now is to build the app and deploy it to an HTTP server in order to make it available to the users. To build the Angular app, we run npm install and npm run build --prod in the <app-name> folder. Angular CLI then creates a new dist folder, where it places the ready-to-deploy content. We could figure lots of ways to copy these files to the webserver, but following this path we are adding complexity to our build process, don’t you agree? As we desire simplicity and automation instead of complexity and manual tasks, we’ll learn how to use Cloud Build.

Cloud Build is a Google Cloud Platform fully-managed service that lets you build software quickly across all languages, counting on containers to get the job done. Having that said, let’s prepare our project to use Cloud Build. Add a file named cloudbuild.yaml to your project’s root folder, with the following content:

This simple file instructs Cloud Build on how to build and deploy the app, similar to a Docker multi-stage build. When we invoke Cloud Build using the command gcloud builds submit --config cloudbuild.yaml . , it will compress the project’s source files (a .gitignore file, if present, will be considered in order to determine which files shall be skipped), and copy the tarball to a managed Cloud Storage Bucket. It happens in your development machine.

Then, running on GCP servers, Cloud Build will uncompress the sources and execute npm install in a container of Cloud Build’s built-in image gcr.io/cloud-builders/npm . The second step will use another npm container to run npm run build --prod . The third one will run a container of another Cloud Build’s built-in image, named gcr.io/cloud-builders/gcloud , to execute a gcloud app deploy command.

I've already talked about the 1st and 2nd steps, but not about the 3rd one, gcloud app deploy , so let me do it. This command is responsible for deploying the built content to App Engine and finish the whole delivery process. In order to succeed it requires an app.yaml file in the project’s root folder (see sample content below), the <your-project-number>@cloudbuild.gserviceaccount.com Service Account must have the App Engine Admin role, and the App Engine Admin API must be enabled for the GCP Project in which the app will be deployed. This step replaces copying the built files to an HTTP server — mentioned before — with copying them to GAE Python 2.7 Standard Environment, where they can be served as static content.

Point your browser to https://<your-project-id>.appspot.com or click a service's name in Cloud Console to see the app running on App Engine! Also, visit https://console.cloud.google.com/cloud-build/builds?project=<your-project-id> to check your project’s build history.

App Engine Services page (Cloud Console > Compute > App Engine > Services)

Ok, now we have an almost fully automated deployment process.

— Hey, Ricardo, what do you mean by “almost fully automated”? — I mean GCP can help us doing better than this :).

We have seen how Cloud Build interoperates with Cloud Storage and App Engine, but there’s a missing piece: Source Repositories.

Git is widely used as a source control management tool nowadays. Source Repositories allow you to use GCP as a Git remote repository or to automatically mirror repositories from Github or Bitbucket. Visit https://console.cloud.google.com/code/develop/repo?project=<your-project-id> , click CREATE REPOSITORY, and follow the steps — it’s pretty straightforward.

Once the repository is set, navigate to Cloud Build’s triggers page: https://console.cloud.google.com/cloud-build/triggers?project=<your-project-id> . Click ADD TRIGGER, select a source, a repository, and proceed to trigger settings. Give a name to the trigger, let's say Push to master branch , select Branch as the Trigger type, type master as the Branch (regex), and select cloudbuild.yaml as the Build configuration. Type /cloudbuild.yaml for the cloudbuild.yaml location and save. And here we go: every time a new commit is pushed to master, the build process is automatically triggered. We don’t need to manually execute gcloud builds submit … to trigger the build anymore. The deployment process is now fully automated!

The steps described in this article can be used or customized to deploy any kind of application supported by Google Cloud Platform’s App Engine Standard Environment. Deploying to Flexible Environment requires changes in folders' structure.

The sample code is available on Github: https://github.com/ricardolsmendes/gcp-cloudbuild-gae-angular. Feel free to fork it and play.

Happy deploying :)