Skip to main content

Challenge 02: Create and Configure Azure AI Resources

Estimated Time

45 min | Cost: ~$0.50 | Domain: Plan & Manage AI Solutions (20-25%)

Exam skills covered

  • Create an Azure AI resource
  • Choose appropriate AI models
  • Determine the default endpoint for a service
  • Configure network access for Azure AI resources
  • Manage keys and secure access to resources

Overview

Creating and configuring Azure AI resources correctly is foundational to every AI-102 scenario. This challenge goes beyond clicking "Create" in the portal—you'll provision resources programmatically, configure network restrictions, retrieve and rotate keys, and validate endpoint connectivity.

Understanding the relationship between resource kinds, SKUs, endpoints, and keys is critical. A multi-service resource exposes a single endpoint like https://<region>.api.cognitive.microsoft.com/ while single-service resources may have service-specific endpoint patterns. You need to know which endpoint format each service uses and how to configure virtual network rules and private endpoints for production workloads.

This challenge also covers the configuration of diagnostic settings, custom subdomain names (required for Microsoft Entra authentication), and the difference between regional and custom endpoints.

Architecture

You'll create resources with custom subdomains, configure network rules, validate connectivity, and set up diagnostic logging—simulating a production-ready AI services deployment.

Challenge 02 topology

Prerequisites

  • Azure subscription with Contributor role
  • Azure CLI 2.50+ installed
  • Python 3.9+ with pip or .NET 8 SDK
  • azure-identity, azure-mgmt-cognitiveservices Python packages

Implementation

Task 1: Create a Resource with Custom Subdomain

from azure.identity import DefaultAzureCredential
from azure.mgmt.cognitiveservices import CognitiveServicesManagementClient
from azure.mgmt.cognitiveservices.models import (
Account, Sku, AccountProperties, NetworkRuleSet, NetworkRuleAction
)

credential = DefaultAzureCredential()
subscription_id = "YOUR_SUBSCRIPTION_ID"
client = CognitiveServicesManagementClient(credential, subscription_id)

# Create with custom subdomain (required for Entra ID auth)
account = client.accounts.begin_create(
resource_group_name="rg-ai102-challenge02",
account_name="ai102-mycompany-ai",
account=Account(
sku=Sku(name="S0"),
kind="AIServices",
location="eastus",
properties=AccountProperties(
custom_sub_domain_name="ai102-mycompany-ai",
public_network_access="Enabled"
)
)
).result()

print(f"Resource: {account.name}")
print(f"Endpoint: {account.properties.endpoint}")
print(f"Custom domain: https://{account.properties.custom_sub_domain_name}.cognitiveservices.azure.com/")

Task 2: Retrieve and Manage Keys

# Retrieve access keys
keys = client.accounts.list_keys(
resource_group_name="rg-ai102-challenge02",
account_name="ai102-mycompany-ai"
)
print(f"Key 1: {keys.key1[:8]}...")
print(f"Key 2: {keys.key2[:8]}...")

# Regenerate key 1 (rotate without downtime using key 2)
from azure.mgmt.cognitiveservices.models import RegenerateKeyParameters, KeyName

new_keys = client.accounts.regenerate_key(
resource_group_name="rg-ai102-challenge02",
account_name="ai102-mycompany-ai",
parameters=RegenerateKeyParameters(key_name=KeyName.KEY1)
)
print(f"New Key 1: {new_keys.key1[:8]}...")
print("Key 2 unchanged—zero-downtime rotation complete")

Task 3: Configure Network Access

from azure.mgmt.cognitiveservices.models import (
NetworkRuleSet, NetworkRuleAction, IpRule, VirtualNetworkRule
)

# Update resource with network restrictions
account = client.accounts.begin_create(
resource_group_name="rg-ai102-challenge02",
account_name="ai102-mycompany-ai",
account=Account(
sku=Sku(name="S0"),
kind="AIServices",
location="eastus",
properties=AccountProperties(
custom_sub_domain_name="ai102-mycompany-ai",
public_network_access="Enabled",
network_acls=NetworkRuleSet(
default_action=NetworkRuleAction.DENY,
ip_rules=[
IpRule(value="203.0.113.0/24"), # Corporate IP range
IpRule(value="198.51.100.42") # Developer IP
]
)
)
)
).result()

print(f"Network rules applied: default action = Deny")
print(f"Allowed IPs: 203.0.113.0/24, 198.51.100.42")
print(f"Public access: {account.properties.public_network_access}")

Expected Output

Resource: ai102-mycompany-ai
Endpoint: https://ai102-mycompany-ai.cognitiveservices.azure.com/
Custom domain: https://ai102-mycompany-ai.cognitiveservices.azure.com/

Key 1: a3f8b2c1...
Key 2: 7d9e4f6a...
New Key 1: x1y2z3w4...
Key 2 unchanged—zero-downtime rotation complete

Network rules applied: default action = Deny
Allowed IPs: 203.0.113.0/24, 198.51.100.42
Public access: Enabled

Break & fix

ScenarioSymptomRoot CauseFix
Custom domain conflictSubdomainAlreadyInUse errorAnother resource uses same subdomain globallyChoose a unique subdomain name
Network blocked403 Forbidden after applying rulesClient IP not in allow listAdd client IP to network rules or use private endpoint
Key rotation breaks app401 Unauthorized after regenerationApp still using old keyUpdate to new key, or use Key 2 during rotation of Key 1
Entra auth fails401 with bearer tokenResource missing custom subdomainCustom subdomain is required for Microsoft Entra auth; recreate with --custom-domain
Endpoint format wrong404 Not FoundUsing regional endpoint format with custom subdomain resourceUse https://<subdomain>.cognitiveservices.azure.com/ format

Knowledge Check

1. Why is a custom subdomain name required when using Microsoft Entra ID (Azure AD) authentication with Azure AI services?

2. You need to rotate API keys for a production Azure AI resource without any downtime. What is the correct procedure?

3. What is the default endpoint format for a multi-service Azure AI resource created WITHOUT a custom subdomain?

4. You configure network rules on your Azure AI resource with default action set to 'Deny'. Which traffic is still allowed?

5. Which SKU should you choose for a development/testing Azure AI multi-service resource to minimize costs while accessing all service APIs?

Cleanup

az group delete --name rg-ai102-challenge02 --yes --no-wait

Learn More