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"
}