Blog

How To Create A Scheduled Cloud Build Trigger With Terraform

18 May, 2022
Xebia Background Header Wave

Scheduled builds are useful for recurring tasks such as nightly tests. Scheduling a build with Cloud Build, however, requires additional infrastructure to trigger the build. In this blog I’ll show you how to use Terraform to configure a Manual trigger and trigger it with Cloud Scheduler.

Remark Sadly we can’t use Terraform for all infrastructure. The source repository connection requires you to install the GitHub App -or similar- once.

Create a scheduled build

A scheduled build is created by defining the build trigger and configuring a job to run the build trigger. The required code is shown next.

resource "google_cloudbuild_trigger" "example" {
  project = "example"
  name    = "example"

  source_to_build {
    repo_type = "GITHUB"
    uri       = "https://github.com/binxio/scheduled-trigger-example"
    ref       = "refs/heads/main"
  }

  git_file_source {
    path = "cloudbuild.yaml"

    repo_type = "GITHUB"
    uri       = "https://github.com/binxio/scheduled-trigger-example"
    revision  = "refs/heads/main"
  }
}

resource "google_cloud_scheduler_job" "example_nightly" {
  project = "example"
  region  = "europe-west1" # NOTE: Scheduler availability is limited
  name    = "example-nightly"

  schedule  = "0 0 * * *"
  time_zone = "Europe/Amsterdam"

  attempt_deadline = "120s"

  http_target {
    http_method = "POST"
    uri         = "https://cloudbuild.googleapis.com/v1/projects/example/triggers/${google_cloudbuild_trigger.example.trigger_id}:run"

    oauth_token {
      service_account_email = google_service_account.build_runner.email
    }
  }
}

resource "google_service_account" "build_runner" {
  project      = "example"
  account_id   = "build-runner"
}

resource "google_project_iam_member" "build_runner_build_editor" {
  project = "example"
  role    = "roles/cloudbuild.builds.editor"
  member  = "serviceAccount:${google_service_account.build_runner.email}"
}

Bonus: Reduce scheduled job permissions

You might have noticed that we granted Cloud Build Editor permissions to the Scheduled Job. This is overkill, because we only need the cloudbuild.builds.create-permission to run a trigger. In the next example, the IAM assignment is replaced with a custom role.

resource "google_project_iam_custom_role" "build_runner" {
  project     = "example"
  role_id     = "buildRunner"
  title       = "Build Runner"
  description = "Grants permissions to trigger Cloud Builds."
  permissions = ["cloudbuild.builds.create"]
}

resource "google_project_iam_member" "build_runner_build_runner" {
  project = "example"
  role    = google_project_iam_custom_role.build_runner.name
  member  = "serviceAccount:${google_service_account.build_runner.email}"
}

While this is better. We are still not applying least privilege. First, the cloudbuild.builds.create permissions allows for more than running a trigger. I’m hoping for a future cloudbuild.builds.run permission to replace this. Second, the role is assigned at the Project-level. In effect you can trigger any build. Again, I’m hoping for a future Build Trigger level IAM permission to replace this.

Conclusion

Creating scheduled build triggers is as easy as configuring a couple of resources. However, beware of the excessive IAM permissions required to trigger a build.

Image by Andreas Lischka from Pixabay

Laurens Knoll
As a cloud consultant I enjoy taking software engineering practices to the cloud. Continuously improving the customers systems, tools and processes by focusing on integration and quality.
Questions?

Get in touch with us to learn more about the subject and related solutions

Explore related posts