Deploying Hasura GraphQL Engine on Cloud Run
To deploy Hasura GraphQL Engine on Google Cloud Run with a Cloud SQL (Postgres) instance and ensure secure communication via private IP, follow this detailed guide.
This guide assumes you have a Google Cloud account and gcloud
installed. Additionally, you should be working within a Google Cloud Project, whether it's one you've newly created or an existing project you have access to.
Step 1: Setup Your Environment
- Authenticate with Google Cloud:
gcloud auth login
- Set your project ID:
Replace <PROJECT_ID>
with your actual Google Cloud project ID.
gcloud config set project <PROJECT_ID>
Step 2: Enable Required Google Cloud Services
Enable Cloud Run, Cloud SQL, Cloud SQL Admin, Secret Manager, and the Service Networking APIs:
gcloud services enable run.googleapis.com sqladmin.googleapis.com servicenetworking.googleapis.com secretmanager.googleapis.com
To execute the above command, your Google Cloud account needs to have the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin) or an equivalent custom role with permissions to enable services. This role allows you to view, enable, and disable services in your GCP project.
If you encounter permissions errors, contact your GCP administrator to ensure your account has the appropriate roles assigned, or to request the services be enabled on the project you are working with.
Step 3: Create a Cloud SQL (Postgres) Instance
- Create the database instance:
gcloud sql instances create hasura-postgres --database-version=POSTGRES_15 --cpu=2 --memory=7680MiB --region=us-central1
- Set the password for the default postgres user:
Replace <PASSWORD>
with your desired password.
gcloud sql users set-password postgres --instance=hasura-postgres --password=<PASSWORD>
- Create a database
Replace <DATABASE_NAME>
with your database name:
gcloud sql databases create <DATABASE_NAME> --instance=hasura-postgres
default
network?The default
network is normally created inside a Google Cloud Platform Project, however in some cases the default
network might have been deleted or the project may have been set up with a specific network configuration without a default network.
To see the networks you have available you can run:
gcloud compute networks list
If you find you do not have an appropriate network for your deployment, you can create a new VPC network by running the following command to create a network named default
:
gcloud compute networks create default --subnet-mode=auto
Step 4: Configure Service Networking for Private Connectivity
- Allocate an IP range for Google services in your VPC:
gcloud compute addresses create google-managed-services-default \
--global \
--purpose=VPC_PEERING \
--prefix-length=24 \
--network=default
- Connect your VPC to the Service Networking API:
Replace <PROJECT_ID>
with your actual Google Cloud project ID.
gcloud services vpc-peerings connect \
--service=servicenetworking.googleapis.com \
--ranges=google-managed-services-default \
--network=default \
--project=<PROJECT_ID>
- Enable a private IP for your CloudSQL instance:
gcloud sql instances patch hasura-postgres --network=default
Step 5: Create your connection string
- Find your Cloud SQL instance's connection name:
gcloud sql instances describe hasura-postgres
Take note of the connectionName
field in the output of the above describe
command. You will use the connectionName
to deploy the GraphQL Engine to Cloud Run.
- Construct your connection string
You can create the connection string by filling in the following template string. Replace <CONNECTION_NAME>
, <PASSWORD>
, and <DATABASE_NAME>
with your actual connectionName, database password, and
database name.
postgres://postgres:<PASSWORD>@/<DATABASE_NAME>?host=/cloudsql/<CONNECTION_NAME>
Step 6: Store your connection string in the Secret Manager
While you can put the connection string directly into the environment variables, it is recommended that you store it and any secrets or credentials inside of Google's Secret Manager for maximum security. This prevents secrets from being visible to administrators and from being accessible in other parts of the control/operations plane.
- Store the constructed connection string as a secret replacing
<CONNECTION_STRING>
with your actual connection string.
echo -n "<CONNECTION_STRING>" | gcloud secrets create hasura-db-connection-string --data-file=-
default
service account?The following steps assume that you are running the gcloud deploy
command via the default service account used by compute engine. If you are not using the default service account, you will need to grant the service account you are using the roles/secretmanager.secretAccessor
role.
- To get the
<PROJECT_NUMBER>
associated with the default service account:
echo "$(gcloud projects describe $(gcloud config get-value project) --format='value(projectNumber)')"
Run the following command to grant the default service acount access to the secrets, replacing
<PROJECT_NUMBER>
with your project number from the previous command:gcloud projects add-iam-policy-binding <PROJECT_NUMBER> \
--member='serviceAccount:<PROJECT_NUMBER>[email protected]' \
--role='roles/secretmanager.secretAccessor'
Step 7: Deploy Hasura to Cloud Run:
- Run the following command and replace
<CONNECTION_NAME>
, with your actual connectionName.
For additional information on configuring the Hasura GraphQL engine, please see the Server configuration reference.
gcloud run deploy hasura-graphql-engine \
--image=hasura/graphql-engine:latest \
--add-cloudsql-instances=<CONNECTION_NAME> \
--update-env-vars='HASURA_GRAPHQL_ENABLE_CONSOLE=true' \
--update-secrets=HASURA_GRAPHQL_DATABASE_URL=hasura-db-connection-string:latest \
--region=us-central1 \
--cpu=1 \
--min-instances=1 \
--memory=2048Mi \
--port=8080 \
--allow-unauthenticated
Step 8: Adding a VPC-Connector (Optional)
To further enhance the connectivity and security of your Hasura GraphQL Engine deployment on Google Cloud Run, especially when connecting to other services within your Virtual Private Cloud (VPC), you might consider adding a Serverless VPC Access connector. This optional step is particularly useful when your architecture requires direct access from your serverless Cloud Run service to resources within your VPC, such as VMs, other databases, or private services that are not exposed to the public internet. For more information, please see Google's official documentation for Serverless VPC Access.
- Enable the Serverless VPC Access API
First ensure that the Serverless VPC Access API is enabled:
gcloud services enable vpcaccess.googleapis.com
- Create a Serverless VPC Access Connector
Choose an IP range that does not overlap with existing ranges in your VPC. This range will be used by the connector to route traffic from your serverless application to your VPC. It's important to ensure that the IP range does not overlap with other subnets to avoid routing conflicts.
gcloud compute networks vpc-access connectors create hasura-connector \
--region=us-central1 \
--network=default \
--range=10.8.0.0/28
- Update the Cloud Run Deployment to use the VPC Connector
When deploying or updating your Hasura GraphQL Engine service, specify the VPC connector with the --vpc-connector
flag:
gcloud run deploy hasura-graphql-engine \
--image=hasura/graphql-engine:latest \
--add-cloudsql-instances=<CONNECTION_NAME> \
--update-env-vars='HASURA_GRAPHQL_ENABLE_CONSOLE=true' \
--update-secrets=HASURA_GRAPHQL_DATABASE_URL=hasura-db-connection-string:latest \
--vpc-connector=hasura-connector \
--region=us-central1 \
--cpu=1 \
--min-instances=1 \
--memory=2048Mi \
--port=8080 \
--allow-unauthenticated
When and Why to Use a VPC Connector
- Enhanced Security: Utilize a VPC Connector when you need to ensure that traffic between your Cloud Run service and internal Google Cloud resources does not traverse the public internet, enhancing security.
- Access to Internal Resources: Use it when your serverless application needs access to resources within your VPC, such as internal APIs, databases, or services that are not publicly accessible.
- Compliance Requirements: If your application is subject to compliance requirements that mandate data and network traffic must remain within a private network, a VPC connector facilitates this by providing private access to your cloud resources.
- Network Peering: It's beneficial when accessing services in a peered VPC, allowing your Cloud Run services to communicate with resources across VPC networks.
Adding a VPC Connector to your Cloud Run deployment ensures that your Hasura GraphQL Engine can securely and privately access the necessary Google Cloud resources within your VPC, providing a robust and secure environment for your applications.
Tearing Down
To avoid incurring charges, delete the resources once you're done:
gcloud sql instances delete hasura-postgres
gcloud run services delete hasura-graphql-engine
gcloud compute addresses delete google-managed-services-default --global
gcloud secrets delete hasura-db-connection-string
If you performed the optional Step 8, you should also delete the VPC-connector resource:
gcloud compute networks vpc-access connectors delete hasura-connector --region=us-central1