diff --git a/client/firebase.json b/client/firebase.json index ff891fa4..903d7c22 100644 --- a/client/firebase.json +++ b/client/firebase.json @@ -8,9 +8,9 @@ ], "rewrites": [ { - "source": "/api/**", + "source": "/server/**", "run": { - "serviceId": "api", + "serviceId": "server", "region": "us-central1" } } diff --git a/client/rollup.config.js b/client/rollup.config.js index fa801154..8053e2df 100644 --- a/client/rollup.config.js +++ b/client/rollup.config.js @@ -38,7 +38,7 @@ export default { replace({ include: ['src/utils/config.js'], preventAssignment: false, - __api_url__: '/api', // set set in firebase.json + __api_url__: '/server', // set in firebase.json }), /** Enable using HTML as rollup entrypoint */ html({ diff --git a/client/web-dev-server.config.mjs b/client/web-dev-server.config.mjs index 6714ac02..2bf80d58 100644 --- a/client/web-dev-server.config.mjs +++ b/client/web-dev-server.config.mjs @@ -35,7 +35,7 @@ export default ({ replace({ include: ['src/utils/config.js'], preventAssignment: false, - '__api_url__': (process.env.API_URL || 'http://localhost:8000') + "/api" + '__api_url__': (process.env.API_URL || 'http://localhost:8000') + "/server" }), ] }); diff --git a/cloudbuild.yaml b/cloudbuild.yaml index 2afc1f57..e88e24b6 100644 --- a/cloudbuild.yaml +++ b/cloudbuild.yaml @@ -34,13 +34,16 @@ steps: dir: provisioning/terraform env: - PROJECT_ID=$PROJECT_ID + - REGION=$_REGION script: | #!/bin/sh terraform init - terraform apply -var project=${PROJECT_ID} -auto-approve - - # Since the client is also node-based, the firebase image can be used for this step. + terraform apply -auto-approve -no-color \ + -var project=${PROJECT_ID} \ + -var region=${REGION} + + # Only since the client is also node-based can the firebase image can be used for this step. - id: client deploy name: gcr.io/$PROJECT_ID/firebase dir: client @@ -51,8 +54,10 @@ steps: npm i npm run build - sed -i "s/__api_url__/\/api/g" dist/*.js + sed -i "s/__api_url__/\/server/g" dist/*.js firebase deploy --project $PROJECT_ID --only hosting +timeout: 1800s -timeout: 1800s \ No newline at end of file +substitutions: + _REGION: us-central1 \ No newline at end of file diff --git a/docs/admin/README.md b/docs/admin/README.md index 2ca325e0..5a093c7c 100644 --- a/docs/admin/README.md +++ b/docs/admin/README.md @@ -5,7 +5,7 @@ As a infrastructure administartor, I want to: * [manually setup Firebase against my project.](firebase-manual-setup.md) * [have terraform deploy the latest version of my container.](terraform-latest.md) * [have Django know it's own host URL for CSRF purposes.](django-self-csrf.md) - + * [extend this example application.](extending-example.md) *Want more options? [Request some new docs!](https://github.com/GoogleCloudPlatform/avocano/issues/new/choose)* \ No newline at end of file diff --git a/docs/admin/django-self-csrf.md b/docs/admin/django-self-csrf.md index e934197f..03da57db 100644 --- a/docs/admin/django-self-csrf.md +++ b/docs/admin/django-self-csrf.md @@ -1,9 +1,7 @@ # Django self-determined URL for CSRF -For Django's CSRF protections, you need to have Django know the host it's being served on. +For Django's CSRF protections, you need to have Django know the host it's being served on. You can set this manually with environment variables, but you can also interrogate the [metadata server](https://cloud.google.com/run/docs/container-contract#metadata-server) and [environment variables](https://cloud.google.com/run/docs/container-contract#services-env-vars) available by default to determine this information. - - The implementation of this can be found in the [`get_service_url`](https://github.com/GoogleCloudPlatform/avocano/search?q=get_service_url) method. It also requires the service has [permissions to view it's own metadata](server_introspection). \ No newline at end of file diff --git a/docs/admin/extending-example.md b/docs/admin/extending-example.md new file mode 100644 index 00000000..a04cf119 --- /dev/null +++ b/docs/admin/extending-example.md @@ -0,0 +1,88 @@ +# Extending the example + +If you are wanting to extend this example application, there are some development steps you're going to need to take. + +## Forking the repo, and GitHub actions + +Please feel free to fork the repo, but know that there are GitHub Actions attached to the parent repo +that probably won't automatically work with your setup. + +To disable: + + * Go to your fork's Settings + * Go to Code and Automation > Actions > General + * Under "Actions permissions", select "Disable actions". + * Click **Save**. + +## Terraform needs `state.tf` file + +If you're running the examples in an environment outside of Cloud Shell, you'll need to be aware that +the `setup.sh` created a Terraform backend state configuration for you. It's a file that's `.gitignore`d, +so you might have missed it. + +Be sure to create a `provisioning/terraform/state.tf` file with the following contents: + +*Note*: The `PROJECT_ID` is a literal replacement, and must be hardcoded (`backend` doesn't accept variables) + +``` +terraform { + backend gcs { + bucket = "terraform-PROJECT_ID" + } +} +``` + + +## Creating migrations + +When automatically generating Django migrations, you'll need to run these on your local machine so you can commit the +results to source. + +To do this, you'll need a connection to your Cloud SQL database, and your settings locally. + +### Setup Cloud SQL Auth Proxy + +Follow the [Install instructions](https://cloud.google.com/sql/docs/postgres/sql-proxy#install) for your platform. + +Saving this into your `$PATH` is a useful administration step so you can take advantage of this executable in other projects. + +### Start Cloud SQL Auth Proxy + +In a new terminal, start the proxy: + +``` +cloud_sql_proxy -instances="${PROJECT_ID}:us-central1:psql"=tcp:5432 +``` + +This will redirect this Cloud SQL instance to localhost. Because of this, you'll need to change where Django knows your database to be. + +### Copy and edit settings + +1. Navigate to the server config: + + ``` + cd server + ``` + +1. Copy the Django settings from Secret Manager to your local `.env` file. + Note: this file is `.gitignore`d. + + ``` + gcloud secrets versions access latest --secret django_settings > .env + ``` + +1. Edit the `DATABASE_URL` line to replace the `cloudsql` config to `localhost`: + + ```diff + -DATABASE_URL="postgres://server:password@//cloudsql/yourproject:us-central1:psql/django" + +DATABASE_URL="postgres://server:password@localhost/django" + ``` + +1. Run your code on your local machine: + + ``` + python manage.py runserver + ``` + + +From here, you should be able to run `makemigrations` and other tasks. \ No newline at end of file diff --git a/docs/django/README.md b/docs/django/README.md index a036e6dd..19661cdc 100644 --- a/docs/django/README.md +++ b/docs/django/README.md @@ -5,6 +5,7 @@ As a Django administrator, I want to: * [log into the Django Admin.](login-django-admin.md) * [update the product listing.](update-product-listing.md) * [change the look and feel of the website.](update-site-config.md) + * [apply database migrations](apply-migrations.md) *Want more options? [Request some new docs!](https://github.com/GoogleCloudPlatform/avocano/issues/new/choose)* \ No newline at end of file diff --git a/docs/django/apply-migrations.md b/docs/django/apply-migrations.md new file mode 100644 index 00000000..45070fc4 --- /dev/null +++ b/docs/django/apply-migrations.md @@ -0,0 +1,24 @@ +# Applying database migrations + +If you want to apply database migrations, a convenience Cloud Run job has been created for you. + +To run migrations: + +``` +gcloud beta run jobs execute migrate-database \ + --region us-central1 --wait +``` + +To run migrations as part of the Cloud Build, add a step to the `cloudbuild.yaml` file: + +``` + - id: server migrate + name: "gcr.io/google.com/cloudsdktool/cloud-sdk:slim" + entrypoint: gcloud + args: ["beta", "run", "jobs", "execute", "migrate-database", + "--region", $_REGION, "--wait"] +``` + +This step must be after the image push step, but can be before or after Terraform (the terraform step +updates the Cloud Run service to the latest image). If your database changes must be made **before** +the application is updated, put it before the terraform step. diff --git a/docs/user/view-products.md b/docs/user/view-products.md index 69e92bea..e821e5f4 100644 --- a/docs/user/view-products.md +++ b/docs/user/view-products.md @@ -13,4 +13,4 @@ If on any product listing you click "Buy", you'll be told "Oops! Sorry! This is **This is expected**. This application isn't designed as a full retail store, merely an "April's Fools Day" "fake product" listing site. -Yes, we wish there were such things as Sparkly Avocadoes, too. \ No newline at end of file +Yes, we wish there were such things as Sparkly Avocados, too. \ No newline at end of file diff --git a/provisioning/terraform/container.tf b/provisioning/terraform/container.tf index 8c4a0b54..fa1a4134 100644 --- a/provisioning/terraform/container.tf +++ b/provisioning/terraform/container.tf @@ -13,8 +13,8 @@ data "google_client_config" "default" {} locals { # these match the values in /cloudbuild.yaml - gcr_hostname = "gcr.io" - server_image = "server" + gcr_hostname = "gcr.io" + server_image = var.service_name image_registry = "${local.gcr_hostname}/${var.project}" } diff --git a/provisioning/terraform/database.tf b/provisioning/terraform/database.tf index fa0660d5..809ebd4e 100644 --- a/provisioning/terraform/database.tf +++ b/provisioning/terraform/database.tf @@ -16,9 +16,8 @@ resource "google_sql_database_instance" "postgres" { } ## Database - resource "google_sql_database" "database" { - name = "django" + name = var.database_name instance = google_sql_database_instance.postgres.name } @@ -26,7 +25,7 @@ resource "google_sql_database" "database" { ## Details used in Django config settings # NOTE: users created this way automatically gain cloudsqladmin rights. resource "google_sql_user" "django" { - name = "server" + name = var.database_username instance = google_sql_database_instance.postgres.name password = random_password.database_user_password.result } diff --git a/provisioning/terraform/secrets.tf b/provisioning/terraform/secrets.tf index 57729609..8dc11a2b 100644 --- a/provisioning/terraform/secrets.tf +++ b/provisioning/terraform/secrets.tf @@ -41,7 +41,7 @@ resource "google_secret_manager_secret" "django_settings" { ## Django configuration settings resource "google_secret_manager_secret_version" "django_settings" { - secret = google_secret_manager_secret.django_settings.id + secret = google_secret_manager_secret.django_settings.id secret_data = <