main.tf (244 lines of code) (raw):

/** * Copyright 2021 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. */ data "google_project" "project" { project_id = var.project_id } locals { api_image = var.api_image fe_image = var.fe_image } module "project-services" { source = "terraform-google-modules/project-factory/google//modules/project_services" version = "13.0.0" disable_services_on_destroy = false project_id = var.project_id enable_apis = var.enable_apis activate_apis = [ "compute.googleapis.com", "cloudapis.googleapis.com", "vpcaccess.googleapis.com", "servicenetworking.googleapis.com", "cloudbuild.googleapis.com", "sql-component.googleapis.com", "sqladmin.googleapis.com", "storage.googleapis.com", "run.googleapis.com", "redis.googleapis.com", ] } resource "google_service_account" "runsa" { project = var.project_id account_id = "${var.deployment_name}-run-sa" display_name = "Service Account for Cloud Run" } resource "google_project_iam_member" "allrun" { for_each = toset(var.run_roles_list) project = data.google_project.project.number role = each.key member = "serviceAccount:${google_service_account.runsa.email}" } resource "google_compute_network" "main" { provider = google-beta name = "${var.deployment_name}-private-network" auto_create_subnetworks = true project = var.project_id } resource "google_compute_global_address" "main" { name = "${var.deployment_name}-vpc-address" provider = google-beta purpose = "VPC_PEERING" address_type = "INTERNAL" prefix_length = 16 network = google_compute_network.main.name project = var.project_id } resource "google_service_networking_connection" "main" { network = google_compute_network.main.self_link service = "servicenetworking.googleapis.com" reserved_peering_ranges = [google_compute_global_address.main.name] } resource "google_vpc_access_connector" "main" { provider = google-beta project = var.project_id name = "${var.deployment_name}-vpc-cx" ip_cidr_range = "10.8.0.0/28" network = google_compute_network.main.name region = var.region max_throughput = 300 } # Looked at using the module, but there doesn't seem to be a huge win there. # Handle redis instance resource "google_redis_instance" "main" { authorized_network = google_compute_network.main.name connect_mode = "DIRECT_PEERING" location_id = var.zone memory_size_gb = 1 name = "${var.deployment_name}-cache" display_name = "${var.deployment_name}-cache" project = var.project_id redis_version = "REDIS_6_X" region = var.region reserved_ip_range = "10.137.125.88/29" tier = "BASIC" transit_encryption_mode = "DISABLED" labels = var.labels } resource "random_id" "id" { byte_length = 2 } # Handle Database resource "google_sql_database_instance" "main" { name = "${var.deployment_name}-db-${random_id.id.hex}" database_version = "POSTGRES_14" region = var.region project = var.project_id settings { tier = "db-g1-small" disk_autoresize = true disk_autoresize_limit = 0 disk_size = 10 disk_type = "PD_SSD" user_labels = var.labels ip_configuration { ipv4_enabled = false private_network = "projects/${var.project_id}/global/networks/${google_compute_network.main.name}" } location_preference { zone = var.zone } database_flags { name = "cloudsql.iam_authentication" value = "on" } } deletion_protection = false depends_on = [ google_service_networking_connection.main ] } resource "google_sql_user" "main" { project = var.project_id name = "${google_service_account.runsa.account_id}@${var.project_id}.iam" type = "CLOUD_IAM_SERVICE_ACCOUNT" instance = google_sql_database_instance.main.name deletion_policy = "ABANDON" } resource "google_sql_database" "database" { project = var.project_id name = "todo" instance = google_sql_database_instance.main.name deletion_policy = "ABANDON" } resource "google_cloud_run_service" "api" { name = "${var.deployment_name}-api" provider = google-beta location = var.region project = var.project_id template { spec { service_account_name = google_service_account.runsa.email containers { image = local.api_image env { name = "redis_host" value = google_redis_instance.main.host } env { name = "db_host" value = google_sql_database_instance.main.ip_address[0].ip_address } env { name = "db_user" value = google_service_account.runsa.email } env { name = "db_conn" value = google_sql_database_instance.main.connection_name } env { name = "db_name" value = "todo" } env { name = "redis_port" value = "6379" } } } metadata { annotations = { "autoscaling.knative.dev/maxScale" = "8" "run.googleapis.com/cloudsql-instances" = google_sql_database_instance.main.connection_name "run.googleapis.com/client-name" = "terraform" "run.googleapis.com/vpc-access-egress" = "all" "run.googleapis.com/vpc-access-connector" = google_vpc_access_connector.main.id } labels = { "run.googleapis.com/startupProbeType" = "Default" } } } metadata { labels = var.labels } autogenerate_revision_name = true depends_on = [ google_sql_user.main, google_sql_database.database ] } resource "google_cloud_run_service" "fe" { name = "${var.deployment_name}-fe" location = var.region project = var.project_id template { spec { service_account_name = google_service_account.runsa.email containers { image = local.fe_image ports { container_port = 80 } env { name = "ENDPOINT" value = google_cloud_run_service.api.status[0].url } } } metadata { annotations = { "autoscaling.knative.dev/maxScale" = "8" } labels = { "run.googleapis.com/startupProbeType" = "Default" } } } metadata { labels = var.labels } } resource "google_cloud_run_service_iam_member" "noauth_api" { location = google_cloud_run_service.api.location project = google_cloud_run_service.api.project service = google_cloud_run_service.api.name role = "roles/run.invoker" member = "allUsers" } resource "google_cloud_run_service_iam_member" "noauth_fe" { location = google_cloud_run_service.fe.location project = google_cloud_run_service.fe.project service = google_cloud_run_service.fe.name role = "roles/run.invoker" member = "allUsers" }