Newer
Older
# main.tf configures top-level resources
# A service account which the webapp runs in the context of.
resource "google_service_account" "webapp" {
project = var.project
account_id = coalesce(var.service_account_id, "${var.name}-run")
display_name = coalesce(var.service_account_display_name, "Web application Cloud Run service account")
}
# The webapp service account has the ability to connect to the SQL instance.
# (Only if sql_instance_connection_name is non-empty.)
resource "google_project_iam_member" "webapp_sql_client" {
count = (var.sql_instance_connection_name != "") ? 1 : 0
project = local.sql_instance_project
role = "roles/cloudsql.client"
member = "serviceAccount:${google_service_account.webapp.email}"
}
# A Cloud Run service which hosts the webapp
resource "google_cloud_run_service" "webapp" {
name = var.name
location = var.cloud_run_region
project = var.project
annotations = merge(
# Annotations which are always set:
{
# Maximum number of auto-scaled instances. For a container with
# N-workers, maxScale should be less than 1/N of the maximum connection
# count for the Cloud SQL instance.
"autoscaling.knative.dev/maxScale" = var.max_scale
# As mentioned at https://www.terraform.io/docs/configuration/resources.html#ignore_changes
# placeholders need to be created as the adding the key to the map is
# considered a change and not ignored by ignore_changes
"client.knative.dev/user-image" = "placeholder"
"run.googleapis.com/client-name" = "placeholder"
"run.googleapis.com/client-version" = "placeholder"
},
# Annotations which are only set if there is a Cloud SQL instance:
(var.sql_instance_connection_name != "") ? {
# Cloud SQL instances to auto-magically make appear in the container as
# Unix sockets.
"run.googleapis.com/cloudsql-instances" = var.sql_instance_connection_name
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
}
spec {
# Maximum number of concurrent requests to an instance before it is
# auto-scaled. For webapps which use connection pooling, it should be safe
# to set this number without regard to the connection limit of the Cloud
# SQL instance. This can be no greater than 80.
#
# See https://cloud.google.com/run/docs/about-concurrency.
container_concurrency = var.container_concurrency
service_account_name = google_service_account.webapp.email
containers {
# This is a bootstrap container image. The real image is deployed by
# Gitlab CI.
image = "gcr.io/cloudrun/hello:latest"
resources {
limits = {
cpu = var.cpu_limit
memory = var.memory_limit
}
}
dynamic "env" {
for_each = var.environment_variables
content {
name = env.key
value = env.value
}
}
}
}
}
traffic {
percent = 100
latest_revision = true
}
lifecycle {
ignore_changes = [
# Which image is deployed to the container will be updated by GitLab CI.
# As such, don't view changes to the container image as requiring the
# resource be updated.
template[0].spec[0].containers[0].image,
# Some common annotations which we don't care about.
template[0].metadata[0].annotations["client.knative.dev/user-image"],
template[0].metadata[0].annotations["run.googleapis.com/client-name"],
template[0].metadata[0].annotations["run.googleapis.com/client-version"],
]
}
}
# Allow unauthenticated invocations for the webapp.
resource "google_cloud_run_service_iam_member" "webapp_all_users_invoker" {
count = var.allow_unauthenticated_invocations ? 1 : 0
location = google_cloud_run_service.webapp.location
project = google_cloud_run_service.webapp.project
service = google_cloud_run_service.webapp.name
role = "roles/run.invoker"
member = "allUsers"
}
# Domain mapping for default web-application. Only present if the domain is
# verified. We use the custom DNS name of the webapp if provided but otherwise
# the webapp is hosted at [SERVICE NAME].[PROJECT DNS ZONE]. We can't create
# the domain mapping if the domain is *not* verified because Google won't let
# us.
resource "google_cloud_run_domain_mapping" "webapp" {
count = local.domain_mapping_present ? 1 : 0
location = var.cloud_run_region
name = var.dns_name
metadata {
# For managed Cloud Run, the namespace *must* be the project name.
namespace = var.project
}
spec {
route_name = google_cloud_run_service.webapp.name
}
}