Building a Robust CI/CD Pipeline with GitHub Actions and GCP

Continuous Integration and Continuous Deployment (CI/CD) pipelines are crucial for modern software development. They automate the testing, building, and deployment processes, ensuring rapid and reliable delivery of applications. In this blog, we’ll explore how to create a CI/CD pipeline using GitHub Actions, Google Cloud Platform (GCP) Artifact Registry, and deploying to Google Cloud Run and Cloud Batch across development, staging, and production environments.
Why CI/CD?
CI/CD eliminates manual errors, provides consistency, and allows teams to deploy applications faster and with confidence. Here’s why this setup is beneficial:
- Automation: Reduces repetitive tasks and human error.
- Consistency: Ensures the same process is followed for every deployment.
- Rapid Feedback: Quickly identifies and addresses issues.
- Scalability: Easily handles multiple environments like dev, staging, and production.
The Workflow
We’ll configure our CI/CD pipeline with the following:
- Development Environment (Dev): For testing new features.
- Staging Environment (Stg): For integration testing and user acceptance testing (UAT).
- Production Environment (Prd): For live deployments.
Each environment will have its own configuration and deployment process to ensure smooth transitions from one stage to the next.
Prerequisites
- Google Cloud Project: Set up a GCP project.
- Artifact Registry: Create a Docker Artifact Registry repository.
- Service Accounts: Create service accounts with appropriate permissions for pushing Docker images and deploying to Cloud Run/Batch.
- Dockerized Application: Ensure your Python application includes a Dockerfile.
- GitHub Secrets: Store sensitive information such as GCP credentials, project IDs, and registry URLs in GitHub Secrets.
Step 1: Dockerize Your Application
Start with a simple Dockerfile for your Python application:
FROM python:3.9-slim
WORKDIR /app
COPY . /app
RUN pip install --no-cache-dir -r requirements.txt
EXPOSE 8080
CMD ["python", "app.py"]
This Dockerfile creates a lightweight image for your application and exposes port 8080 for external access.
Step 2: Configure GitHub Actions for CI/CD
We’ll create three workflows to handle deployments to dev, stg, and prd environments. Each workflow uses GitHub Actions to automate the process.
Development Workflow
Create a .github/workflows/dev-deploy.yml
file:
name: Deploy to Dev
on:
pull_request:
branches:
- feature/*
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@master
with:
version: 'latest'
service_account_key: ${{ secrets.GCP_SERVICE_ACCOUNT_KEY_DEV }}
project_id: ${{ secrets.GCP_PROJECT_ID }}
- name: Configure Docker
run: |
gcloud auth configure-docker ${{ secrets.GCP_ARTIFACT_REGISTRY }}
- name: Build Docker image
run: |
docker build -t ${{ secrets.GCP_ARTIFACT_REGISTRY }}/python-app-dev:latest .
- name: Push Docker image to Artifact Registry
run: |
docker push ${{ secrets.GCP_ARTIFACT_REGISTRY }}/python-app-dev:latest
- name: Deploy to Cloud Run
run: |
gcloud run deploy ${{ secrets.GCP_CLOUD_RUN_SERVICE_DEV }} \
--image ${{ secrets.GCP_ARTIFACT_REGISTRY }}/python-app-dev:latest \
--platform managed \
--region us-central1 \
--allow-unauthenticated
This workflow is triggered by pull requests to feature branches and deploys the application to the dev environment.
Staging Workflow
Create a .github/workflows/stg-deploy.yml
file:
name: Deploy to Staging
on:
push:
branches:
- main
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@master
with:
version: 'latest'
service_account_key: ${{ secrets.GCP_SERVICE_ACCOUNT_KEY_STG }}
project_id: ${{ secrets.GCP_PROJECT_ID }}
- name: Configure Docker
run: |
gcloud auth configure-docker ${{ secrets.GCP_ARTIFACT_REGISTRY }}
- name: Build Docker image
run: |
docker build -t ${{ secrets.GCP_ARTIFACT_REGISTRY }}/python-app-stg:latest .
- name: Push Docker image to Artifact Registry
run: |
docker push ${{ secrets.GCP_ARTIFACT_REGISTRY }}/python-app-stg:latest
- name: Deploy to Cloud Run
run: |
gcloud run deploy ${{ secrets.GCP_CLOUD_RUN_SERVICE_STG }} \
--image ${{ secrets.GCP_ARTIFACT_REGISTRY }}/python-app-stg:latest \
--platform managed \
--region us-central1 \
--allow-unauthenticated
This workflow is triggered by pushes to the main
branch.
Production Workflow
Create a .github/workflows/prd-deploy.yml
file:
name: Deploy to Production
on:
push:
branches:
- production
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@master
with:
version: 'latest'
service_account_key: ${{ secrets.GCP_SERVICE_ACCOUNT_KEY_PRD }}
project_id: ${{ secrets.GCP_PROJECT_ID }}
- name: Configure Docker
run: |
gcloud auth configure-docker ${{ secrets.GCP_ARTIFACT_REGISTRY }}
- name: Build Docker image
run: |
docker build -t ${{ secrets.GCP_ARTIFACT_REGISTRY }}/python-app-prd:latest .
- name: Push Docker image to Artifact Registry
run: |
docker push ${{ secrets.GCP_ARTIFACT_REGISTRY }}/python-app-prd:latest
- name: Deploy to Cloud Run
run: |
gcloud run deploy ${{ secrets.GCP_CLOUD_RUN_SERVICE_PRD }} \
--image ${{ secrets.GCP_ARTIFACT_REGISTRY }}/python-app-prd:latest \
--platform managed \
--region us-central1 \
--allow-unauthenticated
This workflow is triggered by pushes to the production
branch.
Interactions Between Environments
- Development Phase:
- Developers create feature branches (e.g.,
feature/add-new-feature
). - Pull requests trigger the dev workflow for testing.
- Developers create feature branches (e.g.,
- Staging Phase:
- Approved pull requests are merged into the
main
branch, triggering the staging workflow. - Staging is used for integration testing and UAT.
- Approved pull requests are merged into the
- Production Phase:
- Once tested, a pull request is created to merge
main
intoproduction
. - Merging into
production
triggers the production workflow, deploying the application to live users.
- Once tested, a pull request is created to merge
Conclusion
This CI/CD pipeline ensures a smooth and automated process for deploying applications across dev, stg, and prd environments. By leveraging GitHub Actions and GCP, you can achieve fast, reliable, and scalable deployments, allowing your team to focus on delivering high-quality features.