Deploying a large-scale App Engine application containing independent services (like default, telemetry-api, and cron-workers) is prone to errors when run manually. If service configurations are updated or deployed out of order, downstream services can experience outages. Automating deployments through a Continuous Integration and Continuous Deployment (CI/CD) pipeline ensures that code is built, tested, and deployed securely and repeatably.
By scripting GitLab CI runner templates, we can orchestrate multi-service deployments using the Google Cloud SDK.
1. Structuring the GitLab CI Configuration
We create a .gitlab-ci.yml pipeline that registers authentication credentials and deploys modified services sequentially:
# .gitlab-ci.yml
stages:
- test
- deploy-staging
- deploy-production
variables:
GCP_PROJECT_ID: "my-app-engine-project"
before_script:
# Authenticate with Google Cloud using Service Account keys
- echo "$GCP_SERVICE_KEY" > /tmp/gcp-key.json
- gcloud auth activate-service-account --key-file=/tmp/gcp-key.json
- gcloud config set project $GCP_PROJECT_ID
run_unit_tests:
stage: test
image: python:3.9-slim
script:
- pip install -r requirements.txt
- pytest tests/
deploy_telemetry_service:
stage: deploy-production
image: google/cloud-sdk:alpine
only:
- main
script:
# Deploy service yaml configs
- gcloud app deploy services/telemetry/app.yaml --quiet --no-promote
# Run canary checks before routing traffic
- gcloud app services set-traffic telemetry --splits="v2=1"
- gcloud app deploy services/telemetry/app.yaml --quiet --promote
2. Managing Shared Cron and Dispatch Rules
Deploying application routing patterns requires pushing cron.yaml and dispatch.yaml. The pipeline pushes these configurations only after backend code is verified online, preventing routing calls to unavailable versions.