Configure User-Specified Service Accounts for GCP Cloud Build

Configure User-Specified Service Accounts for GCP Cloud Build

Step-by-step: Configure secure GCP Cloud Build using Terraform, GitHub CI/CD, and custom service accounts.


In a move towards enhanced security and granular control, Google Cloud Platform (GCP) has recently shifted its Cloud Build service away from the default service account.

This change encourages users to specify custom service accounts when triggering builds, empowering you to enforce least-privilege principles and tighten your CI/CD pipeline's security posture.

In this blog post, I will guide you through configuring custom service accounts for Cloud Build using Terraform and YAML files within the robust GitHub Actions CI/CD framework.

Prerequisites

  • A Google Cloud Platform account with billing enabled.

  • Terraform installed on your machine.

  • A service account with the necessary permissions to trigger a cloudbuild job.

  • A Github account.

Setup

Step 1: Enable the Cloud Build API

Navigate to the Cloud Build API and enable it.

Step2: Create a Terraform file

Create a main.tf file in the root of your repository with the following content.


data "google_project" "project" {}

resource "google_cloudbuild_trigger" "service-account-trigger" {
  trigger_template {
    branch_name = "main"
    repo_name   = "my-repo"
  }

  service_account = google_service_account.cloudbuild_service_account.id
  filename        = "cloudbuild.yaml"
  depends_on = [
    google_project_iam_member.act_as,
    google_project_iam_member.logs_writer
  ]
}

resource "google_service_account" "cloudbuild_service_account" {
  account_id = "cloud-sa"
}

resource "google_project_iam_member" "act_as" {
  project = data.google_project.project.project_id
  role    = "roles/iam.serviceAccountUser"
  member  = "serviceAccount:${google_service_account.cloudbuild_service_account.email}"
}

resource "google_project_iam_member" "logs_writer" {
  project = data.google_project.project.project_id
  role    = "roles/logging.logWriter"
  member  = "serviceAccount:${google_service_account.cloudbuild_service_account.email}"
}

Step 3: Create a key for the service account


gcloud iam service-accounts keys create [KEY_FILE] \
  --iam-account=[SA-EMAIL]

Step 4: Store the key in Github secrets

Navigate to your Github repository and go to Settings > Secrets and add the key as a secret.

Step 5: Create a cloudbuild.yaml file

Create a cloudbuild.yaml file in the root of your repository with the following content.

steps:
  # Docker Build
  - name: 'gcr.io/cloud-builders/docker'
    args: ['build', '-t', 
           'us-central1-docker.pkg.dev/${PROJECT_ID}/my-docker-repo/myimage', 
           '.']

  # Docker Push
  - name: 'gcr.io/cloud-builders/docker'
    args: ['push', 
           'us-central1-docker.pkg.dev/${PROJECT_ID}/my-docker-repo/myimage']

  # Entrypoint, timeout and environment variables
  - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
    entrypoint: 'gcloud'
    timeout: 240s
    args: ['compute', 'instances', 
           'create-with-container', 'my-vm-name',
           '--container-image', 
           'us-central1-docker.pkg.dev/${PROJECT_ID}/my-docker-repo/myimage']
    env:
      - 'CLOUDSDK_COMPUTE_REGION=us-central1'
      - 'CLOUDSDK_COMPUTE_ZONE=us-central1-a'

Step 6: Create a Github workflow

Create a .github/workflows/main.yml file in the root of your repository with the following content.


name: Trigger cloudbuild job

on:
  push:
    branches:
      - main

jobs:
    trigger:
        runs-on: ubuntu-latest
        steps:
        - name: Checkout
            uses: actions/checkout@v2

        - name: Set up gcloud
            uses: google-github-actions/setup-gcloud@v0.2.0
            with:
            service_account_key: ${{ secrets.SERVICE_ACCOUNT_KEY }}
            project_id: ${{ secrets.PROJECT_ID }}
            export_default_credentials: true

        - name: Trigger cloudbuild job
            run: |
            gcloud builds submit --config=cloudbuild.yaml .

Step 7: Run Terraform

Run the following commands to apply the Terraform configuration.


terraform init

terraform apply

Usage

Commit the changes to your repository and push them to the main branch. This will trigger the Github workflow and start the cloudbuild job.

Conclusion

Congratulations! You have successfully used a user-specified service account to trigger a GCP cloudbuild job with Terraform and YAML using Github CI workflow.

Reference