main.tf (269 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. */ module "project_services" { source = "terraform-google-modules/project-factory/google//modules/project_services" version = "~> 14.2" disable_services_on_destroy = false project_id = var.project_id activate_apis = [ "serviceusage.googleapis.com", "vision.googleapis.com", "cloudfunctions.googleapis.com", "serviceusage.googleapis.com", "artifactregistry.googleapis.com", "eventarc.googleapis.com", "bigquery.googleapis.com", "aiplatform.googleapis.com", "storage.googleapis.com", "cloudbuild.googleapis.com", "run.googleapis.com", "iam.googleapis.com", "notebooks.googleapis.com", "dataform.googleapis.com", ] } data "google_project" "project" { project_id = var.project_id depends_on = [ module.project_services, ] } resource "google_project_service_identity" "eventarc" { provider = google-beta project = data.google_project.project.project_id service = "eventarc.googleapis.com" depends_on = [ module.project_services, ] } resource "google_project_iam_member" "eventarc_sa_role" { project = data.google_project.project.project_id role = "roles/eventarc.serviceAgent" member = "serviceAccount:${google_project_service_identity.eventarc.email}" } resource "null_resource" "previous_time" {} # Gate till APIs are enabled resource "time_sleep" "wait_for_apis" { depends_on = [ null_resource.previous_time, module.project_services, google_project_iam_member.eventarc_sa_role, ] create_duration = var.time_to_enable_apis } resource "random_id" "rand" { byte_length = 4 } data "archive_file" "webhook" { type = "zip" source_dir = var.webhook_path output_path = abspath("./.tmp/${var.webhook_name}.zip") } resource "google_storage_bucket_object" "webhook" { name = "${var.webhook_name}.${data.archive_file.webhook.output_base64sha256}.zip" bucket = google_storage_bucket.main.name source = data.archive_file.webhook.output_path } resource "google_service_account" "webhook" { project = var.project_id account_id = "webhook-service-account" display_name = "Serverless Webhooks Service Account" depends_on = [ module.project_services, ] } resource "google_project_iam_member" "webhook_sa_roles" { project = var.project_id for_each = toset([ "roles/run.invoker", "roles/cloudfunctions.invoker", "roles/storage.admin", "roles/logging.logWriter", "roles/artifactregistry.reader", "roles/bigquery.dataEditor", "roles/aiplatform.user", ]) role = each.key member = "serviceAccount:${google_service_account.webhook.email}" } resource "google_cloudfunctions2_function" "webhook" { project = var.project_id name = var.webhook_name location = var.region build_config { runtime = "python310" entry_point = "entrypoint" source { storage_source { bucket = "${var.bucket_name}-${random_id.rand.hex}" object = google_storage_bucket_object.webhook.name } } } service_config { service_account_email = google_service_account.webhook.email max_instance_count = 5 available_memory = "4G" available_cpu = 1 max_instance_request_concurrency = 5 timeout_seconds = var.gcf_timeout_seconds environment_variables = { PROJECT_ID = var.project_id LOCATION = var.region OUTPUT_BUCKET = google_storage_bucket.output.name DATASET_ID = google_bigquery_dataset.default.dataset_id TABLE_ID = google_bigquery_table.default.table_id } } depends_on = [ module.project_services, time_sleep.wait_for_apis, google_project_iam_member.webhook_sa_roles, ] } resource "google_bigquery_dataset" "default" { dataset_id = "summary_dataset" project = var.project_id depends_on = [ module.project_services, ] } resource "google_bigquery_table" "default" { dataset_id = google_bigquery_dataset.default.dataset_id table_id = "summary_table" project = var.project_id deletion_protection = false schema = <<EOF [ { "name": "bucket", "type": "STRING", "description": "Source bucket of artifact" }, { "name": "filename", "type": "STRING", "description": "Filename of the source artifact" }, { "name": "extracted_text", "type": "STRING", "description": "Text extracted from the source artifact" }, { "name": "summary_uri", "type": "STRING", "description": "The Storage URI of the complete document text" }, { "name": "complete_text_uri", "type": "STRING", "description": "The Storage URI of the complete document text" }, { "name": "summary", "type": "STRING", "description": "Text summary generated by the LLM" }, { "name": "timestamp", "type": "TIMESTAMP", "description": "TeTimestamp that the processing occurred on" } ] EOF } resource "google_storage_bucket" "uploads" { project = var.project_id name = "${var.project_id}_uploads" location = var.region force_destroy = true uniform_bucket_level_access = true } resource "google_storage_bucket" "output" { project = var.project_id name = "${var.project_id}_output" location = var.region force_destroy = true uniform_bucket_level_access = true } resource "google_storage_bucket" "main" { project = var.project_id name = "${var.bucket_name}-${random_id.rand.hex}" location = "US" uniform_bucket_level_access = true } resource "google_service_account" "upload_trigger" { project = var.project_id account_id = "upload-trigger-service-account" display_name = "Eventarc Service Account" depends_on = [ module.project_services, ] } resource "google_project_iam_member" "event_receiver" { project = var.project_id role = "roles/eventarc.eventReceiver" member = "serviceAccount:${google_service_account.upload_trigger.email}" depends_on = [ module.project_services, ] } resource "google_project_iam_member" "run_invoker" { project = var.project_id role = "roles/run.invoker" member = "serviceAccount:${google_service_account.upload_trigger.email}" depends_on = [ module.project_services, ] } data "google_storage_project_service_account" "gcs_account" { project = var.project_id depends_on = [time_sleep.wait_for_apis] } resource "google_project_iam_member" "pubsub_publisher" { project = var.project_id role = "roles/pubsub.publisher" member = "serviceAccount:${data.google_storage_project_service_account.gcs_account.email_address}" depends_on = [ module.project_services, data.google_storage_project_service_account.gcs_account, ] } resource "google_eventarc_trigger" "summarization" { project = var.project_id name = "terraformdev" location = var.region matching_criteria { attribute = "type" value = "google.cloud.storage.object.v1.finalized" } matching_criteria { attribute = "bucket" value = google_storage_bucket.uploads.name } destination { cloud_run_service { service = google_cloudfunctions2_function.webhook.name region = var.region } } service_account = google_service_account.upload_trigger.email depends_on = [ google_project_iam_member.event_receiver, google_project_iam_member.run_invoker, google_project_iam_member.pubsub_publisher, ] }