CI/CD pipeline using Cloud Build across projects

Being compliant with separation of duties among teams, in a large enterprise cloud environment is quite a challenge to achieve, we at Evonence are excited about demonstrating Cloud Run CI/CD pipeline across multiple projects using cloud build adhering to Google Cloud Platform’s best practices.

Benefits of proposed solution: 

  1. Separation of duties and responsibilities among team members & projects

  2. Granular and detailed separate billing for CI/CD operations tasks and maintenance

GCP Architecture

Prerequisites

  • Container compatible code in source repository ( in this we would be using GCP Source Repository ) 

  • At least 2 Google Cloud Projects with billing enabled 

  • Cloud Build & Cloud Run API enabled in GCP projects 

Begin here

  1. Create a repository in Github to host code

In this we are going to have a sample applications of Node.js with 3 files index.js, Dockerfile & cloudbuild.yaml

cd nodejs-helloworld

tree .

sample applications of Node.js

gcloud init && git config --global credential.https://source.developers.google.com.helper gcloud.sh

git remote add google https://source.developers.google.com/p/shared-ops-354608/r/nodejs-helloworld

git push --all google


2. Enable Cloud build and Artifact registry API in Project A, commands for same is as below

Cloud build and Artifact registry API

Same can be done from google cloud console left menu , select APIs & Services > Enable APIs & Services , search Artifact registry and click enable

Artifact Registry API

Similarly, you would be able to enable Cloud Build also from the google cloud console

3. On Project-B enable cloud run service 

Cloud Run API

Alternatively same can be done using below command line 

gcloud services enable run.googleapis.com 

4. Access arrangement, post API enable GCP creates service accounts. To view the same go to Project-A > left menu IAM & Admin > IAM enable Include Google-provided role grants 

The account usually follows the below pattern 

service-<PROJECT-A-ID>@gcp-sa-cloudbuild.iam.gserviceaccount.com it comes with a role as Cloud Build Service Agent 

Gcloud Permission for Project

To use above agent a service account gets created as <PROJECT-A-ID>@cloudbuild.gserviceaccount.com with permissions as below

Artifact Service account

Artifact Registry service account comes with its own roles/permissions as Artifact Registry Service Agent

Artifact Registry Service Agent

Project-B , where cloud run service is enabled will get service account as service-<PROJECT-B-ID>@serverless-robot-prod.iam.gserviceaccount.com

Cloud Run deployment


5.To enable cross project cloud run deployment, facilitate Artifact Reader & Storage Object Viewer role to service-<PROJECT-B-ID>@serverless-robot-prod.iam.gserviceaccount.com account from Project-B in Project-A

Open the Project-A that owns the Artifact registry from where container images will be used.
Go to the IAM & Admin > IAM page > Click Add to add a new principal.In the New principals text box, paste in the email of the service account from Project-B i.e.  service-<PROJECT-B-ID>@serverless-robot-prod.iam.gserviceaccount.com

In the Select a role dropdown list, select the role Artifact Registry -> Artifact Registry Reader. (if you are using Container Registry, select the role Storage -> Storage Object Viewer.) Click Save. 

The below image shows details of the same, for ease, both Artifact & Container Registry read role is given

Artifact & Container registry

6. Now as next step in permissions/role management, get <PROJECT-A-ID>@cloudbuild.gserviceaccount.com and grant Cloud Run Developer and Service Account User roles by using the pencil icon in front of user listed on IAM & Admin > IAM page of Project-B. 

CloudRun Developer

As <PROJECT-A-ID>@cloudbuild.gserviceaccount.com has to use Cloud Run Service user of Project-B, update <PROJECT-B-ID>@cloudbuild.gserviceaccount.com account with Service Account Token Creator role, It would look as below

Cloud Run Services

<PROJECT-A-ID>@cloudbuild.gserviceaccount.com will impersonate as <PROJECT-B-ID>@cloudbuild.gserviceaccount.com to perform a cloud run deployment operation initiated from Project-A.

7. Lets look into cloudbuild.yaml quickly

steps:

- name: 'gcr.io/cloud-builders/docker'

  args: 

    - build

    - --tag=us-central1-docker.pkg.dev/${PROJECT_ID}/cloud-run-source-deploy/nodejs-helloworld:1.0.0

    - .

# Docker push to Google Artifact Registry

- name: 'gcr.io/cloud-builders/docker'

  args: 

    - push

    - us-central1-docker.pkg.dev/${PROJECT_ID}/cloud-run-source-deploy/nodejs-helloworld:1.0.0

# Deploy to Cloud Run

- name: google/cloud-sdk

  args: 

    - gcloud

    - run

    - deploy

    - nodejs-helloworld

    - --image=us-central1-docker.pkg.dev/${PROJECT_ID}/cloud-run-source-deploy/nodejs-helloworld:1.0.0

    - --region=us-central1

    - --project=${PROJECT-B-ID}

In the above cloudbuild.yaml file us-central1-docker.pkg.dev represents artifact registry cloud-run-source-deploy represents artifact repository present in Project-A to manage container images

This cloudbuild.yaml file has 2 substitutions, 

  • ${PROJECT_ID} : this is cloud build inbuilt substitution which takes Project-A’s ID from environment variables 

  • ${PROJECT-B-ID} : this is user-provided substitution where Project-B ID would be passed to have this deployment on Project-B

8. Now go back to Project-A and execute below command 

gcloud builds submit --substitutions=PROJECT-B-ID=<Project-B ID>

You can further configure triggers on Project-A based on events like Push to a branch, Push new tag and Pull request to have automated build and deployment. 

For Production projects where the environment is more secure additional Build approval can also be configured on Cloud Build triggers. 

Previous
Previous

Evonence, Google Cloud partner Ranks No. 1300 on the 2022 Inc. 5000 Annual List

Next
Next

Nine9 goes Google Workspace