terraform/main.tf (198 lines of code) (raw):

/** * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // Declares the variable "services" which lists the Google Cloud services to be enabled. variable "services" { type = list(string) default = ["artifactregistry.googleapis.com", "cloudbuild.googleapis.com", "run.googleapis.com", "cloudscheduler.googleapis.com", "iam.googleapis.com"] } // Enables the Google Cloud services listed in the "services" variable for the project specified. resource "google_project_service" "project_service" { for_each = { for service in var.services : service => service } project = var.project_id service = each.value disable_on_destroy = false } // Creates a service account for Google Cloud Scheduler. resource "google_service_account" "cloud_scheduler_sa" { depends_on = [ resource.google_project_service.project_service ] account_id = "cloud-scheduler-sa" display_name = "Cloud Scheduler service account" project = var.project_id } // Gives the Cloud Scheduler service account the "Cloud Run Invoker" role, allowing it to trigger Cloud Run services. resource "google_project_iam_member" "cloudrun_invoker" { project = var.project_id role = "roles/run.invoker" member = "serviceAccount:${google_service_account.cloud_scheduler_sa.email}" } // Creates a service account for Google Cloud Run Jobs. resource "google_service_account" "cloud_run_job_sa" { depends_on = [ resource.google_project_service.project_service ] account_id = var.cloud_run_job_sa display_name = "Cloud Run Job service account" project = var.project_id } // Gives the Cloud Run Job service account the "Cloud Run Admin" role, allowing it to manage Cloud Run services. resource "google_project_iam_member" "cloud_run_service_account" { project = var.project_id role = "roles/run.admin" member = "serviceAccount:${google_service_account.cloud_run_job_sa.email}" } // Gives the Cloud Run Job service account the "Cloud Run Invoker" role, allowing it to trigger Cloud Run services. resource "google_project_iam_member" "cloud_run_invoker" { project = var.project_id role = "roles/run.invoker" member = "serviceAccount:${google_service_account.cloud_run_job_sa.email}" } // Gives the Cloud Run Job service account "Bigquery Admin" role, allowing it to read data from BigQuery and insert output into BigQuery. resource "google_project_iam_member" "bigquery_admin" { project = var.project_id role = "roles/bigquery.admin" member = "serviceAccount:${google_service_account.cloud_run_job_sa.email}" } // Creates a output Table in existing BigQuery Dataset resource "google_bigquery_table" "bq_table" { count = var.create_output_table == true ? 1 : 0 depends_on = [ google_project_iam_member.bigquery_admin ] dataset_id = var.bigquery_dataset_name table_id = var.output_table deletion_protection = false schema = <<EOF [ { "name": "job_id", "type": "STRING", "mode": "NULLABLE" }, { "name": "user_email", "type": "STRING", "mode": "NULLABLE" }, { "name": "query", "type": "STRING", "mode": "NULLABLE" }, { "name": "recommendation", "type": "RECORD", "mode": "REPEATED", "fields": [ { "name": "name", "type": "STRING", "mode": "NULLABLE" }, { "name": "description", "type": "STRING", "mode": "NULLABLE" } ] }, { "name": "slot_hours", "type": "FLOAT", "mode": "NULLABLE" }, { "name": "process_timestamp", "type": "TIMESTAMP", "mode": "NULLABLE" } ] EOF } // Sets up an Artifact Registry repository to store Docker images. module "docker_artifact_registry" { source = "github.com/GoogleCloudPlatform/cloud-foundation-fabric/modules/artifact-registry" depends_on = [ resource.google_project_service.project_service ] project_id = var.project_id location = var.region format = "DOCKER" id = var.repository } // Builds and pushes a Docker image to the Artifact Registry repository. resource "null_resource" "build_and_push_docker" { # Uncomment below lines to re-run build # triggers = { # always_run = "${timestamp()}" # } depends_on = [ module.docker_artifact_registry, resource.google_project_service.project_service ] provisioner "local-exec" { command = <<-EOF gcloud config set project ${var.project_id} gcloud builds submit .. --config cloudbuild.yaml --substitutions=_REGION=${var.region},_PROJECT_ID=${var.project_id},_REPOSITORY=${var.repository} EOF } } // Sets up a Cloud Run Job. resource "google_cloud_run_v2_job" "default" { name = var.cloud_run_job_name location = var.region depends_on = [ resource.google_project_service.project_service, resource.null_resource.build_and_push_docker ] template { template { containers { image = "${var.region}-docker.pkg.dev/${var.project_id}/${var.repository}/recognizer:0.1.1-SNAPSHOT" args = ["--read_from_info_schema", "--read_from_info_schema_days", "1", "--processing_project_id", "${var.project_id}", "--output_table", "${var.project_id}.${var.bigquery_dataset_name}.${var.output_table}"] } max_retries = 3 timeout = "900s" service_account = google_service_account.cloud_run_job_sa.email } } lifecycle { ignore_changes = [ launch_stage, ] } } // Sets up a Cloud Scheduler Job to regularly trigger the Cloud Run Job. resource "google_cloud_scheduler_job" "job" { count = var.apply_scheduler == true ? 1 : 0 depends_on = [ resource.google_project_service.project_service, resource.google_cloud_run_v2_job.default ] name = var.cloud_run_job_name schedule = var.scheduler_frequency http_target { http_method = "POST" uri = "https://${var.region}-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/${var.project_id}/jobs/${var.cloud_run_job_name}:run" oauth_token { service_account_email = google_service_account.cloud_scheduler_sa.email } } retry_config { max_backoff_duration = "3600s" max_doublings = 5 max_retry_duration = "0s" min_backoff_duration = "5s" retry_count = 0 } }