Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
In this tutorial, you learn how to deploy a data-driven Python Django web app to Azure App Service and use Service Connector to connect it to other Azure services. The sample web app stores restaurant and review information in an Azure Database for PostgreSQL database and stores photos in an Azure Storage container.
You use Azure CLI to complete the following tasks:
- Create a Python Django web app and deploy it to Azure App Service.
- Create an Azure Database for PostgreSQL flexible server and database.
- Create an Azure Storage account and container.
- Connect the web app to the database and storage container using Service Connector with managed identity authentication.
- Interact with the web app.
Note
This tutorial is similar to the App Service Deploy a Python Django web app with PostgreSQL in Azure tutorial, but uses a system-assigned passwordless managed identity with Azure role-based access control to access other Azure resources. The Create a passwordless service connection section of this article shows how Service Connector simplifies the connection process.
The web app uses the DefaultAzureCredential class of the Python Azure Identity client library to automatically detect when a managed identity exists and uses it to access the other resources.
Prerequisites
An Azure subscription with write and role-assignment permissions for the tutorial resources, in an Azure region that supports Service Connector and has sufficient App Service support and quota.
Azure Cloud Shell to run the tutorial steps, or if you prefer to run locally:
- Install Azure CLI 2.30.0 or higher. To check your version, run
az --version. To upgrade, runaz upgrade. - Sign in to Azure by using
az loginand following the prompts.
- Install Azure CLI 2.30.0 or higher. To check your version, run
Set up your environment
Make sure your subscription is registered to use the
Microsoft.ServiceLinkerandMicrosoft.DBforPostgreSQLresource providers. If not, runaz provider register -n Microsoft.[name of service]to register the providers.Install the following Azure CLI extensions:
az extension add --name serviceconnector-passwordless --upgrade az extension add --name rdbms-connect
Clone the sample app
Clone the sample app repository.
git clone https://github.com/Azure-Samples/serviceconnector-webapp-postgresql-django-passwordless.gitAlternatively, you can download the app from https://github.com/Azure-Samples/serviceconnector-webapp-postgresql-django-passwordless and unzip it into a folder called serviceconnector-webapp-postgresql-django-passwordless.
Change directories into the repo folder using
cd serviceconnector-webapp-postgresql-django-passwordlessand run all remaining commands from that folder.
In the sample app, the web app production settings are in the azuresite/production.py file. Development settings are in azuresite/settings.py. The production settings configure Django to run in any production environment and aren't specific to App Service.
The app uses production settings when the WEBSITE_HOSTNAME environment variable is set. For Azure Postgres connection strings, App Service automatically sets this variable to the URL of the web app, such as https://msdocs-django.azurewebsites.net.
For more information, see the Django deployment checklist. Also see Production settings for Django on Azure.
Define initial environment variables
The following code defines the necessary environment variables for this tutorial.
LOCATIONmust be an Azure region where your subscription has sufficient quota to create the resources and doesn't restrict Azure Database for PostgreSQL for your subscription.- The
ADMIN_PWmust contain 8 to 128 characters in at least three of the four categories uppercase letters, lowercase letters, numerals, and nonalphanumeric characters, excluding$.
Set up the following environment variables, replacing the
<region>and<database password>placeholders with valid values.LOCATION="<region>" RAND_ID=$RANDOM RESOURCE_GROUP_NAME="msdocs-mi-web-app" APP_SERVICE_NAME="msdocs-mi-web-$RAND_ID" DB_SERVER_NAME="msdocs-mi-postgres-$RAND_ID" ADMIN_USER="demoadmin" ADMIN_PW="<database password>"Create a resource group to contain all the project resources. The resource group name is cached and automatically applied to subsequent commands.
az group create --name $RESOURCE_GROUP_NAME --location $LOCATION
Deploy the app code to App Service
Create the app host in App Service and deploy the sample app code to that host. The az webapp up command performs the following actions:
- Creates an App Service plan in the Basic (B1) pricing tier.
- Creates the App Service app.
- Enables default logging for the app.
- Uploads the repository using ZIP deployment with build automation enabled.
- Builds the app.
In the code, the sku defines the CPU, memory, and cost of the App Service plan. The Basic (B1) service plan incurs a small cost in your Azure subscription. You can omit the --sku parameter to use the default SKU, usually P1v3 (Premium v3). For a full list of App Service plans, see App Service pricing.
From the serviceconnector-webapp-postgresql-django-passwordless repository folder, run the following
az webapp upcommand:az webapp up \ --resource-group $RESOURCE_GROUP_NAME \ --location $LOCATION \ --name $APP_SERVICE_NAME \ --runtime PYTHON:3.10 \ --sku B1Note
The deployment takes a few minutes, and the command can hang or time out, especially on a Basic SKU. Once the app builds successfully and the output shows
Starting the site, you can exit out of the command by selecting Ctrl+C.Configure the app to use the repository start.sh file by running the az webapp config set command.
az webapp config set \ --resource-group $RESOURCE_GROUP_NAME \ --name $APP_SERVICE_NAME \ --startup-file "start.sh"
Create the Postgres database in Azure
Create the Azure Database for PostgreSQL database to store app information. The az postgres flexible-server create command creates an Azure Database for PostgreSQL flexible server in the specified resource group that has:
- Server name specified in the
--nameparameter. The name must be unique across all of Azure. - SKU specified in the
--sku-nameparameter. - Administrator account username and password specified in the
--admin-userand--admin-passwordparameters.
Create the Azure Database for PostgreSQL server. If prompted to enable access to the current client IP address, enter
yfor yes.az postgres flexible-server create \ --resource-group $RESOURCE_GROUP_NAME \ --name $DB_SERVER_NAME \ --location $LOCATION \ --admin-user $ADMIN_USER \ --admin-password $ADMIN_PW \ --sku-name Standard_D2ds_v4 \ --microsoft-entra-auth EnabledIf you aren't prompted to enable access to your current client IP address, 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.
IP_ADDRESS=<your IP address> az postgres flexible-server firewall-rule create \ --resource-group $RESOURCE_GROUP_NAME \ --name $DB_SERVER_NAME \ --rule-name AllowMyIP \ --start-ip-address $IP_ADDRESS \ --end-ip-address $IP_ADDRESSTip
Use any tool or website that shows your IP address to substitute
<your IP address>in the command. For example, you can use What's My IP Address?.Create a database named
restaurantin the server by using the az postgres flexible-server execute command.az postgres flexible-server execute \ --name $DB_SERVER_NAME \ --admin-user $ADMIN_USER \ --admin-password $ADMIN_PW \ --database-name postgres \ --querytext 'create database restaurant;'
Create a passwordless service connection
Use az webapp connection create postgres-flexible to add a service connector that connects the Azure web app to the Postgres database using passwordless managed identity authentication. The following command configures Azure Database for PostgreSQL to use managed identity and Azure role-based access control. The command output lists the actions Service Connector takes.
The command creates an environment variable named AZURE_POSTGRESQL_CONNECTIONSTRING that provides the database connection information for the app. The app code accesses app environment variables with statements like os.environ.get('AZURE_POSTGRESQL_HOST'). For more information, see Access environment variables.
az webapp connection create postgres-flexible \
--resource-group $RESOURCE_GROUP_NAME \
--name $APP_SERVICE_NAME \
--target-resource-group $RESOURCE_GROUP_NAME \
--server $DB_SERVER_NAME \
--database restaurant \
--client-type python \
--system-identity
Create and connect to a storage account
Use az webapp connection create storage-blob to create an Azure storage account and a service connector. The command takes the following actions:
- Enables system-assigned managed identity on the web app.
- Adds the web app with role Storage Blob Data Contributor to the new storage account.
- Configures the storage account network to accept access from the web app.
- Creates an environment variable named
AZURE_STORAGEBLOB_RESOURCEENDPOINTfor the Azure Storage account.
Run the following command to create the storage account and connection:
STORAGE_ACCOUNT_URL=$(az webapp connection create storage-blob \ --new true \ --resource-group $RESOURCE_GROUP_NAME \ --name $APP_SERVICE_NAME \ --target-resource-group $RESOURCE_GROUP_NAME \ --client-type python \ --system-identity \ --query configurations[].value \ --output tsv) STORAGE_ACCOUNT_NAME=$(cut -d . -f1 <<< $(cut -d / -f3 <<< $STORAGE_ACCOUNT_URL))Update the storage account to allow blob public access for app users to access photos.
az storage account update \ --name $STORAGE_ACCOUNT_NAME \ --allow-blob-public-accessUse az storage container create to create a container called
photosin the storage account, and allow anonymous public read access to blobs in the new container.# 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 variable az 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
Open and test the Azure Restaurant Review web app. The app uses the azure.identity package and its DefaultAzureCredential class. When the app is running in Azure, the DefaultAzureCredential automatically detects when a managed identity exists for the App Service, and uses it to access the Azure Storage and Azure Database for PostgreSQL resources. The app doesn't need to provide storage keys, certificates, or credentials to access these resources.
For a local Azure CLI installation, you can use
az webapp browseto open the app in your default browser:az webapp browse --name $APP_SERVICE_NAME.azurewebsites.net --resource-group $RESOURCE_GROUP_NAMEAzure Cloud Shell can't open a local browser, so it doesn't support the
az webapp browsecommand. From Cloud Shell, the easiest way to open the web app is to select the Default domain link at upper right on the app's Azure portal page.
It can take a minute or two for the app to start. If you see a default app page that isn't the sample app, wait a minute and refresh the browser.
Test the functionality of the sample app by adding a restaurant and some reviews with photos. The app should resemble the following screenshot:
Clean up resources
To avoid ongoing charges, you can delete the resources you created for this tutorial by deleting the resource group that contains them. Be sure you no longer need the app or the resources before you run the command.
az group delete --name $RESOURCE_GROUP_NAME --no-wait
Deleting all the resources can take some time. The --no-wait argument allows the command to return immediately.
Troubleshooting
If you have issues running this tutorial, see the following resources: