deploy/gcp-foundation/modules/main.tf (252 lines of code) (raw):

data "google_project" "project" { project_id = var.project_id } resource "google_iap_brand" "project_brand" { support_email = var.oauth_support_contact_email application_title = "${var.deployment_name} Application" project = data.google_project.project.number depends_on = [google_project_service.gcp_services] } resource "google_iap_client" "project_client" { display_name = "${google_iap_brand.project_brand.application_title} Client" brand = google_iap_brand.project_brand.name } #------------------------------------------------------------------------------------ # # Pubsub Topic and related IAM permission # #------------------------------------------------------------------------------------ locals { pubsub_svc_account_email = "service-${data.google_project.project.number}@gcp-sa-pubsub.iam.gserviceaccount.com" } resource "google_pubsub_topic" "topic" { count = var.create_topic ? 1 : 0 project = var.project_id name = var.pubsub_topic labels = var.gcp_labels kms_key_name = var.topic_kms_key_name dynamic "message_storage_policy" { for_each = var.message_storage_policy content { allowed_persistence_regions = message_storage_policy.key == "allowed_persistence_regions" ? message_storage_policy.value : null } } } resource "google_pubsub_topic_iam_member" "push_topic_binding" { for_each = var.create_topic ? { for i in var.push_subscriptions : i.name => i } : {} project = var.project_id topic = lookup(each.value, "dead_letter_topic", "projects/${var.project_id}/topics/${var.pubsub_topic}") role = "roles/pubsub.publisher" member = "serviceAccount:${local.pubsub_svc_account_email}" depends_on = [ google_pubsub_topic.topic, ] } #------------------------------------------------------------------------------------ # # Terraform module to provisioning CloudSQL (postgreSQL) DB: Instance, DB and DB user # #------------------------------------------------------------------------------------ # generate random password resource "random_password" "db_user_pass" { length = 16 special = false upper = true lower = true number = true } # create a secret for db user password resource "google_secret_manager_secret" "db_user_pass" { project = var.project_id secret_id = "migsc-db-user-pass" replication { automatic = true } depends_on = [google_project_service.gcp_services] } # add secret data for password secret resource "google_secret_manager_secret_version" "db_user_pass" { secret = google_secret_manager_secret.db_user_pass.id secret_data = random_password.db_user_pass.result depends_on = [google_project_service.gcp_services] } # create a secret for connection string resource "google_secret_manager_secret" "db_conn_string" { project = var.project_id secret_id = "migscaler-db-conn-string" replication { automatic = true } depends_on = [google_project_service.gcp_services] } # add secret data for connection string secret resource "google_secret_manager_secret_version" "db_conn_string" { secret = google_secret_manager_secret.db_conn_string.id secret_data = "postgresql+psycopg2://${var.user_name}:${random_password.db_user_pass.result}@/${var.db_name}?host=/cloudsql/${var.project_id}:${var.region}:${module.sql-db.instance_name}" depends_on = [google_project_service.gcp_services] } module "sql-db" { source = "GoogleCloudPlatform/sql-db/google//modules/postgresql" version = "8.0.0" # TODO: Upgrade this module to 11 name = "${var.db_instance_name}-${random_string.random.result}" user_labels = var.gcp_labels db_name = var.db_name user_name = var.user_name user_password = random_password.db_user_pass.result database_version = var.database_version project_id = var.project_id zone = var.zone region = var.region tier = var.tier maintenance_window_update_track = var.maintenance_window_update_track disk_size = var.disk_size maintenance_window_hour = var.maintenance_window_hour ip_configuration = { # authorized_networks = [{name = "network1", value = "0.0.0.0/0"},] authorized_networks = [] ipv4_enabled = true private_network = "" require_ssl = null } backup_configuration = { enabled = var.enable_automatic_backup start_time = var.enable_automatic_backup ? var.backup_config.start_time : null location = var.enable_automatic_backup ? var.backup_config.location : null point_in_time_recovery_enabled = var.enable_automatic_backup ? var.backup_config.point_in_time_recovery_enabled : false transaction_log_retention_days = var.enable_automatic_backup ? var.backup_config.transaction_log_retention_days : null retained_backups = var.enable_automatic_backup ? var.backup_config.retained_backups : null retention_unit = var.enable_automatic_backup ? var.backup_config.retention_unit : null } activation_policy = var.activation_policy availability_type = var.availability_type db_charset = var.db_charset db_collation = var.db_collation random_instance_name = var.random_instance_name create_timeout = var.create_timeout delete_timeout = var.delete_timeout update_timeout = var.update_timeout enable_default_user = var.enable_default_user enable_default_db = var.enable_default_db disk_type = var.disk_type deletion_protection = var.deletion_protection } #--------------------------------- # # Terraform resource to create GCS # #--------------------------------- resource "random_string" "random" { length = 5 special = false upper = false } resource "google_storage_bucket" "bucket" { name = "${var.bucket_name}-${random_string.random.result}" project = var.project_id location = var.region storage_class = var.storage_class uniform_bucket_level_access = var.bucket_policy_only labels = var.gcp_labels force_destroy = var.force_destroy versioning { enabled = var.versioning } dynamic "lifecycle_rule" { for_each = var.lifecycle_rules content { action { type = lifecycle_rule.value.action.type storage_class = lookup(lifecycle_rule.value.action, "storage_class", null) } condition { age = lookup(lifecycle_rule.value.condition, "age", null) created_before = lookup(lifecycle_rule.value.condition, "created_before", null) with_state = lookup(lifecycle_rule.value.condition, "with_state", lookup(lifecycle_rule.value.condition, "is_live", false) ? "LIVE" : null) matches_storage_class = lookup(lifecycle_rule.value.condition, "matches_storage_class", null) num_newer_versions = lookup(lifecycle_rule.value.condition, "num_newer_versions", null) } } } dynamic "logging" { for_each = var.log_bucket == null ? [] : [var.log_bucket] content { log_bucket = var.log_bucket log_object_prefix = var.log_object_prefix } } } resource "google_storage_bucket_object" "gce_metadata_folder" { name = "gce_metadata/" content = "GCE Metadata" bucket = google_storage_bucket.bucket.name } #----------------------------------------- # # Terraform module to enable projects APIs # #----------------------------------------- resource "google_project_service" "gcp_services" { for_each = toset(var.gcp_service_list) project = var.project_id service = each.key timeouts { create = "10m" update = "15m" } disable_on_destroy = false disable_dependent_services = true } //----------------------------------------------------------------------- // // // Terraform module to create Cloudrun svc and pubsub subscriptor (push) // // //----------------------------------------------------------------------- resource "google_cloud_tasks_queue" "migsc-ctq" { name = "${var.cloud_tasks_queue_name}-${random_string.random.result}" location = var.region project = var.project_id retry_config { max_attempts = 1 } depends_on = [google_project_service.gcp_services] } //-------------------------------------------------- // // // Terraform code for SA and role // // //-------------------------------------------------- # # GCP resource provisioning for custom roles and IAM permissions / Service Accounts for the BMS application # resource "google_project_iam_custom_role" "waverunner" { project = var.project_id role_id = "${var.custom_role_id}${random_string.random.result}" permissions = var.application_sa_custom_role_permissions title = var.custom_role_id description = "Waverunner app custom role" } resource "google_service_account" "waverunner" { account_id = var.application_sa_name project = var.project_id } resource "google_project_iam_member" "app_sa_custom_role" { project = var.project_id role = google_project_iam_custom_role.waverunner.name member = "serviceAccount:${google_service_account.waverunner.email}" } resource "google_project_iam_member" "app_sa_predefined_roles" { for_each = var.application_sa_roles project = var.project_id role = each.key member = "serviceAccount:${google_service_account.waverunner.email}" } //-------------------------------------------------- // // // Terraform code to create pubsub subscriptor push // // //-------------------------------------------------- resource "google_pubsub_subscription" "migsc-push-subs" { name = var.pub_subs_name // "bms-subs-dev-mvp" project = var.project_id topic = google_pubsub_topic.topic.0.name labels = var.gcp_labels message_retention_duration = var.subs_message_retention_duration // "604800s" retain_acked_messages = var.subs_retain_acked_messages // false ack_deadline_seconds = var.subs_ack_deadline_seconds // 10 expiration_policy { ttl = "" } retry_policy { minimum_backoff = var.subs_retry_policy["minimum_backoff"] maximum_backoff = var.subs_retry_policy["maximum_backoff"] } enable_message_ordering = var.subs_enable_message_ordering push_config { // push_endpoint = "https://${var.site_domain_name}/webhooks/status" push_endpoint = "https://${var.project_id}./webhooks/status" oidc_token { service_account_email = "${google_service_account.waverunner.email}" audience = "${google_iap_client.project_client.client_id}" } attributes = { x-goog-version = var.x-goog-version // "v1" } } }