release/main.tf (248 lines of code) (raw):

terraform { backend "gcs" { prefix = "terraform/state" project = "gcp-release-notes-bot-test" } } # Zip up source code folder data "google_project" "project" { project_id = var.project_id } resource "google_project_service" "project_services" { for_each = toset([ "cloudresourcemanager.googleapis.com", "compute.googleapis.com", "firestore.googleapis.com", "logging.googleapis.com", "artifactregistry.googleapis.com", "cloudfunctions.googleapis.com", "run.googleapis.com", "pubsub.googleapis.com", "cloudscheduler.googleapis.com", "cloudbuild.googleapis.com", "iam.googleapis.com", "chat.googleapis.com", "gsuiteaddons.googleapis.com", "appsmarket-component.googleapis.com", "aiplatform.googleapis.com" ]) project = var.project_id service = each.key disable_on_destroy = false # Keep APIs enabled after apply } output "project_number" { value = data.google_project.project.number } resource "google_storage_bucket" "bucket" { name = "${var.project_id}-${var.cloud_functions_source_bucket_suffix}" project = var.project_id location = var.region force_destroy = true } data "archive_file" "function_source_check" { type = "zip" output_path = format("%s.zip", var.check_name) source_dir = format(".././%s/", var.check_name) } data "archive_file" "function_source_blog" { type = "zip" output_path = format("%s.zip", var.blog_name) source_dir = format(".././%s/", var.blog_name) } data "archive_file" "function_source_client" { type = "zip" output_path = format("%s.zip", var.client_name) source_dir = format(".././%s/", var.client_name) } resource "google_storage_bucket_object" "function_zip_object_check" { depends_on = [google_storage_bucket.bucket] name = "cloudfunctions_source/${data.archive_file.function_source_check.output_md5}-${basename(data.archive_file.function_source_check.output_path)}" bucket = google_storage_bucket.bucket.name source = data.archive_file.function_source_check.output_path content_type = "application/zip" } resource "google_storage_bucket_object" "function_zip_object_blog" { depends_on = [google_storage_bucket.bucket] name = "cloudfunctions_source/${data.archive_file.function_source_blog.output_md5}-${basename(data.archive_file.function_source_blog.output_path)}" bucket = google_storage_bucket.bucket.name source = data.archive_file.function_source_blog.output_path content_type = "application/zip" } resource "google_storage_bucket_object" "function_zip_object_client" { depends_on = [google_storage_bucket.bucket] name = "cloudfunctions_source/${data.archive_file.function_source_client.output_md5}-${basename(data.archive_file.function_source_client.output_path)}" bucket = google_storage_bucket.bucket.name source = data.archive_file.function_source_client.output_path content_type = "application/zip" } resource "google_cloudfunctions2_function" "check_function" { depends_on = [google_storage_bucket_object.function_zip_object_check] location = var.region name = var.check_name project = var.project_id build_config { runtime = var.runtime entry_point = "http_request" source { storage_source { bucket = google_storage_bucket.bucket.name object = google_storage_bucket_object.function_zip_object_check.name } } } service_config { max_instance_count = 1 available_memory = "4Gi" available_cpu = "8" timeout_seconds = var.timeout environment_variables = { GCP_PROJECT_ID = var.project_id PUB_SUB_TOPIC_NAME = var.pub_sub_topic_name } } } resource "google_cloudfunctions2_function" "blog_function" { depends_on = [google_storage_bucket_object.function_zip_object_blog] location = var.region name = var.blog_name project = var.project_id build_config { runtime = var.runtime entry_point = "http_request" source { storage_source { bucket = google_storage_bucket.bucket.name object = google_storage_bucket_object.function_zip_object_blog.name } } } service_config { max_instance_count = 1 available_memory = "4Gi" available_cpu = "8" timeout_seconds = var.timeout environment_variables = { GCP_PROJECT_ID = var.project_id PUB_SUB_TOPIC_NAME = var.pub_sub_topic_name } } } resource "google_cloudfunctions2_function" "client_function" { depends_on = [google_storage_bucket_object.function_zip_object_client] location = var.region name = var.client_name project = var.project_id build_config { runtime = var.runtime entry_point = "chat_app" source { storage_source { bucket = google_storage_bucket.bucket.name object = google_storage_bucket_object.function_zip_object_client.name } } } service_config { min_instance_count = 1 available_memory = "4Gi" available_cpu = "8" timeout_seconds = var.timeout environment_variables = { BASE_URL = "https://${var.region}-${var.project_id}.cloudfunctions.net/${var.client_name}" GCP_PROJECT_ID = var.project_id } } } resource "google_service_account" "service_account" { account_id = "cloud-run-pubsub-invoker" display_name = "Cloud Run Pub/Sub Invoker" project = var.project_id } # Grant Cloud Run Invoker role on the client Cloud Run function resource "google_cloud_run_service_iam_binding" "cloud_run_service_agent_client" { depends_on = [google_service_account.service_account] project = var.project_id location = var.region service = google_cloudfunctions2_function.client_function.name role = "roles/run.invoker" members = ["serviceAccount:${google_service_account.service_account.email}", "serviceAccount:service-${data.google_project.project.number}@gcp-sa-gsuiteaddons.iam.gserviceaccount.com"] } # Grant Cloud Run Invoker role on the check Cloud Run function resource "google_cloud_run_service_iam_binding" "cloud_run_service_agent_check" { depends_on = [google_service_account.service_account] project = var.project_id location = var.region service = google_cloudfunctions2_function.check_function.name role = "roles/run.invoker" members = ["serviceAccount:${google_service_account.service_account.email}"] } # Grant Cloud Run Invoker role on the blog Cloud Run function resource "google_cloud_run_service_iam_binding" "cloud_run_service_agent_blog" { depends_on = [google_service_account.service_account] project = var.project_id location = var.region service = google_cloudfunctions2_function.blog_function.name role = "roles/run.invoker" members = ["serviceAccount:${google_service_account.service_account.email}"] } resource "google_project_iam_member" "service_account_token_creator_binding" { project = var.project_id member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-pubsub.iam.gserviceaccount.com" role = "roles/iam.serviceAccountTokenCreator" } resource "google_pubsub_topic" "topic" { name = var.pub_sub_topic_name project = var.project_id } resource "google_pubsub_subscription" "subscription" { depends_on = [google_pubsub_topic.topic, google_cloudfunctions2_function.client_function] project = var.project_id name = "myRunSubscription" topic = google_pubsub_topic.topic.id ack_deadline_seconds = 600 push_config { push_endpoint = "${google_cloudfunctions2_function.client_function.url}/messages" oidc_token { service_account_email = google_service_account.service_account.email audience = google_cloudfunctions2_function.client_function.url } } } resource "google_cloud_scheduler_job" "job" { name = "refresh-release-notes" project = var.project_id region = var.region description = "Refresh releases notes every 5 minutes" schedule = "*/5 * * * *" time_zone = "America/New_York" attempt_deadline = "240s" # 4 minutes http_target { http_method = "GET" uri = google_cloudfunctions2_function.check_function.url oidc_token { audience = google_cloudfunctions2_function.check_function.url service_account_email = google_service_account.service_account.email } } } resource "google_cloud_scheduler_job" "blog_job" { name = "refresh-blogs" project = var.project_id region = var.region description = "Refresh blogs every 30 minutes" schedule = "*/30 * * * *" time_zone = "America/New_York" attempt_deadline = "320s" http_target { http_method = "GET" uri = google_cloudfunctions2_function.blog_function.url oidc_token { audience = google_cloudfunctions2_function.blog_function.url service_account_email = google_service_account.service_account.email } } } resource "google_firestore_database" "database" { depends_on = [google_project_service.project_services] project = var.project_id name = "(default)" location_id = "nam5" type = "FIRESTORE_NATIVE" delete_protection_state = "DELETE_PROTECTION_ENABLED" }