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:
Separation of duties and responsibilities among team members & projects
Granular and detailed separate billing for CI/CD operations tasks and maintenance
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
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 .
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
Similarly, you would be able to enable Cloud Build also from the google cloud console
3. On Project-B enable cloud run service
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
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
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.
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.