Skip to content

Latest commit

 

History

History

react-spa-app

React single page app on Cloud Run + Cloud Storage

Introduction

This blueprint contains a simple React single page application created with create-react-app and necessary Terraform resources to deploy it in on Google Cloud. The blueprint also contains a very simple Python backend that returns Hello World.

This example incorporates several HTTP security features like:

  • Hashes script files for Content-Security-Policy
  • Cross domain control for backend (when using DNS; see configuration for DNS below)
  • Backend ingress settings
  • Minimally permissioned service accounts
  • Cloud Armor policy (though permissive)
  • Support for Identity-Aware Proxy (when using DNS; see below)

Prerequisites

You will need an existing project with billing enabled and a user with the “Project owner” IAM role on that project. Note: to grant a user a role, take a look at the Granting and Revoking Access documentation.

Spinning up the architecture

General steps

  1. Clone the repo to your local machine or Cloud Shell:
git clone https://github.com/GoogleCloudPlatform/cloud-foundation-fabric
  1. Change to the directory of the blueprint:
cd cloud-foundation-fabric/blueprints/serverless/cloud-run-react-spa

You should see this README and some terraform files.

  1. To deploy a specific use case, you will need to create a file in this directory called terraform.tfvars and follow the corresponding instructions to set variables. Values that are meant to be substituted will be shown inside brackets but you need to omit these brackets. E.g.:
project_id = "[your-project_id]"
region = "[region-to-deploy-in]"

may become

project_id = "my-project-id"
region = "europe-west4"

Although each use case is somehow built around the previous one they are self-contained so you can deploy any of them at will.

  1. Now, you should build the React application:
# cd my-app
# npm install
# npm run build
# cd..
  1. The usual terraform commands will do the work:
terraform init
terraform plan
terraform apply

It will take a few minutes. When complete, you should see an output stating the command completed successfully, a list of the created resources, and some output variables with information to access your services.

Congratulations! You have successfully deployed the use case you chose based on the variables configuration.

Deploy regional load balancer

You can choose between global and regional load balancer (or use both) by setting regional_lb and global_lb variables in your terraform.tfvars.

Create DNS

If you want to create a DNS config which separates the frontend and backend to separate hosts, you can set the dns_config parameter:

dns_config = {
  zone_name     = "react-test-example-com"
  zone_dns_name = "react.test.example.com."
}

Note: Enabling DNS also turns on TLS certificate provisioning.

Enable Identity-Aware Proxy

You can also enable Identity-Aware Proxy (works best with regional proxy, due to Cloud Run proxy for the bucket). Please note you need DNS configured for this (see above):

iap_config = {
  enabled       = true
  support_email = "[email protected]"
}

(if you already have a brand, you can specify the number ID for it in brand variable, which you canfetch via gcloud iap oauth-brands list).

Note: enabling IAP can take quite a while (O(minutes)).

You also need to set backendUrl to (for example) https://backend.react.test.example.com (or the regional equivalent) in my-app/App/index.js (and run cd my-app/ && npm run build && cd .. afterwards).

Note: you can't have both global and load balancers active in this configuration.

Variables

name description type required default
project_id Google Cloud project ID. string
region Region where to deploy the function and resources. string
backend Backend settings. object({…}) {}
bucket Bucket settings for hosting the SPA. object({…}) {}
dns_config Create a public DNS zone for the load balancer (and optionally subdomain delegation). object({…}) null
enable_cdn Enable CDN for backend bucket. bool false
global_lb Deploy a global application load balancer. bool true
iap_config Identity-Aware Proxy configuration object({…}) {}
lb_name Application Load Balancer name. string "my-react-app"
nginx_image Nginx image to use for regional load balancer. string "gcr.io/cloud-marketplace/google/nginx1:1.26"
project_create Parameters for the creation of a new project. object({…}) null
regional_lb Deploy a regional application load balancer. bool false
vpc_config Settings for VPC (required when deploying a Regional LB). object({…}) {…}

Outputs

name description sensitive
global_lb Global load balancer address.
regional_lb Regional load balancer address.