FAQ | This is a LIVE service | Changelog

Skip to content
Snippets Groups Projects
main.tf 4.55 KiB
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   = "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" {
Dr Abraham Martin's avatar
Dr Abraham Martin committed
  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
  }
}