Tutorial: Using Service Connector to build a Django app with Postgres on Azure App Service
Article
Note
In this tutorial, you use Service Connector to connect a web app to a database service. This tutorial is a modification of the App Service tutorial, so you may see some similarities. Look into section Create a passwordless connector to Postgres database to see where Service Connector comes into play and simplifies the connection process given in the App Service tutorial.
Launch from Azure Cloud Shell in the Azure Portal and install the service connector passwordless extension for the Azure CLI.
terminal
az extension add --name serviceconnector-passwordless --upgrade
Install the Azure CLI 2.30.0 or higher. To check if your Azure CLI version is 2.30.0 or higher, run the az --version command. If you need to upgrade, run az upgrade (requires version 2.11.0+).
Sign in to Azure using the CLI with az login. This command opens a browser to gather your credentials. When the command finishes, it shows JSON output containing information about your subscriptions. Once signed in, you can run Azure commands with the Azure CLI to work with resources in your subscription.
Install the service connector passwordless extension for Azure CLI
terminal
az extension add --name serviceconnector-passwordless --upgrade
Production settings are in the azuresite/production.py file. Development settings are in azuresite/settings.py.
The app uses production settings when the WEBSITE_HOSTNAME environment variable is set. Azure App Service automatically sets this variable to the URL of the web app, such as msdocs-django.azurewebsites.net.
The production settings are specific to configuring Django to run in any production environment and aren't particular to App Service. For more information, see the Django deployment checklist. Also see Production settings for Django on Azure for details on some of the changes.
The ADMIN_PW must contain 8 to 128 characters from three of the following categories: English uppercase letters, English lowercase letters, numbers, and nonalphanumeric characters. When creating usernames or passwords do not use the $ character. Later you create environment variables with these values where the $ character has a specific meaning within the Linux container used to run Python apps.
Create a resource group (you can change the name, if desired). The resource group name is cached and automatically applied to subsequent commands.
Azure CLI
az group create --name$RESOURCE_GROUP_NAME--location$LOCATION
Create the database server. If prompted to enable access to current client IP address, type y for yes. This process takes a few minutes:
Create a default resource group if there's not a cached name already.
Create a PostgreSQL Flexible server:
With the server name specified with the --name parameter. The name must be unique across all of Azure.
With the sku specified with the --sku-name parameter.
Create an administrator account with a username and password specified with the --admin-user and --admin-password parameters.
Create a database which name is specified with the --database-name parameter.
Configure a firewall rule on your server with the az postgres flexible-server firewall-rule create command. This rule allows your local environment access to the server. (If you're prompted to enable access from your client IP address in previous step, you can skip this step.)
In this section, you create app host in App Service app, connect this app to the Postgres database, then deploy your code to that host.
Create the App Service app
In the terminal, make sure you're in the serviceconnector-webapp-postgresql-django-passwordless repository folder that contains the app code.
Run the following az webapp up command to create the App Service host for the app:
Azure CLI
az webapp up \
--resource-group$RESOURCE_GROUP_NAME \
--location$LOCATION \
--name$APP_SERVICE_NAME \
--runtime PYTHON:3.9 \
--sku B1
The sku defines the size (CPU, memory) and cost of the App Service plan. The B1 (Basic) service plan incurs a small cost in your Azure subscription. For a full list of App Service plans, view the App Service pricing page.
This command performs the following actions, which may take a few minutes, using resource group and location cached from the previous az group create command (the group $RESOURCE_GROUP_NAME in the eastus region in this example).
Create an App Service plan in the Basic pricing tier (B1). You can omit --sku to use default values.
Create the App Service app.
Enable default logging for the app.
Upload the repository using ZIP deployment with build automation enabled.
Configure App Service to use the start.sh in the repo with the az webapp config set command.
Azure CLI
az webapp config set \
--resource-group$RESOURCE_GROUP_NAME \
--name$APP_SERVICE_NAME \
--startup-file"start.sh"
Create a passwordless connector to Postgres database
With the code now deployed to App Service, the next step is to connect the app to the Postgres database in Azure. The app code expects to find database information in an environment variable named AZURE_POSTGRESQL_CONNECTIONSTRING for PostgresSQL flexible server and an environment variable named AZURE_STORAGEBLOB_RESOURCEENDPOINT for Azure Storage account.
The Service Connector commands configure Azure Storage and Azure Database for PostgreSQL resources to use managed identity and Azure role-based access control. The commands create app settings in the App Service that connect your web app to these resources. The output from the commands lists the service connector actions taken to enable passwordless capability.
Add a PostgreSQL service connector with the az webapp connection create postgres-flexible command. The system-assigned managed identity is used to authenticate the web app to the target resource, PostgreSQL in this case.
If you see the error message "The subscription is not registered to use Microsoft.ServiceLinker", please run az provider register -n Microsoft.ServiceLinker to register the Service Connector resource provider and run the connection command again.
In your Python code, you access these settings as environment variables with statements like os.environ.get('AZURE_POSTGRESQL_HOST'). For more information, see Access environment variables.
Update the storage account to allow blob public access for the restaurant app users to access images.
Azure CLI
az storage account update \
--name$STORAGE_ACCOUNT_NAME \
--allow-blob-public-access
Create a container called photos in the storage account with the az storage container create command. Allow anonymous read (public) access to blobs in the newly created container.
Azure CLI
# Set the BLOB_ENDPOINT variable
BLOB_ENDPOINT=$(az storage account show --name$STORAGE_ACCOUNT_NAME--query"primaryEndpoints.blob" | sed 's/"//g')
echo $BLOB_ENDPOINT# Create the storage container using the BLOB_ENDPOINT variableaz storage container create \
--account-name$STORAGE_ACCOUNT_NAME \
--name photos \
--public-access blob \
--auth-mode login \
--blob-endpoint$BLOB_ENDPOINT
Test the Python web app in Azure
The sample Python app uses the azure.identity package and its DefaultAzureCredential class. When the app is running in Azure, DefaultAzureCredential automatically detects if a managed identity exists for the App Service and, if so, uses it to access other Azure resources (storage and PostgreSQL in this case). There's no need to provide storage keys, certificates, or credentials to the App Service to access these resources.
Browse to the deployed application at the URL http://$APP_SERVICE_NAME.azurewebsites.net.
It can take a minute or two for the app to start. If you see a default app page that isn't the default sample app page, wait a minute and refresh the browser.
Test the functionality of the sample app by adding a restaurant and some reviews with photos for the restaurant.
The restaurant and review information is stored in Azure Database for PostgreSQL and the photos are stored in Azure Storage. Here's an example screenshot:
Clean up resources
If you'd like to keep the app or continue to more tutorials, skip ahead to Next steps. Otherwise, to avoid incurring ongoing charges, delete the resource group created for this tutorial:
Azure CLI
az group delete --name$RESOURCE_GROUP_NAME--no-wait
By deleting the resource group, you also deallocate and delete all the resources contained within it. Be sure you no longer need the resources in the group before using the command.
Deleting all the resources can take some time. The --no-wait argument allows the command to return immediately.
Administer an SQL Server database infrastructure for cloud, on-premises and hybrid relational databases using the Microsoft PaaS relational database offerings.