infrastructure/terraform/modules/monitor/main.tf (237 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. locals { source_root_dir = "../.." dashboard_dataset_name = "maj_dashboard" log_dataset_name = "maj_logs" link_load_file = "load_links.json" console = "https://console.cloud.google.com" bq_console = "${local.console}/bigquery" vertex_console = "${local.console}/vertex-ai" p_key = "project" mds_project_url = "${local.p_key}=${var.mds_project_id}" feature_store_project_url = "${local.p_key}=${var.feature_store_project_id}" activation_project_url = "${local.p_key}=${var.activation_project_id}" mds_dataform_repo = "marketing-analytics" } module "project_services" { source = "terraform-google-modules/project-factory/google//modules/project_services" version = "18.0.0" disable_dependent_services = false disable_services_on_destroy = false project_id = var.project_id activate_apis = [ "cloudfunctions.googleapis.com", "bigquery.googleapis.com", "logging.googleapis.com", "bigquerystorage.googleapis.com", "storage.googleapis.com", ] } # This resource executes gcloud commands to check whether the BigQuery API is enabled. # Since enabling APIs can take a few seconds, we need to make the deployment wait until the API is enabled before resuming. resource "null_resource" "check_bigquery_api" { provisioner "local-exec" { command = <<-EOT COUNTER=0 MAX_TRIES=100 while ! gcloud services list --project=${module.project_services.project_id} | grep -i "bigquery.googleapis.com" && [ $COUNTER -lt $MAX_TRIES ] do sleep 6 printf "." COUNTER=$((COUNTER + 1)) done if [ $COUNTER -eq $MAX_TRIES ]; then echo "bigquery api is not enabled, terraform can not continue!" exit 1 fi sleep 20 EOT } } module "dashboard_bigquery" { source = "terraform-google-modules/bigquery/google" version = "9.0.0" dataset_id = local.dashboard_dataset_name dataset_name = local.dashboard_dataset_name description = "providing links to looker dashboard" project_id = null_resource.check_bigquery_api.id != "" ? module.project_services.project_id : "" location = var.location delete_contents_on_destroy = true tables = [ { table_id = "resource_link", schema = file("../../sql/schema/table/resource_link.json"), time_partitioning = null, range_partitioning = null, expiration_time = null, clustering = [], labels = {}, }] } module "load_bucket" { source = "terraform-google-modules/cloud-storage/google//modules/simple_bucket" version = "9.0.1" project_id = module.project_services.project_id name = "maj-monitor-${module.project_services.project_id}" location = var.location force_destroy = true } data "template_file" "resource_link_content" { template = file("${local.source_root_dir}/templates/monitoring_resource_link_template.csv") vars = { console = local.console bq_console = local.bq_console vertex_console = local.vertex_console mds_project = var.mds_project_id feature_store_project = var.feature_store_project_id activation_project = var.activation_project_id mds_project_url = local.mds_project_url feature_store_project_url = local.feature_store_project_url activation_project_url = local.activation_project_url mds_dataset_suffix = var.mds_dataset_suffix mds_location = var.mds_location mds_dataform_repo = local.mds_dataform_repo mds_dataform_workspace = var.mds_dataform_workspace } } resource "google_storage_bucket_object" "resource_link_load_file" { name = local.link_load_file bucket = module.load_bucket.name content = data.template_file.resource_link_content.rendered } resource "google_bigquery_job" "monitor_resources_load" { job_id = uuid() project = module.project_services.project_id load { source_uris = [ "gs://${module.load_bucket.name}/${google_storage_bucket_object.resource_link_load_file.output_name}", ] destination_table { project_id = module.project_services.project_id dataset_id = module.dashboard_bigquery.bigquery_dataset.dataset_id table_id = module.dashboard_bigquery.table_ids[0] } write_disposition = "WRITE_TRUNCATE" } location = var.location lifecycle { ignore_changes = [job_id] } } locals { dataform_log_table_id = "dataform_googleapis_com_workflow_invocation_completion" vertex_pipelines_log_table_id = "aiplatform_googleapis_com_pipeline_job_events" dataflow_log_table_id = "dataflow_googleapis_com_job_message" log_table_ids = [ local.dataform_log_table_id, local.vertex_pipelines_log_table_id, local.dataflow_log_table_id ] } module "log_export_bigquery" { source = "terraform-google-modules/bigquery/google" version = "9.0.0" dataset_id = local.log_dataset_name dataset_name = local.log_dataset_name description = "Holds log exports" project_id = module.project_services.project_id location = var.location delete_contents_on_destroy = true tables = [for table_id in local.log_table_ids : { table_id = table_id, schema = file("../../sql/schema/table/${table_id}.json"), time_partitioning = { type = "DAY", field = "timestamp", require_partition_filter = false, expiration_ms = null, }, range_partitioning = null, expiration_time = null, clustering = [], labels = {}, }] } resource "google_logging_project_sink" "mds_daily_execution" { name = "mds_execution_export" project = var.mds_project_id filter = "resource.type=\"dataform.googleapis.com/Repository\"" destination = "bigquery.googleapis.com/projects/${module.log_export_bigquery.project}/datasets/${module.log_export_bigquery.bigquery_dataset.dataset_id}" unique_writer_identity = true bigquery_options { use_partitioned_tables = true } } resource "google_project_iam_member" "mds_daily_execution_member" { project = module.project_services.project_id role = "roles/bigquery.dataEditor" member = element(concat(google_logging_project_sink.mds_daily_execution[*].writer_identity, [""]), 0) } resource "google_logging_project_sink" "vertex_pipeline_execution" { name = "vertex_pipeline_execution_export" project = var.feature_store_project_id filter = "jsonPayload.@type=\"type.googleapis.com/google.cloud.aiplatform.logging.PipelineJobLogEntry\" AND (jsonPayload.state=\"PIPELINE_STATE_SUCCEEDED\" OR \"PIPELINE_STATE_FAILED\" OR \"PIPELINE_STATE_CANCELLED\")" destination = "bigquery.googleapis.com/projects/${module.log_export_bigquery.project}/datasets/${module.log_export_bigquery.bigquery_dataset.dataset_id}" unique_writer_identity = true bigquery_options { use_partitioned_tables = true } } resource "google_project_iam_member" "vertex_pipeline_execution_member" { project = module.project_services.project_id role = "roles/bigquery.dataEditor" member = element(concat(google_logging_project_sink.vertex_pipeline_execution[*].writer_identity, [""]), 0) } resource "google_logging_project_sink" "activation_pipeline_execution" { name = "activation_pipeline_execution_export" project = var.activation_project_id filter = "resource.labels.job_name=\"activation-processing\" AND textPayload=\"Worker pool stopped.\"" destination = "bigquery.googleapis.com/projects/${module.log_export_bigquery.project}/datasets/${module.log_export_bigquery.bigquery_dataset.dataset_id}" unique_writer_identity = true bigquery_options { use_partitioned_tables = true } } resource "google_project_iam_member" "activation_pipeline_execution_member" { project = module.project_services.project_id role = "roles/bigquery.dataEditor" member = element(concat(google_logging_project_sink.activation_pipeline_execution[*].writer_identity, [""]), 0) } data "template_file" "looker_studio_dashboard_url" { template = file("${local.source_root_dir}/templates/looker_studio_create_dashboard_url_template.txt") vars = { mds_project = var.mds_project_id monitor_project = module.project_services.project_id feature_store_project = var.feature_store_project_id report_id = "f61f65fe-4991-45fc-bcdc-80593966f28c" mds_ga4_product_dataset = "marketing_ga4_v1_${var.mds_dataset_suffix}" mds_ga4_base_dataset = "marketing_ga4_base_${var.mds_dataset_suffix}" mds_ads_product_dataset = "marketing_ads_v1_${var.mds_dataset_suffix}" mds_ads_base_dataset = "marketing_ads_base_${var.mds_dataset_suffix}" logs_dataset = module.log_export_bigquery.bigquery_dataset.dataset_id aggregated_vbb_dataset = "aggregated_vbb" aggregated_predictions_dataset = "aggregated_predictions" gemini_insights_dataset = "gemini_insights" purchase_propensity_dataset = var.purchase_propensity_dataset_id dataform_log_table_id = local.dataform_log_table_id vertex_pipelines_log_table_id = local.vertex_pipelines_log_table_id dataflow_log_table_id = local.dataflow_log_table_id } } data "template_file" "purchase_propensity_prediction_stats_query" { template = file("${local.source_root_dir}/templates/purchase_propensity_smart_bidding_view.sql.tpl") vars = { project_id = var.feature_store_project_id purchase_propensity_dataset = var.purchase_propensity_dataset_id activation_dataset = "activation" smart_bidding_configuration_table = var.smart_bidding_configuration_table } } resource "google_bigquery_table" "purchase_propensity_prediction_stats" { project = var.feature_store_project_id dataset_id = var.purchase_propensity_dataset_id table_id = "purchase_propensity_prediction_stats" deletion_protection = false view { query = data.template_file.purchase_propensity_prediction_stats_query.rendered use_legacy_sql = false } }