diff --git a/README.md b/README.md index 8b8e58ae8b96a91377bbc110b8f9003089495bfd..c7d9d423eb9e6cafc0c6b7249d8081f8a44d2df9 100644 --- a/README.md +++ b/README.md @@ -1,100 +1,111 @@ # 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. +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`: +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 +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. +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 `v8` branch. The `v1`, -`v2`, `v3` etc. branches will maintain source compatibility with the initial release. +The `master` branch contains the tip of development and corresponds to the `v8` +branch. The `v1`, `v2`, `v3` etc. branches will maintain source compatibility +with the initial release. ## Ingress style -There are two supported ingress styles depending on `var.ingress_style` variable. +There are two supported ingress styles depending on `var.ingress_style` +variable. `var.ingress_style` can be: -- `domain-mapping` (default): passing DNS domains as `var.dns_names` or `var.dns_name`, which takes - precedence over `var.dns_names`, will create domain mappings to the Cloud Run service. Before - setting this, you _must_ have verified ownership of the provided domains 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. - -- `load-balancer`: a load balancer will be configured instead of a domain mapping. The DNS domains - in `var.dns_names` or `var.dns_name`, which takes precedence over `var.dns_names`, will get - Google-managed or custom TLS certificates depending on `var.use_ssl_certificates` and - `var.ssl_certificates`. An IPv6 address can also be allocated to the load balancer if - `var.enable_ipv6` is `true`. +- `domain-mapping` (default): passing DNS domains as `var.dns_names` or + `var.dns_name`, which takes precedence over `var.dns_names`, will create + domain mappings to the Cloud Run service. Before setting this, you _must_ have + verified ownership of the provided domains 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. + +- `load-balancer`: a load balancer will be configured instead of a domain + mapping. The DNS domains in `var.dns_names` or `var.dns_name`, which takes + precedence over `var.dns_names`, will get Google-managed or custom TLS + certificates depending on `var.use_ssl_certificates` and + `var.ssl_certificates`. An IPv6 address can also be allocated to the load + balancer if `var.enable_ipv6` is `true`. ## Pre-deploy Cloud Run job -The `v8` release introduced an `enable_pre_deploy_job` variable. When set to `true` a [Cloud -Run job](https://cloud.google.com/run/docs/create-jobs) is created to execute a configurable command -_before_ the main Cloud Run service is deployed. The initial use case for this is to run database -migrations, however in the future we're sure there'll be more. - -The pre-deploy job uses the image specified in `var.pre_deploy_job_image_name` if set, otherwise it -falls back to the same `var.image_name` that the main service uses. The command and arguments that -the job executes are configurable via the `pre_deploy_job_command` and `pre_deploy_job_args` -variables. - -A `null_resource` is also configured to execute the pre-deploy job whenever it detects that the -value of `var.image_name` has changed (or at every `apply` if `var.force_pre_deploy_job` is set to -`true`). This uses the `gcloud run jobs execute` command and is run in the context of the -`terraform-deploy` service account via an access token. Using `null_resource` is never ideal. -However, in this situation it provides a very handy way to trigger this simple job so it has been -accepted. - -To ensure that the pre-deploy job always runs _before_ a new revision of the Cloud Run webapp -service is deployed, the resources in question are explicitly configured with `depends_on` -relationships, as follows. - -1. The `google_cloud_run_v2_job.pre_deploy` Cloud Run job has no `depends_on` relationships defined - and is therefore deployed first. -2. The `null_resource.pre_deploy_job_trigger` resource depends on - `google_cloud_run_v2_job.pre_deploy` and therefore won't be deployed until the Cloud Run job is - deployed successfully. -3. Finally, the `google_cloud_run_service.webapp` Cloud Run service depends on +The `v8` release introduced an `enable_pre_deploy_job` variable. When set to +`true` a [Cloud Run job](https://cloud.google.com/run/docs/create-jobs) is +created to execute a configurable command _before_ the main Cloud Run service is +deployed. The initial use case for this is to run database migrations, however +in the future we're sure there'll be more. + +The pre-deploy job uses the image specified in `var.pre_deploy_job_image_name` +if set, otherwise it falls back to the same `var.image_name` that the main +service uses. The command and arguments that the job executes are configurable +via the `pre_deploy_job_command` and `pre_deploy_job_args` variables. + +A `null_resource` is also configured to execute the pre-deploy job whenever it +detects that the value of `var.image_name` has changed (or at every `apply` if +`var.force_pre_deploy_job` is set to `true`). This uses the `gcloud run jobs +execute` command and is run in the context of the `terraform-deploy` service +account via an access token. Using `null_resource` is never ideal. However, in +this situation it provides a very handy way to trigger this simple job so it has +been accepted. + +To ensure that the pre-deploy job always runs _before_ a new revision of the +Cloud Run webapp service is deployed, the resources in question are explicitly +configured with `depends_on` relationships, as follows. + +1. The `google_cloud_run_v2_job.pre_deploy` Cloud Run job has no `depends_on` + relationships defined and is therefore deployed first. +1. The `null_resource.pre_deploy_job_trigger` resource depends on + `google_cloud_run_v2_job.pre_deploy` and therefore won't be deployed until + the Cloud Run job is deployed successfully. +1. Finally, the `google_cloud_run_service.webapp` Cloud Run service depends on `null_resource.pre_deploy_job_trigger`, meaning it is only deployed once the `null_resource.pre_deploy_job_trigger` has executed successfully. ## 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 [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(!) +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. +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. +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: +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" { @@ -121,45 +132,51 @@ module "cloud_run_service" { ### 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. +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. +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. +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. +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. +Secret Manager secrets can be as environment variables or volume mounts (files) +in the running container. -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`. +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`. +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. +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. +> Note: `name` should only have alphanumeric characters, hyphens and +> underscores. -Setting `version = ""` is equivalent to `version = "latest"` but the variable is not optional. +Setting `version = ""` is equivalent to `version = "latest"` but the variable is +not optional. ```tf module "webapp" { @@ -203,4 +220,5 @@ module "webapp" { 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`. +Currently, the module deploys the image from the mandatory variable +`image_name`.