# 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 = "webapp-run" display_name = "Web application Cloud Run service account" } # The webapp service account has the ability to connect to the SQL instance. resource "google_project_iam_member" "webapp_sql_client" { 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 "random_id" "webapp_revision_name" { byte_length = 4 prefix = "${var.name}-" } resource "google_cloud_run_service" "webapp" { name = var.name location = var.cloud_run_region project = var.project template { metadata { annotations = { # 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 # Cloud SQL instances to auto-magically make appear in the container as # Unix sockets. "run.googleapis.com/cloudsql-instances" = var.sql_instance_connection_name # 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" } # See the README for information on this. name = random_id.webapp_revision_name.hex } 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, # Also the name of the revision will change with each CI deployment template[0].metadata[0].name, # 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 } }