Monday, April 15, 2024
No menu items!
HomeCloud ComputingCl/CD for Gitlab repositories with Cloud Build repositories Gen2

Cl/CD for Gitlab repositories with Cloud Build repositories Gen2

The trailhead for any path to production starts at source control. The integration of Cloud Build, as the automation tool, with the source repository is therefore crucial to increasing the delivery speed and ultimately becoming a high-performing organization.

In this article we look at two exciting new capabilities of the recently launched second generation of Cloud Build repositories. First, Cloud Build can now connect to source code repositories in Gitlab and Gitlab Enterprise. And second, repository connections can now be managed declaratively in Terraform. We will now dive into a simple end-to-end demonstration to experience both of these features.

Preparing the Gitlab Environment

For our demo we use a private repository that is hosted on Gitlab.com. If you already have a Gitlab repository with a Cloud Build configuration, you can set the GITLAB_REPO_URI variable to the HTTPS URI of your repository and continue with the next section.

To create a minimal Gitlab repository to experiment with Cloud Build you can perform the following steps:

Create a private repo in Gitlab.com. I am using cloud-build-demo as the name here.

Store the repo URI as the variable GITLAB_REPO_URI in my case this is: GITLAB_REPO_URI=’https://gitlab.com/<USER>/cloud-build-demo.git’ (you can use ssh for the local clone to the workstation but we’ll use HTTPS for the Cloud Build Repository below

In a terminal (e.g. cloud shell or locally) initialize the repository with a cloudbuild.yaml config as follows:

code_block[StructValue([(u’code’, u’mkdir cloud-build-demo && cd cloud-build-demorncat <<EOF >cloudbuild.yamlrnsteps:rn – name: ubunturn id: just a demorn args:rn – echorn – Probably the world’s simplest pipeline.rnEOFrngit init –initial-branch=mainrngit remote add gitlab $GITLAB_REPO_URIrngit add .rngit commit -m “initial import”rngit push -u gitlab main’), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3eac184423d0>)])]

You should now see your repository content (in our case just the cloudbuild.yaml file) in the Gitlab web UI.

Preparations in Google Cloud

To get started we need to ensure that our Google Cloud project has the necessary APIs for Cloud Build and Secret Manager enabled on the project. Our example requires us to add the two services to a Terraform configuration or to run the following commands in a terminal:

code_block[StructValue([(u’code’, u’export PROJECT_ID=<my-project-id-here>rngcloud services enable cloudbuild.googleapis.com secretmanager.googleapis.com –project $PROJECT_ID’), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3eac18442e90>)])]

Cloud Build repositories are authenticated at the level of a so-called host connection. The authentication process of a host connection is specific to the source code repository and differs slightly between Gitlab and Github. For host connection to access repositories in Gitlab you need to issue personal access tokens for both the api and read-api scope as described in the document Connect to a GitLab host.

Once you have issued the tokens you can store them as environment variables GITLAB_API_TOKEN and GITLAB_READ_API_TOKEN and run the command below to create secrets in Secret Manager. If you look closely you’ll find that we will also create the required secret for Gitlab webhooks but we won’t use them for this demo. In a last step we also authorize the Cloud Build Service Agent to use the secrets that we just created such that it can establish the host connection.

Note: You could create these secrets in Terraform as well but the plain text values will be visible in your tf state.

code_block[StructValue([(u’code’, u’GITLAB_API_TOKEN=’### SET TOKEN HERE ###’rnGITLAB_READ_API_TOKEN=’### SET TOKEN HERE ###’rnrngcloud secrets create gitlab-api-token \rn –replication-policy=”automatic” –project=$PROJECT_IDrnecho -n “$GITLAB_API_TOKEN” | \rn gcloud secrets versions add gitlab-api-token –project=$PROJECT_ID –data-file=-rnGITLAB_API_TOKEN_SECRET_REF=$(gcloud secrets versions list gitlab-api-token –format json | jq -r ‘.[0].name’)rnrngcloud secrets create gitlab-read-token \rn –replication-policy=”automatic” –project=$PROJECT_IDrnecho -n “$GITLAB_READ_API_TOKEN” | \rn gcloud secrets versions add gitlab-read-token –project=$PROJECT_ID –data-file=-rnGITLAB_READ_API_TOKEN_SECRET_REF=$(gcloud secrets versions list gitlab-read-token –format json | jq -r ‘.[0].name’)rnrngcloud secrets create gitlab-webhook-token \rn –replication-policy=”automatic” –project=$PROJECT_IDrnecho -n “not-used-here” | \rn gcloud secrets versions add gitlab-webhook-token –project=$PROJECT_ID –data-file=-rnGITLAB_WEBHOOK_TOKEN_SECRET_REF=$(gcloud secrets versions list gitlab-webhook-token –format json | jq -r ‘.[0].name’)rnrnPROJECT_NUMBER=”$(gcloud projects describe “$PROJECT_ID” –format=”value(projectNumber)”)”rnCLOUD_BUILD_SA_MEMBER=”serviceAccount:service-$PROJECT_NUMBER@gcp-sa-cloudbuild.iam.gserviceaccount.com”rngcloud secrets add-iam-policy-binding gitlab-api-token –member=$CLOUD_BUILD_SA_MEMBER –role=roles/secretmanager.secretAccessor –project=$PROJECT_IDrngcloud secrets add-iam-policy-binding gitlab-read-token –member=$CLOUD_BUILD_SA_MEMBER –role=roles/secretmanager.secretAccessor –project=$PROJECT_IDrngcloud secrets add-iam-policy-binding gitlab-webhook-token –member=$CLOUD_BUILD_SA_MEMBER –role=roles/secretmanager.secretAccessor –project=$PROJECT_ID’), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3eac18442690>)])]

Configuring the Cloud Build Repository and triggers with Terraform

With the authentication credentials configured in Secret Manager we can move on to the Terraform configuration. For simplicity we put everything in a single main.tf file that looks as follows:

code_block[StructValue([(u’code’, u’variable “project_id” {rn type = stringrn}rnrnvariable “gitlab_api_token_secret” {rn type = stringrn}rnrnvariable “gitlab_read_api_token_secret” {rn type = stringrn}rnrnvariable “gitlab_webhook_token_secret” {rn type = stringrn}rnrnvariable “gitlab_repo_uri” {rn type = stringrn}rnrnvariable “build_location” {rn type = stringrn default = “europe-west1″rn}rnrnprovider “google” {rn project = var.project_idrn}rnrnresource “google_cloudbuildv2_connection” “gitlab-connection” {rn location = var.build_locationrn name = “gitlab-connection”rnrn gitlab_config {rn authorizer_credential {rn user_token_secret_version = var.gitlab_api_token_secretrn }rn read_authorizer_credential {rn user_token_secret_version = var.gitlab_read_api_token_secretrn }rn webhook_secret_secret_version = var.gitlab_webhook_token_secretrn }rn}rnrnresource “google_cloudbuildv2_repository” “demo-repo” {rn name = “gitlab-demo-repo”rn location = var.build_locationrn parent_connection = google_cloudbuildv2_connection.gitlab-connection.idrn remote_uri = var.gitlab_repo_urirn}rnrnresource “google_cloudbuild_trigger” “demo-trigger” {rn location = var.build_locationrn repository_event_config {rn repository = google_cloudbuildv2_repository.demo-repo.idrn push {rn branch = “.*”rn }rn }rn filename = “cloudbuild.yaml”rn}’), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3eac18442310>)])]

We provide variables for the Google Cloud project ID, references to the externally created secrets in Secret Manager, and an optional location override for the Cloud Build resources.

The Cloud Build specific Terraform resources are:

google_cloudbuildv2_connection to specify the host connection with a name, region and the credentials. Host connections can be used by multiple repositories so the credentials can be managed centrally.

google_cloudbuildv2_repository to specify the Gitlab repo we want to use and associate it with a host connection. This requires that the host connections’ credentials have access to the repository specified as remote_uri.

google_cloudbuild_trigger to run the Cloud Build pipeline on push events on any branch in the Gitlab repository.

To apply the Terraform configuration we execute the following two commands from within the folder that contains our main.tf file:

code_block[StructValue([(u’code’, u’terraform initrnterraform apply \rn –var=project_id=”$PROJECT_ID” \rn –var=gitlab_api_token_secret=”$GITLAB_API_TOKEN_SECRET_REF” \rn –var=gitlab_read_api_token_secret=”$GITLAB_READ_API_TOKEN_SECRET_REF” \rn –var=gitlab_webhook_token_secret=”$GITLAB_WEBHOOK_TOKEN_SECRET_REF” \rn –var=gitlab_repo_uri=$GITLAB_REPO_URI’), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3eac182b3f90>)])]

Once the resources are created, we can see them in the Google Cloud Console under Cloud Build > Repositories:

To test our simple pipeline and the repo trigger we can push an empty commit to our sample repo:

code_block[StructValue([(u’code’, u’cd cloud-build-demorngit commit -m “trigger pipeline” –allow-emptyrngit push -u gitlab main’), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3eac15476050>)])]

In the Cloud Build dashboard in the Google Cloud Console you can see the build that was kicked off.

The same result is visible in the Gitlab UI under Builds > Pipelines.

Next steps

You can find more information about Cloud Build repositories and a side by side comparison of the features of the Gen 1 and Gen 2 repositories in the official Cloud Build repositories documentation. If you are planning to use Cloud Build with a Git repository hosted on GitHub, you should follow these instructions for your Terraform configuration.

Cloud BlogRead More

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments