services.tf (234 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.
*/
resource "google_cloud_run_service" "frontend_run" {
name = var.random_suffix ? "frontend-${random_id.suffix.hex}" : "frontend"
location = var.region
project = var.project_id
metadata {
annotations = {
# For valid annotation values and descriptions, see
# https://cloud.google.com/sdk/gcloud/reference/run/deploy#--ingress
"run.googleapis.com/ingress" = "internal-and-cloud-load-balancing"
}
labels = var.labels
}
template {
metadata {
annotations = {
"autoscaling.knative.dev/minScale" = "1"
"autoscaling.knative.dev/maxScale" = "1"
}
}
spec {
service_account_name = google_service_account.frontend_sa.email
containers {
image = var.frontend_image
env {
name = "APP_TITLE"
value = var.app_title
}
}
}
}
autogenerate_revision_name = true
traffic {
percent = 100
latest_revision = true
}
# Avoids a redeploy each time "run.googleapis.com/operation-id" changes.
lifecycle {
ignore_changes = [
metadata[0].annotations,
]
}
depends_on = [google_project_service.apis]
}
locals {
cloud_db_uri = var.use_vpc ? "mysql+mysqlconnector://${google_sql_user.crmint.name}:${google_sql_user.crmint.password}@${google_sql_database_instance.main.first_ip_address}/${google_sql_database.crmint.name}" : "mysql+mysqlconnector://${google_sql_user.crmint.name}:${google_sql_user.crmint.password}@/${google_sql_database.crmint.name}?unix_socket=/cloudsql/${google_sql_database_instance.main.connection_name}"
}
resource "google_secret_manager_secret" "cloud_db_uri" {
secret_id = "cloud_db_uri"
replication {
auto {}
}
depends_on = [google_project_service.apis]
}
resource "google_secret_manager_secret_version" "cloud_db_uri-latest" {
secret = google_secret_manager_secret.cloud_db_uri.name
secret_data = local.cloud_db_uri
}
resource "google_secret_manager_secret_iam_member" "cloud_db_uri-access" {
secret_id = google_secret_manager_secret.cloud_db_uri.id
role = "roles/secretmanager.secretAccessor"
member = "serviceAccount:${google_service_account.controller_sa.email}"
}
locals {
report_usage_id = var.report_usage ? random_integer.report_usage_id.id : ""
}
resource "random_integer" "report_usage_id" {
min = 1000000000
max = 1999999999
}
resource "google_cloud_run_service" "controller_run" {
provider = google-beta
name = var.random_suffix ? "controller-${random_id.suffix.hex}" : "controller"
location = var.region
project = var.project_id
metadata {
annotations = {
# For valid annotation values and descriptions, see
# https://cloud.google.com/sdk/gcloud/reference/run/deploy#--ingress
"run.googleapis.com/ingress" = "internal-and-cloud-load-balancing"
}
labels = var.labels
}
template {
metadata {
annotations = merge(
{
"autoscaling.knative.dev/minScale" = "0"
"autoscaling.knative.dev/maxScale" = "2"
},
var.use_vpc ? {
# Uses the VPC Connector
"run.googleapis.com/vpc-access-connector" = google_vpc_access_connector.connector[0].name
# Routes only egress to private ip addresses through the VPC Connector.
"run.googleapis.com/vpc-access-egress" = "private-ranges-only"
} : {
"run.googleapis.com/cloudsql-instances" = google_sql_database_instance.main.connection_name
}
)
}
spec {
service_account_name = google_service_account.controller_sa.email
containers {
image = var.controller_image
# TODO(dulacp): soon available in beta
# liveness_probe {
# initial_delay_seconds = 20
# timeout_seconds = 4
# period_seconds = 5
# failure_threshold = 2
# http_get {
# path = "/readiness_check"
# }
# }
env {
name = "REPORT_USAGE_ID"
value = local.report_usage_id
}
env {
name = "APP_TITLE"
value = var.app_title
}
env {
name = "NOTIFICATION_SENDER_EMAIL"
value = var.notification_sender_email
}
env {
name = "GOOGLE_CLOUD_PROJECT"
value = var.project_id
}
env {
name = "SERVICE_ACCOUNT_EMAIL"
value = google_service_account.controller_sa.email
}
env {
name = "PUBSUB_VERIFICATION_TOKEN"
value = random_id.pubsub_verification_token.b64_url
}
env {
name = "DATABASE_URI"
value_from {
secret_key_ref {
name = google_secret_manager_secret.cloud_db_uri.secret_id
key = "latest"
}
}
}
}
}
}
autogenerate_revision_name = true
traffic {
percent = 100
latest_revision = true
}
# Avoids a redeploy each time "run.googleapis.com/operation-id" changes.
lifecycle {
ignore_changes = [
metadata[0].annotations,
]
}
depends_on = [
google_project_service.apis,
google_secret_manager_secret_version.cloud_db_uri-latest
]
}
resource "google_cloud_run_service" "jobs_run" {
provider = google-beta
name = var.random_suffix ? "jobs-${random_id.suffix.hex}" : "jobs"
location = var.region
project = var.project_id
metadata {
annotations = {
# For valid annotation values and descriptions, see
# https://cloud.google.com/sdk/gcloud/reference/run/deploy#--ingress
"run.googleapis.com/ingress" = "internal-and-cloud-load-balancing"
}
labels = var.labels
}
template {
metadata {
annotations = {
"autoscaling.knative.dev/minScale" = "0"
"autoscaling.knative.dev/maxScale" = "5"
}
}
spec {
service_account_name = google_service_account.jobs_sa.email
containers {
image = var.jobs_image
# TODO(dulacp): soon available in beta
# liveness_probe {
# initial_delay_seconds = 20
# timeout_seconds = 4
# period_seconds = 5
# failure_threshold = 2
# http_get {
# path = "/readiness_check"
# }
# }
env {
name = "GOOGLE_CLOUD_PROJECT"
value = var.project_id
}
env {
name = "PUBSUB_VERIFICATION_TOKEN"
value = random_id.pubsub_verification_token.b64_url
}
}
timeout_seconds = 900 # 15min
}
}
autogenerate_revision_name = true
traffic {
percent = 100
latest_revision = true
}
# Avoids a redeploy each time "run.googleapis.com/operation-id" changes.
lifecycle {
ignore_changes = [
metadata[0].annotations,
]
}
depends_on = [google_project_service.apis]
}
resource "google_cloudbuild_worker_pool" "private" {
count = var.use_vpc ? 1 : 0
name = "crmint-private-pool"
location = var.region
worker_config {
disk_size_gb = 100
machine_type = "e2-standard-2"
no_external_ip = var.use_vpc ? true : false
}
dynamic "network_config" {
# Includes this block only if `local.private_network` is set to a non-null value.
for_each = local.private_network[*]
content {
peered_network = google_compute_network.private[0].id
}
}
depends_on = [
google_project_service.apis,
google_project_service.vpcaccess,
google_service_networking_connection.private_vpc_connection
]
}
# Local variables are used to simplify the definition of outputs.
locals {
migrate_image = var.controller_image
migrate_sql_conn_name = google_sql_database_instance.main.connection_name
pool = var.use_vpc ? google_cloudbuild_worker_pool.private[0].id : "default"
}