Sign in during Public Preview to get the Team plan free, plus an early-adopter discount when we launch. Sign in
The Azure SDK for Python is Microsoft's set of libraries for working with Azure from your Python applications. At this time the SDK needs a couple of lines of code to be able to work against Locally.
This guide covers those changes, using a Resource Group as an example - the same configuration works for the other Azure SDK clients too.
This guide was tested using the following versions of these packages, but newer versions should work too.
azure-mgmt-resource - v26.0.0
azure-identity - v1.25.3
We're going to provision a Resource Group using the SDK Client ResourceManagementClient from azure.mgmt.resource.resources.
When constructing an Azure SDK client, there are three things we need to do to configure it to work against Locally:
authority and the client's base_url. This ensures that calls made by the Azure SDK will interact with Locally rather than Azure Public (or another Azure Environment).
disable_instance_discovery to True. Instance Discovery is a MSAL service which validates that the Azure Tenant is known by Microsoft, to ensure you don't send your credentials to an unknown third-party. Since Locally is running on your local machine and isn't a Microsoft-hosted service - its Tenant ID isn't returned by MSAL Instance Discovery, therefore we need to disable it for the Azure SDK to connect.
credential_scopes to Locally's Resource Manager audience (the base_url followed by .default). By default the Azure SDK requests a token scoped to Azure Public (https://management.azure.com/.default), which Locally's Resource Manager rejects with an InvalidAuthenticationToken error.
We're hoping to have the Azure SDK for Python support Automatic Configuration in the future, but for now these handful of changes need to be made to the Azure SDKs to be able to connect to Locally.
The Azure SDK for Python implements DefaultAzureCredential differently to other languages, and doesn't pass disable_instance_discovery through to the credential it builds - so we use a ClientSecretCredential directly below.
We can set these on the ClientSecretCredential and ResourceManagementClient constructors:
import os
from azure.identity import ClientSecretCredential
from azure.mgmt.resource.resources import ResourceManagementClient
# Connect to Locally rather than Azure Public
authority = "https://127.0.0.1:5677/"
resource_manager_endpoint = "https://127.0.0.1:5680/"
# Retrieve the Credentials from the Environment Variables provided by Locally
# The Python SDK implements DefaultAzureCredential differently to other languages and
# doesn't pass 'disable_instance_discovery' through to the credential it builds, so we
# construct a ClientSecretCredential directly instead.
tenant_id = os.environ["AZURE_TENANT_ID"]
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]
client_id = os.environ["AZURE_CLIENT_ID"]
client_secret = os.environ["AZURE_CLIENT_SECRET"]
credential = ClientSecretCredential(tenant_id=tenant_id,
client_id=client_id,
client_secret=client_secret,
authority=authority,
# MSAL Instance Discovery validates that the Tenant is known and hosted by Microsoft, with the
# intention being to prevent credentials accidentally being sent to a non-Microsoft provided service.
#
# Since Locally is running on your local machine (and therefore isn't a Microsoft-hosted service)
# we need to disable Instance Discovery, else we'll fail to connect.
disable_instance_discovery=True)
Now that we've got a Credential populated, we can construct an Azure SDK client to work against Locally:
# ...
# Construct an Azure SDK client targeting Locally
resource_client = ResourceManagementClient(credential,
subscription_id,
base_url=resource_manager_endpoint,
# By default the Azure SDK requests a token scoped to Azure Public
# (https://management.azure.com/.default), which Locally's Resource Manager rejects.
# Point the token scope at Locally's Resource Manager audience instead.
credential_scopes=[f"{resource_manager_endpoint}.default"])
At this point the Azure SDK client is a regular Azure SDK client - meaning that any calls should work as normal.
This means that we can create a Resource Group in Locally using the Azure SDK using:
# ...
# Create a Resource Group using the Azure SDK for Python
result = resource_client.resource_groups.create_or_update(
"rg-from-azure-sdk-for-python", {
"location": "berlin",
}
)
print(f"Created Resource Group {result.id}..")
Assuming this file is named main.py, we can then run this sample against Locally using:
$
locally run python3 ./main.py
Should you encounter any issues, please take a look at the troubleshooting section.
import os
from azure.identity import ClientSecretCredential
from azure.mgmt.resource.resources import ResourceManagementClient
# Connect to Locally rather than Azure Public
authority = "https://127.0.0.1:5677/"
resource_manager_endpoint = "https://127.0.0.1:5680/"
# Retrieve the Credentials from the Environment Variables provided by Locally
# The Python SDK implements DefaultAzureCredential differently to other languages and
# doesn't pass 'disable_instance_discovery' through to the credential it builds, so we
# construct a ClientSecretCredential directly instead.
tenant_id = os.environ["AZURE_TENANT_ID"]
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]
client_id = os.environ["AZURE_CLIENT_ID"]
client_secret = os.environ["AZURE_CLIENT_SECRET"]
credential = ClientSecretCredential(tenant_id=tenant_id,
client_id=client_id,
client_secret=client_secret,
authority=authority,
# MSAL Instance Discovery validates that the Tenant is known and hosted by Microsoft, with the
# intention being to prevent credentials accidentally being sent to a non-Microsoft provided service.
#
# Since Locally is running on your local machine (and therefore isn't a Microsoft-hosted service)
# we need to disable Instance Discovery, else we'll fail to connect.
disable_instance_discovery=True)
# Construct an Azure SDK client targeting Locally
resource_client = ResourceManagementClient(credential,
subscription_id,
base_url=resource_manager_endpoint,
# By default the Azure SDK requests a token scoped to Azure Public
# (https://management.azure.com/.default), which Locally's Resource Manager rejects.
# Point the token scope at Locally's Resource Manager audience instead.
credential_scopes=[f"{resource_manager_endpoint}.default"])
# Create a Resource Group using the Azure SDK for Python
result = resource_client.resource_groups.create_or_update(
"rg-from-azure-sdk-for-python", {
"location": "berlin",
}
)
print(f"Created Resource Group {result.id}..")
Resources like Storage Accounts also get a Data Plane Emulator, which the Azure Storage SDKs can connect to. To run your code in a pipeline, see Using Locally in CI.
Sign in during Public Preview to get the Team plan free, plus an early-adopter discount when we launch. Sign in
Your Azure infrastructure, running on your machine. Deploy in seconds, break things freely, and ship to Azure when you're ready.