Hasura GraphQL engine on Azure with Container Instances and Postgres
Introductionβ
This guide walks you through deploying the Hasura GraphQL engine on Azure using Container Instances with Azure Database for PostgreSQL server.
One-click deployment using ARM Templateβ
You can deploy all the resources mentioned in this guide with the one-click button below.
- With a new Postgres Server
- With an existing Postgres Server
(This button takes you to the Azure Portal. You might want to Ctrl+Click
to open it in a new tab. Read more about this Resource
Manager Template here).
(This button takes you to the Azure Portal. You might want to Ctrl+Click
to open it in a new tab. Read more about this Resource
Manager Template here).
Pre-requisitesβ
- Valid Azure subscription with billing enabled or credits (click here for a free trial).
- Azure CLI.
The actions mentioned below can be executed using the Azure Portal and the Azure CLI. But for the sake of simplicity in documentation, we are using Azure CLI; so that commands can be easily copy-pasted and executed.
Once you install the CLI
, login to your Azure account:
az login
Create a new Resource Groupβ
The Resource Groups are used to group various resources on Azure. Create a resource group called hasura
at the westus
location.
az group create --name hasura --location westus
Provision a PostgreSQL serverβ
Note
If you already have a database setup, you can skip these steps and jump directly to Allow access to Azure Services.
After you create the resource group, create a Postgres server instance:
az postgres server create --resource-group hasura \
--name "<server_name>" \
--location westus \
--admin-user hasura \
--admin-password "<server_admin_password>" \
--sku-name GP_Gen5_2 \
--version 10
Note
- Choose a unique name for
<server_name>
variable. - Select a strong password for the
<server_admin_password>
variable, that must include uppercase, lowercase, and numeric characters. You will need the password later to connect to the database. (make sure you escape the special characters depending on your shell).
Note the hostname in the output, as indicated below:
...
"fullyQualifiedDomainName": "<server_name>.postgres.database.azure.com",
...
where; <server_name>.postgres.database.azure.com
is the hostname.
Note
If you get an error saying Specified server name is already used
, change the value of --name
(<server_name>
) to something else.
Create a new databaseβ
Create a new database on the server:
az postgres db create --resource-group hasura \
--server-name "<server_name>" \
--name hasura
Allow access to Azure Servicesβ
Create a firewall rule allowing access from Azure internal services:
az postgres server firewall-rule create --resource-group hasura \
--server-name "<server_name>" \
--name "allow-azure-internal" \
--start-ip-address 0.0.0.0 \
--end-ip-address 0.0.0.0
Create a Container Instanceβ
Launch Hasura using a container instance:
az container create --resource-group hasura \
--name hasura-graphql-engine \
--image hasura/graphql-engine \
--dns-name-label "<dns-name-label>" \
--ports 80 \
--environment-variables "HASURA_GRAPHQL_SERVER_PORT"="80" "HASURA_GRAPHQL_ENABLE_CONSOLE"="true" "HASURA_GRAPHQL_ADMIN_SECRET"="<admin-secret>"\
--secure-environment-variables "HASURA_GRAPHQL_DATABASE_URL"="<database-url>"
<database-url>
should be replaced by the following format:
postgres://hasura%40<server_name>:<server_admin_password>@<hostname>:5432/hasura
If you'd like to connect to an existing database, use that server's database url.
Note
%40
is used in the username because Azure creates usernames as
[email protected]
and since the database url uses @
to separate
username-password from hostname, we need to url-escape it in the
username. Any other special character should be url-encoded.
If the <dns-name-label>
is not available, choose another unique name and execute the command again.
Setting up JWTβ
Use the HASURA_GRAPHQL_JWT_SECRET
env variable to setup JWT. To generate a new JWT config refer here.
Note
The HASURA_GRAPHQL_JWT_SECRET
env variable requires JSON format. To create a container group with az container create --environment-variables
flag you need to pass the variable as a key-value pair.
In order to use the env variable with the az container create
command,
pass the JSON value for the env variable as a string by escaping the characters like so:
az container create --resource-group hasura \
--name hasura-graphql-engine \
--image hasura/graphql-engine \
--dns-name-label "<dns-name-label>" \
--ports 80 \
--environment-variables "HASURA_GRAPHQL_SERVER_PORT"="80" \
"HASURA_GRAPHQL_ENABLE_CONSOLE"="true" \
"HASURA_GRAPHQL_ADMIN_SECRET"="<admin-secret>" \
"HASURA_GRAPHQL_JWT_SECRET"= \ "{\"type\": \"RS512\",\"key\": \"-----BEGIN CERTIFICATE-----\\nMIIDBzCCAe+gAwIBAgIJTpEEoUJ/bOElMA0GCSqGSIb3DQEBCwUAMCExHzAdBgNV\\nBAMTFnRyYWNrLWZyOC51cy5hdXRoMC5jb20wHhcNMjAwNzE3MDYxMjE4WhcNMzQw\\nMzI2MDYxMjE4WjAhMR8wHQYDVQQDExZ0cmFjay1mcjgudXMuYXV0aDAuY29tMIIB\\nIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuK9N9FWK1hEPtwQ8ltYjlcjF\\nX03jhGgUKkLCLxe8q4x84eGJPmeHpyK+iZZ8TWaPpyD3fk+s8BC3Dqa/Sd9QeOBh\\nZH/YnzoB3yKqF/FruFNAY+F3LUt2P2t72tcnuFg4Vr8N9u8f4ESz7OHazn+XJ7u+\\ncuqKulaxMI4mVT/fGinCiT4uGVr0VVaF8KeWsF/EJYeZTiWZyubMwJsaZ2uW2U52\\n+VDE0RE0kz0fzYiCCMfuNNPg5V94lY3ImcmSI1qSjUpJsodqACqk4srmnwMZhICO\\n14F/WUknqmIBgFdHacluC6pqgHdKLMuPnp37bf7ACnQ/L2Pw77ZwrKRymUrzlQID\\nAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSOG3E+4lHiI+l0i91u\\nxG2Rca2NATAOBgNVHQ8BAf8EBAMCAoQwDQYJKoZIhvcNAQELBQADggEBAKgmxr6c\\nYmSNJOTPtjMFFDZHHX/7iwr+vqzC3nalr6ku8E3Zs0/IpwAtzqXp0eVVdPCWUY3A\\nQCUTt63GrqshBHYAxTbT0rlXFkqL8UkJvdZQ3XoQuNsqcp22zlQWGHxsk3YP97rn\\nltPI56smyHqPj+SBqyN/Vs7Vga9G8fHCfltJOdeisbmVHaC9WquZ9S5eyT7JzPAC\\n5dI5ZUunm0cgKFVbLfPr7ykClTPy36WdHS1VWhiCyS+rKeN7KYUvoaQN2U3hXesL\\nr2M+8qaPOSQdcNmg1eMNgxZ9Dh7SXtLQB2DAOuHe/BesJj8eRyENJCSdZsUOgeZl\\nMinkSy2d927Vts8=\\n-----END CERTIFICATE-----\"}"
--secure-environment-variables "HASURA_GRAPHQL_DATABASE_URL"="<database-url>"
Note
Check out the Running with JWT section for the usage of HASURA_GRAPHQL_JWT_SECRET
env variable.
Open the Hasura Consoleβ
That's it! Once the deployment is complete, navigate to the container instance's IP or hostname to open the Hasura console:
az container show --resource-group hasura \
--name hasura-graphql-engine \
--query "{FQDN:ipAddress.fqdn,ProvisioningState:provisioningState}" \
--out table
The output will contain the FQDN in the format <dns-name-label>.westus.azurecontainer.io
.
Visit the following URL for the Hasura console:
http://<dns-name-label>.westus.azurecontainer.io/console
Replace <dns-name-label>
with the label given earlier.

You can create tables and test your GraphQL queries here.
Troubleshootingβ
If your password contains special characters, check if the password is URL encoded and given as env variables. Also, check for proper escaping of these characters based on your shell.
You can check the logs to see if the database credentials are proper and if Hasura is able to connect to the database.
If you're using an existing/external database, make sure the firewall rules for the database allows connection for Azure services.
Checking logsβ
If the console doesn't load, check the logs:
az container logs --resource-group hasura \
--name hasura-graphql-engine \
--container-name hasura-graphql-engine
# use --follow flag to stream logs
Tearing downβ
To clean up the deployment, delete the resource group:
az group delete --resource-group hasura