Serving Totopos
Add totopo to your own dishes.

I've talked about Totopo - the barebones mustache interpolating HTTP server - in a previous post. I mentioned I was using Topopo to serve this website, and I also promised to have instructions published on how to get it running in your own Google Cloud account. So here we go.

I'm writing these instructions as a way to describe the logical steps. But really, if one wanted to get Totopo up and running, the setup.sh script should be a good starting point.

Totopo - at the time of this write up - compiles and runs in Google Cloud, it uses Cloud Run + Cloud Storage at runtime, and Cloud Build + Cloud Source at compile time. So the first step is to set some variables in the environment to make the rest of the commands less verbose.

$ RUN_REGION=<specify-a-cloud-region-here>
$ PROJECT_ID=<specify-a-cloud-project-id-here>
$ SERVICE_ACCOUNT_ID=<specify-a-proper-service-account-name-here>
$ SERVICE_ACCOUNT_DISPLAY=${SERVICE_ACCOUNT_ID}
$ SERVICE_ACCOUNT_NAME=${SERVICE_ACCOUNT_ID}@${PROJECT_ID}.iam.gserviceaccount.com
$ PROJECT_NUMBER=`gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)"`

Once getting variables out of the way, the next step is to enable the required APIs in the Google Cloud account:

$ gcloud services enable cloudbuild.googleapis.com
$ gcloud services enable artifactregistry.googleapis.com
$ gcloud services enable sourcerepo.googleapis.com
$ gcloud services enable run.googleapis.com

After the services are enabled in the account, one should proceed to create a new service account under which the new Totopo instance would run. This is recommended to better isolate the resources the Totopo instance has access to.

$ gcloud iam service-accounts create ${SERVICE_ACCOUNT_ID} \
--description="Account used to build and run totopo instances" \
--display-name="${SERVICE_ACCOUNT_DISPLAY}"
$ gcloud iam service-accounts add-iam-policy-binding ${SERVICE_ACCOUNT_NAME} \
--member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
--role="roles/iam.serviceAccountUser"

Once accounting is completed, the Cloud Build script can be run. This build uses cloudbuild.yaml, which tells Cloud Build how compile and deploy Totopo to Cloud Run. Because cloudbuild.yaml uses replacement variables the following values need to be set in the environment.

$ TOTOPO_CDN_URL=<specify-a-url-serving-static-content-here>
$ TOTOPO_BUCKET_URI=<specify-a-bucket-containing-mustache-templates-here>
$ BUILD_SUBSTITUTIONS=$(printf %s \
'_SERVICE_ACCOUNT_NAME="${SERVICE_ACCOUNT_NAME}"' \
',_RUN_INSTANCE_NAME="${RUN_INSTANCE_NAME}"' \
',_RUN_SERVICE_ACCOUNT="${SERVICE_ACCOUNT_NAME}"' \
',_RUN_REGION="${RUN_REGION}"' \
',_TOTOPO_CDN_URL="${TOTOPO_CDN_URL}"' \
',_TOTOPO_BUCKET_URI="${TOTOPO_BUCKET_URI}"')

In the previous command, the CDN URL is used to specify a base path where static resources can be served from. Totopo templates that use the {{#StaticResource}}{{/StaticResource}} function, use the specified value as the base for those resources. And the bucket URI is the Cloud Storage path used as an alternative to the container local filesystem.

Once these variables are set, the final command can be run to request a build:

$ gcloud builds submit \
--config scripts/gcloud/cloudbuild.yaml \
--substitutions=${BUILD_SUBSTITUTIONS} ./

The build will run in Cloud Build for a while, and eventually will have an instance of the resulting container in Cloud Run.

To recap, these are the logical steps required to run an instance of Totopo in your own Cloud account:

  1. Set up Totopo and Cloud variables.
  2. Enable services/APIs in Cloud account.
  3. Create service account with the required permissions for Totopo.
  4. Request a build.

That's it, you should have a running instance of Totopo! you should be ready to start troubleshooting why your own instance didn't start.

2021-02-07 Guillermo Sandoval