I recently developed a web app end-to-end at work which was my first endevaour into full stack web development. While I plan to write another post about the journey of learning NextJS, I wanted to share the cloud architecture I set up to host this app using Google Cloud.
Automated Deployment
So first up we have the deployment pipeline using Cloud Build which I have previously written about. For this project, I set up multiple cloudbuild.yaml
files in my github repo to effectively use different branches to publish the staging and production versions of the app. Some of the key operations Cloud Build was running:
- Connect to Secret Manager to rebuild .env file
- Use docker build arguments to set the environment as staging or production
- Build the docker image
- Push it to the container registry
- Finally, deploy the container on Cloud Run
Extra note here that I also used this step to connect a VPC subnet to direct all traffic to the cloud run service, more on that in a sec..
VPC Router
For this project, a requirement was for the backend service to use a static IP to enable interaction with APIs using IP whitelisting. While I am still new to the world of networking, I was able to follow this docs guide to set up a subnet to route all the Cloud Run traffic through, ensuring all backend requests to external APIs came from a static IP.
Load Balanacer
Sitting in front of the Cloud Run service, I set up a load balancer, allowing us to intercept traffic and set a static IP from the front end and linking that to a custom domain.
Logging
Not shown in my diagram, the NextJS app itself was also configured to send logs to Google Cloud logging using their Winston Client Library. To enable this, I had to set up a service account which only needed Logs Creator
role and store the json key within the app. I used the same technique as rebuilding the .env variables to store the key in secret manager and inject it into the app at deployment via Cloud Build.
Authenticated Google Account Calls
Some of the external API calls my app makes was to other cloud run services. Rather than setting the security on these to be public, I granted the service account Cloud Run Invoker
permission and used the Google Auth Library to make authenticated requests with the service account's IAM permissions, meaning my target Cloud Run API could retain the extra layer of security.
All in all, this project was a great challenge for learning the concepts of web development and how that fit in with my existing knowledge of Google's cloud environment.
Top comments (1)
This is a really insightful breakdown of the GCP tech stack for a serverless Next.js web app. I'm particularly interested in how you used Cloud Build to manage deployments and how you integrated the VPC router to secure external API interactions.