Skip to content

datadrivers/terraform-google-cloud-run

Repository files navigation

Terraform Cloud Run Module

This module handles the basic deployment of containerized applications on Cloud Run, along with domain mapping and IAM policy for the service.

The resources/services/activations/deletions that this module will create/trigger are:

  • Creates a Cloud Run service with provided name and container
  • Creates Domain mapping for the deployed service
  • Applies IAM policies

Assumptions and Prerequisites

This module assumes that below mentioend prerequisites are in place before consuming the module.

  • All required APIs are enabled in the GCP Project
  • Cloud SQL
  • VPC Connector
  • Environment Variables in Secret Manager

Usage

Basic usage of this module is as follows:

module "cloud_run" {
  source  = "terraform-google-modules/terraform-google-cloud-run/google"
  version = "~> 0.1.1"

  service_name           = "<SERVICE NAME>"
  project_id             = "<PROJECT ID>"
  location               = "<LOCATION>"
  generate_revision_name = true
  traffic_split = [
    {
      latest_revision = true
      percent         = 100
      revision_name   = ""
    }
  ]
  service_labels = {
    "usage"         = "<ENV>" ,
    "owner"         = "<ADMIN>"
  }
  service_annotations = {
    # possible values: all, internal, internal-and-cloud-load-balancing
    "run.googleapis.com/ingress" = "all"
  }

  // Metadata
  template_labels = {
    "app" = "helloworld"
  }
  template_annotations = {
    "run.googleapis.com/cloudsql-instances" = "<CLOUD_SQL_CONNECTION_STRING>"
    "autoscaling.knative.dev/maxScale"      = 4
    "autoscaling.knative.dev/minScale"      = 2
    "run.googleapis.com/vpc-access-connector" = "<VPC_CONNECTOR_NAME>" # format 'projects/PROJECT_ID/locations/LOCATION/connectors/CONNECTOR_NAME'
    "run.googleapis.com/vpc-access-egress" = "all-traffic"
  }

  // template spec
  container_concurrency = 0
  timeout_seconds       = "120"
  service_account_name  = "<USER_MANAGED_SERVICE_ACCOUNT_NAME>"
  volumes = [
    {
      name = "<SECRET_VOLUME_NAME>"
      secret = [{
        secret_name = "<SECRET_NAME>"
        items = {
          path = "<SECRET_PATH>"
          key  = "<SECRET_VERSION>"
        }
      }]
    },
  ]

  # template spec container
  # resources
  # cpu = (core count * 1000)m
  # memory = (size) in Mi/Gi/M/G
  limits = {
    cpu    = "1000m"
    memory = "256Mi"
  }
  requests = {
    cpu    = "500m"
    memory = "128Mi"
  }

  // ports
  ports = {
    name     = "http1"
    port     = 3000
  }
  argument          = ""
  container_command = ""

  # envs
  env_vars = [
    {
      name  = "<ENV_VARIABLE_1>"
      value = "<ENV_VARIABLE_VALUE_1"
    },
    {
      name  = "<ENV_VARIABLE_2>"
      value = "<ENV_VARIABLE_VALUE_2>"
    }
  ]
  env_vars = [
    {
      name  = "<ENV_SECRET_VARIABLE_1>"
      value_from = [{
        secret_key_ref = {
          name = "<SECRET_NAME>"
          key  = "<SECRET_VERSION>"
        }
      }]
    },
  ]
  volume_mounts = [
    {
      mount_path = "<SECRET_MOUNT_PATH>"
      name       = "<SECRET_VOLUME_NAME>"
    },
  ]

  #### DOMAIN MAP
  verified_domain_name = "<DOMAIN_NAME>"
  force_override       = false
  certificate_mode     = "AUTOMATIC" # NONE, AUTOMATIC
  domain_map_labels = {
    "business_unit" = "app_name"
  }
  domain_map_annotations = {
    "run.googleapis.com/launch-stage" = "BETA"
  }

  #### IAM
  role = "roles/viewer"
  members = [
    "user:<USER_EMAIL>",
    "serviceAccount:<SA_EMAIL>"
  ]
  authenticated_access = false
}

Inputs

Name Description Type Default Required
argument Arguments passed to the entry point command string "" no
authenticated_access Option to enable or disable service authentication bool false no
certificate_mode The mode of the certificate string "NONE" no
container_command Leave blank to use the entry point command defined in the container image string "" no
container_concurrency Concurrent request limits to the service number 0 no
domain_map_annotations Annotations to the domain map map(string) {} no
domain_map_labels Labels to the domain map map(string)
{
"business_unit": "app_name"
}
no
env_secret_vars [Beta] Environment variables (Secret Manager)
list(object({
name = string
value_from = set(object({
secret_key_ref = map(string)
}))
}))
[] no
env_vars Environment variables (cleartext)
list(object({
value = string
name = string
}))
[] no
force_override Option to force override existing mapping bool false no
generate_revision_name Option to enable revision name generation bool true no
image GCR hosted image URL to deploy string n/a yes
limits Resource limits to the container map(string) {} no
location Cloud Run service deployment location string n/a yes
members Users/SAs to be givem permission to the service list(string)
[
"user:abc@xyz.com",
"serviceAccount:abc@xyz.com"
]
no
ports Port which the container listens to
object({
name = string
port = number
})
{
"name": "http1",
"port": 2000
}
no
project_id The project ID to deploy to string n/a yes
requests Resource requests to the container map(string) {} no
role Roles to be provisioned to the service string null no
service_account_name Service Account needed for the service string null no
service_annotations Annotations to the service map(string)
{
"run.googleapis.com/ingress": "all"
}
no
service_labels Labels to the service map(string)
{
"business_unit": "app_name"
}
no
service_name The name of the Cloud Run service to create string n/a yes
template_annotations Annotations to the container metadata map(string)
{
"autoscaling.knative.dev/maxScale": 2,
"autoscaling.knative.dev/minScale": 1,
"generated-by": "terraform",
"run.googleapis.com/client-name": "terraform"
}
no
template_labels Labels to the container metadata map(string)
{
"app": "helloworld"
}
no
timeout_seconds Timeout for each request number 120 no
traffic_split Managing traffic routing to the service
list(object({
latest_revision = bool
percent = number
revision_name = string
}))
[
{
"latest_revision": true,
"percent": 100,
"revision_name": "v1-0-0"
}
]
no
verified_domain_name Custom Domain Name string null no
volume_mounts [Beta] Volume Mounts to be attached to the container (when using secret)
list(object({
mount_path = string
name = string
}))
[] no
volumes [Beta] Volumes needed for environment variables (when using secret)
list(object({
name = string
secret = set(object({
secret_name = string
items = map(string)
}))
}))
[] no

Outputs

Name Description
domain_map_id Unique Identifier for the created domain map
domain_map_status Status of Domain mapping
location Location in which the Cloud Run service was created
project_id Google Cloud project in which the service was created
revision Deployed revision for the service
service_id Unique Identifier for the created service
service_name Name of the created service
service_status Status of the created service
service_url The URL on which the deployed service is available

Requirements

These sections describe requirements for using this module.

Software

The following dependencies must be available:

  • [Terraform][terraform] v0.13+
  • [Terraform Provider for GCP][terraform-provider-gcp] plugin v3.53+

Service Account

A user managed service account can be used with required roles to deploy and access other resources from Cloud Run service:

  • GKE Admin: roles/container.admin
  • Storage Admin: roles/storage.admin

Note: In order to deploy a service with a user-managed service account, the user deploying the service must have the iam.serviceAccounts.actAs permission on that service account.

APIs

A project with the following APIs enabled must be used to host the resources of this module:

  • Google Cloud Run: run.googleapis.com

The [Project Factory module][project-factory-module] and the [IAM module][iam-module] may be used in combination to provision a service account with the necessary roles applied.

Contributing

Refer to the contribution guidelines for information on contributing to this module.

Releases

No releases published

Packages

No packages published

Languages

  • HCL 76.9%
  • Go 20.9%
  • Makefile 1.6%
  • Ruby 0.6%