Demystifying GCP: Building a Simple Web Application Architecture with Cloud Run and MongoDB

Omer Arshad
7 min readOct 8, 2023

--

Dive into the intricacies of Google Cloud Platform as we construct a streamlined web application architecture using Cloud Run and MongoDB. This guide offers a high-level overview, shedding light on the essential components and their synergy.

Cloud infrastructure has become the go-to solution for hosting services in the realm of web-based applications. AWS, Azure, and Google Cloud Platform (GCP) are among the giants in this space. While these platforms offer many tools and services to facilitate complex infrastructures, setting up even a basic application can sometimes feel like navigating a maze. The ease of running services often contrasts with the intricacy of building, managing, and securing the underlying infrastructure.

This article will explore a straightforward GCP architecture designed for a basic application. This application comprises two services: an API and a UI hosted on Cloud Run and a MongoDB database instance on Compute Engine. While the architecture might seem intricate initially, this overview remains high-level. We won’t dive deep into security measures, service accounts, or roles. Instead, our focus will be on the fundamental components that make up this architecture. A step-by-step guide on constructing this in GCP is beyond the scope of this piece.

The diagram above illustrates two applications hosted on GCP’s Cloud Run. These applications interface with the external world via an IP address and internally connect to a MongoDB instance on Compute Engine. As depicted in the diagram, numerous components work together to realise this setup.

Let’s break it down, examining each component’s role.

Imagine starting with a blank slate. We’ll sequentially introduce each component, understanding its significance and role in the grand scheme of things.

Typically, your first step in GCP would be establishing a private Virtual Private Cloud (VPC) network. While GCP does provide a default network upon project creation, it’s often recommended, for enhanced security and alignment with best practices, to initiate with a custom VPC network.

A Virtual Private Cloud (VPC) network in GCP is a private, isolated section of Google Cloud where resources can securely communicate using internal IP addresses. Each VPC network is a global entity spanning all GCP regions, ensuring that resources across regions can communicate with one another without requiring public IP addresses or traversing the public internet.

Within a VPC, you can define subnetworks, which are regional entities. Each subnetwork has its IP address range, allowing you to segment and organise your resources based on IP addresses.

At its core, a private VPC is akin to a sealed box. It neither accepts incoming traffic nor allows outgoing traffic. Even inter-service communication within this network is restricted. Once your VPC network is in place, you’ll configure firewall rules to address this. These rules can be tailored to permit internal communication, refuse external traffic to specific IP addresses, or allow only certain protocols, among other configurations.

Upon establishing a new private VPC, it’s crucial to recognise that, by default, it doesn’t permit any service within this network to communicate with the external world. To facilitate such communication, you must integrate the GCP Compute Router NAT with the Compute Router. This setup enables services within the VPC network to reach external resources. Depending on your specific system requirements, this might only sometimes be necessary. However, for our use case, since we aim to set up a MongoDB instance on our Compute Engine (within the same VPC Network), we require internet connectivity to download the MongoDB binaries.

With the VPC network configured, it’s time to launch a Compute Engine instance, associating it with the private VPC Network. Post-creation, you can SSH into the instance to install MongoDB. Alternatively, a more streamlined approach is initialising the Compute Engine with a startup script. This script can be programmed to auto-install MongoDB immediately after creating the instance. Since our VPC Network has NAT access, downloading and installing the MongoDB binaries is straightforward.

Upon successfully creating and configuring the MongoDB instance, GCP assigns it a private IP address. Based on the earlier VPC firewall rules, any service linked to this VPC network can connect to our MongoDB instance using this private IP. While this setup is functional, it poses a challenge. Suppose multiple services connect to our database, and the IP address changes (perhaps due to an upgrade or a different instance). In that case, we’d need to update all services referencing our MongoDB instance. We introduce a Private DNS zone linked to the VPC network to circumvent this. This allows us to associate a custom hostname with our MongoDB instance’s IP address. Consequently, services can connect to MongoDB using this hostname, ensuring that service configurations remain unaffected even if the IP changes in the future.

Our VPC network configuration is nearing completion, but there’s one component left to address. We intend to deploy our application on Cloud Run, a serverless environment. By nature, serverless environments are somewhat isolated, existing in their network space. To enable communication between our Cloud Run services and the resources within our VPC network, we introduce the Serverless VPC Access Connector.

With these components in place, our VPC setup is comprehensive and primed. We can now proceed to develop our services on Cloud Run.

With the foundational infrastructure, it’s time to deploy your UI and backend API applications on Cloud Run. To enable the backend API to communicate with MongoDB, ensure that the API service on Cloud Run is linked to the VPC Access Connector we established earlier. This connection facilitates seamless interaction between our API service and the database.

While our applications are now operational and integrated with the database, external accessibility remains a challenge. You can access them via the unique URLs GCP assigns to each Cloud Run service. However, for a more professional and streamlined user experience, we aim to access our services through a custom domain. If we were dealing with a single service, GCP offers a straightforward method to bind a custom domain to a Cloud Run service. But our scenario involves two services, necessitating a more nuanced approach. Ideally, we’d want URL-based routing for an application with a domain like xyz.com: calls to /api should route to the API service, while other requests should direct to the UI service.

We begin by provisioning a single external IP address and linking it to HTTP and HTTPS load balancers to realise this.

With the external IP in place, we proceed to set up two distinct load balancers: one for HTTP and another for HTTPS. The HTTP setup is straightforward; we don’t intend to serve our application over HTTP, so we configure the HTTP load balancer to redirect all requests to its HTTPS counterpart. Setting up the HTTPS load balancer requires an SSL certificate. Fortunately, GCP has significantly simplified this process, allowing users to generate SSL certificates directly within the cloud console. This feature eliminates the often cumbersome task of sourcing certificates externally.

After generating and securing the SSL certificate, it’s attached to our HTTPS load balancer. Additionally, we define URL mapping rules for the HTTPS load balancer, ensuring that incoming requests are correctly routed based on their URLs.

With these configurations in place, our streamlined cloud infrastructure is fully operational and ready to serve.

Conclusion

In today’s digital age, the cloud has revolutionised how we deploy, manage, and scale applications. While platforms like GCP offer a vast array of tools and services, navigating the intricacies of cloud architecture can sometimes be daunting. However, as we’ve explored in this article, with a systematic approach and a clear understanding of each component’s role, even seemingly complex architectures can easily be broken down and understood.

We’ve walked through the creation of a simple yet robust GCP architecture designed to serve both UI and API applications while ensuring secure and efficient communication with a MongoDB instance. By leveraging Cloud Run, VPC networks, load balancers, and other GCP offerings, we’ve demonstrated how to build a scalable and secure infrastructure ready for real-world challenges.

As you embark on your cloud journey, remember that while the tools and technologies are crucial, the strategy and understanding genuinely make a difference. Whether building a simple application or a complex multi-tiered system, a well-thought-out architecture is the foundation of any successful digital solution.

Thank you for joining me on this exploration, and here’s to your success in the cloud!

--

--

Omer Arshad
Omer Arshad

Written by Omer Arshad

Scala | Java Developer — I help companies deliver innovative IT solutions.