# GCP Cloud Run manager terraform module This module manages a Cloud Run-hosted container. It takes care of making sure the container is connected to a Cloud SQL instance and sets environment variables on the application. Specify the project to deploy into on the command line. So, for example, to deploy to the project ``my-project``: ```console $ terraform init $ terraform apply -var project=my-project ``` In this example, terraform is configured to use default application credentials. For Google APIs and these credentials should correspond to a user with owner or editor access to the target project. You can use the ``gcloud`` command line tool to set your personal credentials as application default credentials. See the ``gcloud auth application-default`` command output for more information. ## Versioning The `master` branch contains the tip of development and corresponds to the `v2` branch. The `v1` branch will maintain source compatibility with the initial release. ## Custom domain mapping Setting the `dns_name` will create a domain mapping for the webapp. Before setting this value you *must* have verified ownership of the domain with Google. [Instructions on how to do this](https://guidebook.devops.uis.cam.ac.uk/en/latest/notes/google-domain-verification/) can be found in the DevOps division guidebook. ## Monitoring and Alerting If the variable [alerting_email_address](variables.tf) is set, the module adds basic uptime *alerting* via email for failing http polling. If the variable [disable_monitoring](variables.tf) is true, the module will disable *monitoring*. This is different from disabling alerting; if no alerting email addresses are provided, the uptime checks will still be configured, there just won't be any alerts sent if they fail. Disabling monitoring will also disable alerting as without any monitoring there is nothing to alert(!) See [variables.tf](variables.tf) for how to configure alerting and monitoring. Note that the project containing resources to be monitored must be in a Stackdriver monitoring workspace and this must be configured manually. At the time of writing there is no terraform support for this. This module will error when applying if this is not so. Stackdriver distinguishes between workspaces and projects within those workspaces. Each workspace must have a host project and that project *must* be the default project of the `google.stackdriver` provider used by this module. The `google.stackdriver` must be configured with credentials allowing monitoring resources to be created in the *host* project. If the workspace host project differs from the project which contains the resources to be monitored, you can use a provider alias: ```tf provider "google" { project = "my-project" # ... some credentials for the *project* admin ... } provider "google" { project = "stackdriver-host-project" alias = "host" # ... some credentials for the *product* admin ... } module "cloud_run_service" { # ... other parameters ... providers = { google.stackdriver = google.host } } ``` ### Monitoring instances which require service account authentication If `allow_unauthenticated_invocations` is not true, a Cloud Function will be created which authenticates via a service account, allowing the StackDriver monitoring to call the Cloud Function, with the Cloud Function authentication and proxying the request to the Cloud Run instance. Because this requires a Cloud Function to be created, the `cloudfunctions.googleapis.com` service should be enabled on the project that houses the Cloud Run instance. ## Static Egress IP A static egress IP can be allocated for the cloud run instance, using the variable `enable_static_egress_ip`. This will configure the necessary resources to route outbound traffic from the cloud run through a static ip. **Important!** The static ip is configured with `prevent_destroy = true`, meaning that it cannot be destroyed without removing it from terraform state using `terraform state rm` and then manually destroying the resource within the GCP console. This is to prevent accidental destruction of an IP which is likely to be whitelisted within firewall configuration that lives outside of our deployments. ## Secrets as Volumes and Env Vars Secret Manager secrets can be as environment variables or volume mounts (files) in the running container. At time of writing, this requires Cloud Run to run as BETA. The service account that Cloud Run runs as needs access to the secrets for this feature to work. Thus, this module gives `secretAccessor` role to that service account for the secrets passed on `secrets_volume` and `secrets_envars`. Any number of items in the list is supported and not defining these variables when calling this module is acceptable. The path of the mounted file will be based on `path/name`. For the example configuration below the files will be `/secrets-1/foobarfile1` and `/secrets-2/foobarfile2`. A common `path` for multiple secrets is not supported, they must be unique. > Note: `name` should only have alphanumeric characters, hyphens and underscores. Setting `version = ""` is equivalent to `version = "latest"` but the variable is not optional. ```tf module "webapp" { source = "git::https://gitlab.developers.cam.ac.uk/uis/devops/infra/terraform/gcp-cloud-run-app.git?ref=v3" ... secrets_volume = [ { name = "foobarfile1" path = "/secret-1" id = google_secret_manager_secret.secret-a.secret_id version = "latest" }, { name = "foobarfile2" path = "/secret-2" id = google_secret_manager_secret.secret-b.secret_id version = "2" } ] secrets_envars = [ { name = "FOOBAR1" id = google_secret_manager_secret.secret-c.secret_id version = "latest" }, { name = "FOOBAR2" id = google_secret_manager_secret.secret-d.secret_id version = "" } ] ... ``` ## Passing Image Names to the Module Originally, the module did not deploy images except on the very first use (using `gcr.io/cloudrun/hello:latest`). Currently, the module deploys the image from the mandatory variable `image_name`.