yt coffee

Study hard, play harder.

Deploy AppEngine Apps Using CircleCI

  • 2019-01-18 05:00
  • #GCP

I have implemented continuous delivery of Google AppEngine applications using CircleCI:

  • Deploy to staging on pushing to master branch.
  • Deploy to production on pushing a tag matching /^v\d+\.\d+\.\d+$/.

This configuration is quite useful and I'm sure I'll have a chance to reuse it. In this article I describe the implementation details.

Create a Service Account

At first, I created a service account that will be used to authenticate Cloud SDK in CircleCI:

  1. Create a new account at Service Accounts of Google Cloud Platform Console:
    • Named "circleci" to make it easy to guess what is's for.
    • Created a key and download it in JSON.
  2. Attach roles to the created service account at IAM page:
    • App Engine Deployer (appengine.deployer)
    • App Engine Service Admin (appengine.serviceAdmin)
    • Cloud Build Editor (cloudbuild.builds.editor)
    • Storage Object Creator (storage.objectCreator)
    • Storage Object Viewer (storage.objectViewer)

Note that it may take a few minutes for the results to be reflected.

When you create a new GCP project, a xxx@cloudbuild.gserviceaccount.com service account which has a Cloud Build Service Account role is created. You also need to attach the following role to the service account:

  • Storage Object Viewer

Configure CircleCI

My GAE application uses nodejs10 runtime. I added following npm run scripts:

  • npm run test
    • Run tests
  • npm run build
    • Build project and put artifacts to the /build directory.

And I implemented CD using those scripts.

Cloud SDK

I use google/cloud-sdk image which was described in How to Use Google Cloud SDK Using Docker:

Set the downloaded JSON key as GCLOUD_SERVICE_KEY environment variable, then do following command to authenticate Cloud SDK:

echo $GCLOUD_SERVICE_KEY | gcloud auth activate-service-account --key-file=-

workspace

Build artifacts (generated by npm run build) are required to deploy.

Node.js is required to run npm command but the google/cloud-sdk image does not contain Node.js runtime. There are some way to solve this problem:

  1. Create a Docker image with both Node.js and Cloud SDK and use it.
  2. Store build artifacts somewhere and use it in the Cloud SDK container.

I started by 1. but finally found that I can use workspaces to share files across jobs so adopted 2.

Deploy

gcloud app deploy command deploys your application to GAE. I used the following options:

  • --version
    • Give the version name.
    • You can replace an existing version by specifing the same version name.
  • --no-promote
    • Don't route traffic to the newly created version after deployment.

Conclusion

You may think it's hard to set up continuous delivery in the early stages of a project. However, from a medium- to long-term perspective, I think these efforts are worthwhile.

References