Skip to content

Instantly share code, notes, and snippets.

@mau21mau
Last active April 9, 2024 10:51
Show Gist options
  • Save mau21mau/e6fcd6f611f4320a9f8e15ffa16341ac to your computer and use it in GitHub Desktop.
Save mau21mau/e6fcd6f611f4320a9f8e15ffa16341ac to your computer and use it in GitHub Desktop.
Configure Google Cloud's Cloud Run service with custom domain

These are the steps to Deploy a Cloud Run service that will:

  1. Communicate with the internet passing through your VPC.
  2. Be accessible through a custom domain managed outside GCP.

NOTE: If your VPC has a Nat Gateway and Router with an static IP address, then your Cloud Run will have a static Outbound IP allowing things like database whitelisting.

Now with the steps:

  1. Create and static preimum Global IP to bind to the LoadBalancer later. Point the subdomain to that IP on CloudFlare
PROJECT_ID=<set-your-own>
REGION=us-central1
SERVICE_NAME=<set-your-own>
NETWORK_NAME=<set-your-own>
SUBNET_NAME=<set-your-own>-servless-connector
SUBNET_CIDR_RANGE=11.0.0.0/28
VPC_CONNECTOR_NAME=serveless-connector
IMAGE_PATH=<set-your-own>
SERVICE_ACCOUNT_EMAIL=<set-your-own>
SERVICE_ENVS="^;^FOO=BAR;HELLO=WORLD"
CERTIFICATE_DOMAIN=<set-your-own>

NOTE: VPC_CONNECTOR_NAME needs to be smaller than 23 characters

  1. Create Subnet for VPC Serverless Connector
gcloud compute networks subnets create $SUBNET_NAME \
--network=$NETWORK_NAME \
--range=$SUBNET_CIDR_RANGE \
--region=$REGION \
--project=$PROJECT_ID
  1. Create VPC Serverless Connector
gcloud compute networks vpc-access connectors create $VPC_CONNECTOR_NAME \
--region=$REGION \
--subnet=$SUBNET_NAME \
--min-instances=2 \
--max-instances=10 \
--machine-type=e2-micro \
--project=$PROJECT_ID
  1. Deploy your Clour Run/Function
gcloud beta run deploy $SERVICE_NAME \
--image=$IMAGE_PATH \
--allow-unauthenticated \
--port=8080 \
--service-account=$SERVICE_ACCOUNT \
--vpc-connector=$VPC_CONNECTOR_NAME \
--vpc-egress=all-traffic \
--timeout=600 \
--cpu=1 \
--memory=128Mi \
--max-instances=1 \
--concurrency=10 \
--set-env-vars=$SERVICE_ENVS \
--region=$REGION \
--project=$PROJECT_ID
  1. Create network endpoint group (NEG) fro the Cloud Run service
gcloud compute network-endpoint-groups create ${SERVICE_NAME} \
--project=$PROJECT_ID \
--region=$REGION \
--network=$NETWORK_NAME \
--network-endpoint-type=GCE_VM_IP_PORT \
--subnet=$SUBNET_NAME \
--network-endpoint-type=serverless \
--cloud-run-service=$SERVICE_NAME
  1. Create Backend Service for our LoadBalancer
gcloud compute backend-services create ${SERVICE_NAME}-back-end \
    --load-balancing-scheme=EXTERNAL \
    --project=$PROJECT_ID \
    --global
  1. Set Cloud Run's Network Endpoint Group (NEG created earlier) as the Backend of the Backend Service from previous step
gcloud compute backend-services add-backend ${SERVICE_NAME}-back-end \
    --global \
    --network-endpoint-group=${SERVICE_NAME} \
    --project=$PROJECT_ID \
    --network-endpoint-group-region=$REGION
  1. Create URL Map (LoadBalancer itself) pointing it to the recently configured Backendd Service
gcloud compute url-maps create ${SERVICE_NAME}-load-balancer \
    --project=$PROJECT_ID \
    --default-service ${SERVICE_NAME}-back-end
  1. Create the certificate
gcloud beta compute ssl-certificates create ${SERVICE_NAME}-certificate \
--project=$PROJECT_ID \
--global \
--domains=$CERTIFICATE_DOMAIN

NOTE: Make sure you have pointed the domain to the previously reserved Premium Global IP

  1. Then, go to LoadBalancer at the Browser's Console interface, edit the LoadBalancer then:
  1. Click "ADD FRONTEND IP AND PORT".
  2. Give it a name
  3. At "Protocol" select "HTTPS(includes HTTP/2)" on the dropdown.
  4. At "IP Address" select the previously reserved Premium Global IP.
  5. At "Certificate" select the previously created Certificate on the dropdown.
  6. Check "Enable HTTP to HTTPS redirect" to create a secondary HTTP LoadBalancer to serve as proxy for redirecting HTTP request to HTTPS.
  7. Click "UPDATE" to update the LoadBalancer.
  8. Go to the Certificates Tab and wait for your certifcate "Status" to be "Active"

NOTE: Even after the certificate "Status" becomes "Active", it might take a few minutes for your service be available at the domain.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment