diff --git a/infrastructure/infrastructure-setup-bicep/00-basic/azuredeploy.json b/infrastructure/infrastructure-setup-bicep/00-basic/azuredeploy.json index 5edf30433..d8b8eb940 100644 --- a/infrastructure/infrastructure-setup-bicep/00-basic/azuredeploy.json +++ b/infrastructure/infrastructure-setup-bicep/00-basic/azuredeploy.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.39.26.7824", - "templateHash": "4687470877814835157" + "templateHash": "848823311706516415" } }, "parameters": { @@ -19,7 +19,40 @@ }, "location": { "type": "string", - "defaultValue": "eastus2" + "defaultValue": "[resourceGroup().location]", + "allowedValues": [ + "australiaeast", + "brazilsouth", + "canadacentral", + "canadaeast", + "centralindia", + "centralus", + "eastasia", + "eastus", + "francecentral", + "germanywestcentral", + "italynorth", + "japaneast", + "koreacentral", + "northcentralus", + "northeurope", + "norwayeast", + "qatarcentral", + "southafricanorth", + "southcentralus", + "southindia", + "southeastasia", + "spaincentral", + "swedencentral", + "switzerlandnorth", + "uaenorth", + "uksouth", + "westeurope", + "westus", + "westus3", + "usgovarizona", + "usgovvirginia" + ] } }, "resources": [ diff --git a/infrastructure/infrastructure-setup-bicep/00-basic/main.bicep b/infrastructure/infrastructure-setup-bicep/00-basic/main.bicep index cf0df6f16..ad0a1d67c 100644 --- a/infrastructure/infrastructure-setup-bicep/00-basic/main.bicep +++ b/infrastructure/infrastructure-setup-bicep/00-basic/main.bicep @@ -1,6 +1,39 @@ param aiFoundryName string = 'foundry-name' param aiProjectName string = '${aiFoundryName}-proj' -param location string = 'eastus2' +@allowed([ + 'australiaeast' + 'brazilsouth' + 'canadacentral' + 'canadaeast' + 'centralindia' + 'centralus' + 'eastasia' + 'eastus' + 'francecentral' + 'germanywestcentral' + 'italynorth' + 'japaneast' + 'koreacentral' + 'northcentralus' + 'northeurope' + 'norwayeast' + 'qatarcentral' + 'southafricanorth' + 'southcentralus' + 'southindia' + 'southeastasia' + 'spaincentral' + 'swedencentral' + 'switzerlandnorth' + 'uaenorth' + 'uksouth' + 'westeurope' + 'westus' + 'westus3' + 'usgovarizona' + 'usgovvirginia' +]) +param location string = any(resourceGroup().location) /* An AI Foundry resources is a variant of a CognitiveServices/account resource type diff --git a/infrastructure/infrastructure-setup-bicep/01-connections/ai-gateway-tier/azuredeploy.json b/infrastructure/infrastructure-setup-bicep/01-connections/ai-gateway-tier/azuredeploy.json index f63c151b4..50dff68e2 100644 --- a/infrastructure/infrastructure-setup-bicep/01-connections/ai-gateway-tier/azuredeploy.json +++ b/infrastructure/infrastructure-setup-bicep/01-connections/ai-gateway-tier/azuredeploy.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.46.1.21595", - "templateHash": "2257742962386746331" + "templateHash": "10260295346214143128" } }, "parameters": { @@ -40,9 +40,42 @@ }, "location": { "type": "string", - "defaultValue": "eastus2", + "defaultValue": "[resourceGroup().location]", + "allowedValues": [ + "australiaeast", + "brazilsouth", + "canadacentral", + "canadaeast", + "centralindia", + "centralus", + "eastasia", + "eastus", + "francecentral", + "germanywestcentral", + "italynorth", + "japaneast", + "koreacentral", + "northcentralus", + "northeurope", + "norwayeast", + "qatarcentral", + "southafricanorth", + "southcentralus", + "southindia", + "southeastasia", + "spaincentral", + "swedencentral", + "switzerlandnorth", + "uaenorth", + "uksouth", + "westeurope", + "westus", + "westus3", + "usgovarizona", + "usgovvirginia" + ], "metadata": { - "description": "Region for the account, project, and model. Defaults to eastus2; can differ from gatewayLocation (e.g. a CI region)." + "description": "Region for the account, project, and model. Defaults to the resource-group location and can differ from gatewayLocation." } }, "gatewayLocation": { diff --git a/infrastructure/infrastructure-setup-bicep/01-connections/ai-gateway-tier/main.bicep b/infrastructure/infrastructure-setup-bicep/01-connections/ai-gateway-tier/main.bicep index d0fae8dc8..b6a6ae2ed 100644 --- a/infrastructure/infrastructure-setup-bicep/01-connections/ai-gateway-tier/main.bicep +++ b/infrastructure/infrastructure-setup-bicep/01-connections/ai-gateway-tier/main.bicep @@ -50,8 +50,41 @@ param projectDescription string = 'AI Gateway tier hub: owns the model behind th @description('Hub project display name.') param projectDisplayName string = 'AI Gateway tier hub' -@description('Region for the account, project, and model. Defaults to eastus2; can differ from gatewayLocation (e.g. a CI region).') -param location string = 'eastus2' +@description('Region for the account, project, and model. Defaults to the resource-group location and can differ from gatewayLocation.') +@allowed([ + 'australiaeast' + 'brazilsouth' + 'canadacentral' + 'canadaeast' + 'centralindia' + 'centralus' + 'eastasia' + 'eastus' + 'francecentral' + 'germanywestcentral' + 'italynorth' + 'japaneast' + 'koreacentral' + 'northcentralus' + 'northeurope' + 'norwayeast' + 'qatarcentral' + 'southafricanorth' + 'southcentralus' + 'southindia' + 'southeastasia' + 'spaincentral' + 'swedencentral' + 'switzerlandnorth' + 'uaenorth' + 'uksouth' + 'westeurope' + 'westus' + 'westus3' + 'usgovarizona' + 'usgovvirginia' +]) +param location string = any(resourceGroup().location) @allowed([ 'eastus2' diff --git a/infrastructure/infrastructure-setup-bicep/01-connections/connection-foundry.bicep b/infrastructure/infrastructure-setup-bicep/01-connections/connection-foundry.bicep index 944a446e7..3938baff4 100644 --- a/infrastructure/infrastructure-setup-bicep/01-connections/connection-foundry.bicep +++ b/infrastructure/infrastructure-setup-bicep/01-connections/connection-foundry.bicep @@ -12,18 +12,51 @@ az deployment group create \ Optional parameters: - connectedResourceName: Name of the target Azure AI Foundry resource (default: foundry-{aiFoundryName}) -- location: Azure region (default: westus) +- location: Target account location (default: deployment resource group location) - newOrExisting: Whether to create new or use existing Azure AI Foundry resource (default: new) - authType: Authentication type - ApiKey or AAD (default: ApiKey) - isSharedToAll: Share connection with all users (default: true) Example with all parameters: -az deployment group create --name AzDeploy --resource-group myResourceGroup --template-file connection-foundry.bicep --parameters aiFoundryName=myFoundry connectedResourceName=myTargetFoundry location=eastus newOrExisting=existing authType=AAD isSharedToAll=false +az deployment group create --name AzDeploy --resource-group myResourceGroup --template-file connection-foundry.bicep --parameters aiFoundryName=myFoundry connectedResourceName=myTargetFoundry location=westus3 newOrExisting=new authType=AAD isSharedToAll=false */ param aiFoundryName string = '' param connectedResourceName string = 'foundry-${aiFoundryName}' -param location string = 'westus' +@allowed([ + 'australiaeast' + 'brazilsouth' + 'canadacentral' + 'canadaeast' + 'centralindia' + 'centralus' + 'eastasia' + 'eastus' + 'francecentral' + 'germanywestcentral' + 'italynorth' + 'japaneast' + 'koreacentral' + 'northcentralus' + 'northeurope' + 'norwayeast' + 'qatarcentral' + 'southafricanorth' + 'southcentralus' + 'southindia' + 'southeastasia' + 'spaincentral' + 'swedencentral' + 'switzerlandnorth' + 'uaenorth' + 'uksouth' + 'westeurope' + 'westus' + 'westus3' + 'usgovarizona' + 'usgovvirginia' +]) +param location string = any(resourceGroup().location) // Whether to create a new Azure AI Foundry resource @allowed([ diff --git a/infrastructure/infrastructure-setup-bicep/01-connections/connection-foundry.json b/infrastructure/infrastructure-setup-bicep/01-connections/connection-foundry.json index ccee68748..994d13678 100644 --- a/infrastructure/infrastructure-setup-bicep/01-connections/connection-foundry.json +++ b/infrastructure/infrastructure-setup-bicep/01-connections/connection-foundry.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.37.4.10188", - "templateHash": "8574372845632247592" + "templateHash": "10842231687547934134" } }, "parameters": { @@ -19,7 +19,40 @@ }, "location": { "type": "string", - "defaultValue": "westus" + "defaultValue": "[resourceGroup().location]", + "allowedValues": [ + "australiaeast", + "brazilsouth", + "canadacentral", + "canadaeast", + "centralindia", + "centralus", + "eastasia", + "eastus", + "francecentral", + "germanywestcentral", + "italynorth", + "japaneast", + "koreacentral", + "northcentralus", + "northeurope", + "norwayeast", + "qatarcentral", + "southafricanorth", + "southcentralus", + "southindia", + "southeastasia", + "spaincentral", + "swedencentral", + "switzerlandnorth", + "uaenorth", + "uksouth", + "westeurope", + "westus", + "westus3", + "usgovarizona", + "usgovvirginia" + ] }, "newOrExisting": { "type": "string", @@ -61,14 +94,14 @@ "name": "[format('{0}/{1}', parameters('aiFoundryName'), format('{0}-foundry', parameters('aiFoundryName')))]", "properties": { "category": "AIServices", - "target": "[reference(resourceId('Microsoft.CognitiveServices/accounts', parameters('connectedResourceName')), '2025-04-01-preview').endpoint]", + "target": "[if(equals(parameters('newOrExisting'), 'new'), reference(resourceId('Microsoft.CognitiveServices/accounts', parameters('connectedResourceName')), '2025-04-01-preview').endpoint, reference(resourceId('Microsoft.CognitiveServices/accounts', parameters('connectedResourceName')), '2025-04-01-preview').endpoint)]", "authType": "[parameters('authType')]", "isSharedToAll": "[parameters('isSharedToAll')]", - "credentials": "[if(equals(parameters('authType'), 'ApiKey'), createObject('key', listKeys(resourceId('Microsoft.CognitiveServices/accounts', parameters('connectedResourceName')), '2025-04-01-preview').key1), createObject())]", + "credentials": "[if(equals(parameters('authType'), 'ApiKey'), createObject('key', if(equals(parameters('newOrExisting'), 'new'), listKeys(resourceId('Microsoft.CognitiveServices/accounts', parameters('connectedResourceName')), '2025-04-01-preview').key1, listKeys(resourceId('Microsoft.CognitiveServices/accounts', parameters('connectedResourceName')), '2025-04-01-preview').key1)), createObject())]", "metadata": { "ApiType": "Azure", - "ResourceId": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('connectedResourceName'))]", - "location": "[reference(resourceId('Microsoft.CognitiveServices/accounts', parameters('connectedResourceName')), '2025-04-01-preview', 'full').location]" + "ResourceId": "[if(equals(parameters('newOrExisting'), 'new'), resourceId('Microsoft.CognitiveServices/accounts', parameters('connectedResourceName')), resourceId('Microsoft.CognitiveServices/accounts', parameters('connectedResourceName')))]", + "location": "[if(equals(parameters('newOrExisting'), 'new'), reference(resourceId('Microsoft.CognitiveServices/accounts', parameters('connectedResourceName')), '2025-04-01-preview', 'full').location, reference(resourceId('Microsoft.CognitiveServices/accounts', parameters('connectedResourceName')), '2025-04-01-preview', 'full').location)]" } }, "dependsOn": [ @@ -76,4 +109,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/infrastructure/infrastructure-setup-bicep/02-storage-speech-language/README.md b/infrastructure/infrastructure-setup-bicep/02-storage-speech-language/README.md index eeac1d91b..d9766884b 100644 --- a/infrastructure/infrastructure-setup-bicep/02-storage-speech-language/README.md +++ b/infrastructure/infrastructure-setup-bicep/02-storage-speech-language/README.md @@ -1,6 +1,6 @@ # Bring Your Own Azure Storage for Speech and Language capabilities (Preview) -Use this template to associate your Azure Storage account to a new Foundry resource. This template allows you to bring an existing Azure Storage account as the storage for your Speech and Language usecases. Learn more about this feature's restrictions via our public documentation. +Use this template to create a Foundry resource and project, then associate an Azure Storage account with the resource for Speech and Language use cases. You can use an existing storage account or create one with the template. Learn more about this feature's restrictions via our public documentation. ## Advanced implementation details ### How is this setup different from an Azure Storage connection in Foundry? diff --git a/infrastructure/infrastructure-setup-bicep/02-storage-speech-language/main.bicep b/infrastructure/infrastructure-setup-bicep/02-storage-speech-language/main.bicep index 874f959a0..263923d2c 100644 --- a/infrastructure/infrastructure-setup-bicep/02-storage-speech-language/main.bicep +++ b/infrastructure/infrastructure-setup-bicep/02-storage-speech-language/main.bicep @@ -5,8 +5,44 @@ @description('Name of the Azure AI Foundry account') param aiFoundryName string +@description('Name of the first project under the Azure AI Foundry account') +param aiProjectName string = '${aiFoundryName}-proj' + @description('Location for the resource') -param location string = resourceGroup().location +@allowed([ + 'australiaeast' + 'brazilsouth' + 'canadacentral' + 'canadaeast' + 'centralindia' + 'centralus' + 'eastasia' + 'eastus' + 'francecentral' + 'germanywestcentral' + 'italynorth' + 'japaneast' + 'koreacentral' + 'northcentralus' + 'northeurope' + 'norwayeast' + 'qatarcentral' + 'southafricanorth' + 'southcentralus' + 'southindia' + 'southeastasia' + 'spaincentral' + 'swedencentral' + 'switzerlandnorth' + 'uaenorth' + 'uksouth' + 'westeurope' + 'westus' + 'westus3' + 'usgovarizona' + 'usgovvirginia' +]) +param location string = any(resourceGroup().location) // Storage Account Parameters @description('Azure storage resource ID (leave empty to create a new storage account)') @@ -107,6 +143,16 @@ resource aiFoundry 'Microsoft.CognitiveServices/accounts@2025-07-01-preview' = { } } +resource aiProject 'Microsoft.CognitiveServices/accounts/projects@2025-06-01' = { + name: aiProjectName + parent: aiFoundry + location: location + identity: { + type: 'SystemAssigned' + } + properties: {} +} + // ==================================================================== // STEP 4: CREATE ROLE ASSIGNMENT FOR AI FOUNDRY'S MANAGED IDENTITY // ==================================================================== diff --git a/infrastructure/infrastructure-setup-bicep/03-custom-dns/azuredeploy.json b/infrastructure/infrastructure-setup-bicep/03-custom-dns/azuredeploy.json index 672e78928..b35eb9c3f 100644 --- a/infrastructure/infrastructure-setup-bicep/03-custom-dns/azuredeploy.json +++ b/infrastructure/infrastructure-setup-bicep/03-custom-dns/azuredeploy.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.39.26.7824", - "templateHash": "17555450976668837106" + "templateHash": "119560110974746177" } }, "parameters": { @@ -23,7 +23,40 @@ }, "location": { "type": "string", - "defaultValue": "eastus2" + "defaultValue": "[resourceGroup().location]", + "allowedValues": [ + "australiaeast", + "brazilsouth", + "canadacentral", + "canadaeast", + "centralindia", + "centralus", + "eastasia", + "eastus", + "francecentral", + "germanywestcentral", + "italynorth", + "japaneast", + "koreacentral", + "northcentralus", + "northeurope", + "norwayeast", + "qatarcentral", + "southafricanorth", + "southcentralus", + "southindia", + "southeastasia", + "spaincentral", + "swedencentral", + "switzerlandnorth", + "uaenorth", + "uksouth", + "westeurope", + "westus", + "westus3", + "usgovarizona", + "usgovvirginia" + ] } }, "resources": [ diff --git a/infrastructure/infrastructure-setup-bicep/03-custom-dns/main.bicep b/infrastructure/infrastructure-setup-bicep/03-custom-dns/main.bicep index 1a8590bfe..1dcc871cc 100644 --- a/infrastructure/infrastructure-setup-bicep/03-custom-dns/main.bicep +++ b/infrastructure/infrastructure-setup-bicep/03-custom-dns/main.bicep @@ -1,7 +1,40 @@ param aiFoundryName string = 'foundry-name' param customDNSName string = 'foundry-alt-custom-dns' param aiProjectName string = '${aiFoundryName}-proj' -param location string = 'eastus2' +@allowed([ + 'australiaeast' + 'brazilsouth' + 'canadacentral' + 'canadaeast' + 'centralindia' + 'centralus' + 'eastasia' + 'eastus' + 'francecentral' + 'germanywestcentral' + 'italynorth' + 'japaneast' + 'koreacentral' + 'northcentralus' + 'northeurope' + 'norwayeast' + 'qatarcentral' + 'southafricanorth' + 'southcentralus' + 'southindia' + 'southeastasia' + 'spaincentral' + 'swedencentral' + 'switzerlandnorth' + 'uaenorth' + 'uksouth' + 'westeurope' + 'westus' + 'westus3' + 'usgovarizona' + 'usgovvirginia' +]) +param location string = any(resourceGroup().location) /* An AI Foundry resources is a variant of a CognitiveServices/account resource type diff --git a/infrastructure/infrastructure-setup-bicep/04-disable-local-auth/azuredeploy.json b/infrastructure/infrastructure-setup-bicep/04-disable-local-auth/azuredeploy.json index d2cee29a4..23d20cbae 100644 --- a/infrastructure/infrastructure-setup-bicep/04-disable-local-auth/azuredeploy.json +++ b/infrastructure/infrastructure-setup-bicep/04-disable-local-auth/azuredeploy.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.39.26.7824", - "templateHash": "6087024663439753870" + "version": "0.48.1.52935", + "templateHash": "9490626156247361104" } }, "parameters": { @@ -19,7 +19,40 @@ }, "location": { "type": "string", - "defaultValue": "eastus2" + "defaultValue": "[resourceGroup().location]", + "allowedValues": [ + "australiaeast", + "brazilsouth", + "canadacentral", + "canadaeast", + "centralindia", + "centralus", + "eastasia", + "eastus", + "francecentral", + "germanywestcentral", + "italynorth", + "japaneast", + "koreacentral", + "northcentralus", + "northeurope", + "norwayeast", + "qatarcentral", + "southafricanorth", + "southcentralus", + "southindia", + "southeastasia", + "spaincentral", + "swedencentral", + "switzerlandnorth", + "uaenorth", + "uksouth", + "westeurope", + "westus", + "westus3", + "usgovarizona", + "usgovvirginia" + ] } }, "resources": [ diff --git a/infrastructure/infrastructure-setup-bicep/04-disable-local-auth/main.bicep b/infrastructure/infrastructure-setup-bicep/04-disable-local-auth/main.bicep index 94693a1e8..5f4a09e58 100644 --- a/infrastructure/infrastructure-setup-bicep/04-disable-local-auth/main.bicep +++ b/infrastructure/infrastructure-setup-bicep/04-disable-local-auth/main.bicep @@ -1,6 +1,39 @@ param aiFoundryName string = 'foundry-disable-localauth' param aiProjectName string = '${aiFoundryName}-proj' -param location string = 'eastus2' +@allowed([ + 'australiaeast' + 'brazilsouth' + 'canadacentral' + 'canadaeast' + 'centralindia' + 'centralus' + 'eastasia' + 'eastus' + 'francecentral' + 'germanywestcentral' + 'italynorth' + 'japaneast' + 'koreacentral' + 'northcentralus' + 'northeurope' + 'norwayeast' + 'qatarcentral' + 'southafricanorth' + 'southcentralus' + 'southindia' + 'southeastasia' + 'spaincentral' + 'swedencentral' + 'switzerlandnorth' + 'uaenorth' + 'uksouth' + 'westeurope' + 'westus' + 'westus3' + 'usgovarizona' + 'usgovvirginia' +]) +param location string = any(resourceGroup().location) /* An AI Foundry resources is a variant of a CognitiveServices/account resource type diff --git a/infrastructure/infrastructure-setup-bicep/10-private-network-basic/azuredeploy.json b/infrastructure/infrastructure-setup-bicep/10-private-network-basic/azuredeploy.json index b8716c128..a1bb88314 100644 --- a/infrastructure/infrastructure-setup-bicep/10-private-network-basic/azuredeploy.json +++ b/infrastructure/infrastructure-setup-bicep/10-private-network-basic/azuredeploy.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.44.1.10279", - "templateHash": "964975521955820946" + "version": "0.48.1.52935", + "templateHash": "9333187855641087974" } }, "parameters": { @@ -18,7 +18,40 @@ }, "location": { "type": "string", - "defaultValue": "eastus", + "defaultValue": "[resourceGroup().location]", + "allowedValues": [ + "australiaeast", + "brazilsouth", + "canadacentral", + "canadaeast", + "centralindia", + "centralus", + "eastasia", + "eastus", + "francecentral", + "germanywestcentral", + "italynorth", + "japaneast", + "koreacentral", + "northcentralus", + "northeurope", + "norwayeast", + "qatarcentral", + "southafricanorth", + "southcentralus", + "southindia", + "southeastasia", + "spaincentral", + "swedencentral", + "switzerlandnorth", + "uaenorth", + "uksouth", + "westeurope", + "westus", + "westus3", + "usgovarizona", + "usgovvirginia" + ], "metadata": { "description": "Location for all resources." } @@ -101,7 +134,7 @@ "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2024-05-01", "name": "[format('{0}-private-endpoint', parameters('aiFoundryName'))]", - "location": "[resourceGroup().location]", + "location": "[parameters('location')]", "properties": { "subnet": { "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('peSubnetName'))]" diff --git a/infrastructure/infrastructure-setup-bicep/10-private-network-basic/main.bicep b/infrastructure/infrastructure-setup-bicep/10-private-network-basic/main.bicep index b3d24469c..0fe8f4579 100644 --- a/infrastructure/infrastructure-setup-bicep/10-private-network-basic/main.bicep +++ b/infrastructure/infrastructure-setup-bicep/10-private-network-basic/main.bicep @@ -9,7 +9,40 @@ param aiFoundryName string = 'foundrypnadisabled-${uniqueString(resourceGroup().id)}' @description('Location for all resources.') -param location string = 'eastus' +@allowed([ + 'australiaeast' + 'brazilsouth' + 'canadacentral' + 'canadaeast' + 'centralindia' + 'centralus' + 'eastasia' + 'eastus' + 'francecentral' + 'germanywestcentral' + 'italynorth' + 'japaneast' + 'koreacentral' + 'northcentralus' + 'northeurope' + 'norwayeast' + 'qatarcentral' + 'southafricanorth' + 'southcentralus' + 'southindia' + 'southeastasia' + 'spaincentral' + 'swedencentral' + 'switzerlandnorth' + 'uaenorth' + 'uksouth' + 'westeurope' + 'westus' + 'westus3' + 'usgovarizona' + 'usgovvirginia' +]) +param location string = any(resourceGroup().location) @description('Name of the first project') param defaultProjectName string = '${aiFoundryName}-proj' @@ -89,7 +122,7 @@ Step 3: Create a private endpoint to access your private resource // - Establishes private connection to AI Services account resource aiAccountPrivateEndpoint 'Microsoft.Network/privateEndpoints@2024-05-01' = { name: '${aiFoundryName}-private-endpoint' - location: resourceGroup().location + location: location properties: { subnet: { id: subnet.id // Deploy in customer hub subnet diff --git a/infrastructure/infrastructure-setup-bicep/10-private-network-basic/main.json b/infrastructure/infrastructure-setup-bicep/10-private-network-basic/main.json index f27643520..a1bb88314 100644 --- a/infrastructure/infrastructure-setup-bicep/10-private-network-basic/main.json +++ b/infrastructure/infrastructure-setup-bicep/10-private-network-basic/main.json @@ -4,21 +4,54 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.35.1.17967", - "templateHash": "514902755770759577" + "version": "0.48.1.52935", + "templateHash": "9333187855641087974" } }, "parameters": { "aiFoundryName": { "type": "string", - "defaultValue": "foundrypnadisabled", + "defaultValue": "[format('foundrypnadisabled-{0}', uniqueString(resourceGroup().id))]", "metadata": { - "description": "That name is the name of our application. It has to be unique. Type a name followed by your resource group name. (-)" + "description": "Name for the AI Foundry account. Used as customSubDomainName (globally unique). Default appends a per-RG suffix to avoid collisions." } }, "location": { "type": "string", - "defaultValue": "eastus", + "defaultValue": "[resourceGroup().location]", + "allowedValues": [ + "australiaeast", + "brazilsouth", + "canadacentral", + "canadaeast", + "centralindia", + "centralus", + "eastasia", + "eastus", + "francecentral", + "germanywestcentral", + "italynorth", + "japaneast", + "koreacentral", + "northcentralus", + "northeurope", + "norwayeast", + "qatarcentral", + "southafricanorth", + "southcentralus", + "southindia", + "southeastasia", + "spaincentral", + "swedencentral", + "switzerlandnorth", + "uaenorth", + "uksouth", + "westeurope", + "westus", + "westus3", + "usgovarizona", + "usgovvirginia" + ], "metadata": { "description": "Location for all resources." } @@ -30,19 +63,25 @@ "description": "Name of the first project" } }, - "defaultProjectDisplayName": { + "vnetName": { "type": "string", - "defaultValue": "Project" + "defaultValue": "private-vnet", + "metadata": { + "description": "Name of the virtual network" + } }, - "defaultProjectDescription": { + "peSubnetName": { "type": "string", - "defaultValue": "Describe what your project is about." + "defaultValue": "pe-subnet", + "metadata": { + "description": "Name of the private endpoint subnet" + } } }, "resources": [ { "type": "Microsoft.CognitiveServices/accounts", - "apiVersion": "2025-04-01-preview", + "apiVersion": "2025-06-01", "name": "[parameters('aiFoundryName')]", "location": "[parameters('location')]", "identity": { @@ -59,6 +98,167 @@ "disableLocalAuth": false } }, + { + "type": "Microsoft.Network/virtualNetworks", + "apiVersion": "2024-05-01", + "name": "[parameters('vnetName')]", + "location": "[parameters('location')]", + "properties": { + "addressSpace": { + "addressPrefixes": [ + "192.168.0.0/16" + ] + }, + "subnets": [ + { + "name": "[parameters('peSubnetName')]", + "properties": { + "addressPrefix": "192.168.0.0/24" + } + } + ] + } + }, + { + "type": "Microsoft.Network/virtualNetworks/subnets", + "apiVersion": "2024-05-01", + "name": "[format('{0}/{1}', parameters('vnetName'), parameters('peSubnetName'))]", + "properties": { + "addressPrefix": "192.168.0.0/24" + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/virtualNetworks', parameters('vnetName'))]" + ] + }, + { + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2024-05-01", + "name": "[format('{0}-private-endpoint', parameters('aiFoundryName'))]", + "location": "[parameters('location')]", + "properties": { + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('peSubnetName'))]" + }, + "privateLinkServiceConnections": [ + { + "name": "[format('{0}-private-link-service-connection', parameters('aiFoundryName'))]", + "properties": { + "privateLinkServiceId": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('aiFoundryName'))]", + "groupIds": [ + "account" + ] + } + } + ] + }, + "dependsOn": [ + "[resourceId('Microsoft.CognitiveServices/accounts', parameters('aiFoundryName'))]", + "[resourceId('Microsoft.CognitiveServices/accounts/projects', parameters('aiFoundryName'), parameters('defaultProjectName'))]", + "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('peSubnetName'))]" + ] + }, + { + "type": "Microsoft.Network/privateDnsZones", + "apiVersion": "2020-06-01", + "name": "privatelink.services.ai.azure.com", + "location": "global" + }, + { + "type": "Microsoft.Network/privateDnsZones", + "apiVersion": "2020-06-01", + "name": "privatelink.openai.azure.com", + "location": "global" + }, + { + "type": "Microsoft.Network/privateDnsZones", + "apiVersion": "2020-06-01", + "name": "privatelink.cognitiveservices.azure.com", + "location": "global" + }, + { + "type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks", + "apiVersion": "2024-06-01", + "name": "[format('{0}/{1}', 'privatelink.services.ai.azure.com', 'aiServices-link')]", + "location": "global", + "properties": { + "virtualNetwork": { + "id": "[resourceId('Microsoft.Network/virtualNetworks', parameters('vnetName'))]" + }, + "registrationEnabled": false + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/privateDnsZones', 'privatelink.services.ai.azure.com')]", + "[resourceId('Microsoft.Network/virtualNetworks', parameters('vnetName'))]" + ] + }, + { + "type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks", + "apiVersion": "2024-06-01", + "name": "[format('{0}/{1}', 'privatelink.openai.azure.com', 'aiServicesOpenAI-link')]", + "location": "global", + "properties": { + "virtualNetwork": { + "id": "[resourceId('Microsoft.Network/virtualNetworks', parameters('vnetName'))]" + }, + "registrationEnabled": false + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/privateDnsZones', 'privatelink.openai.azure.com')]", + "[resourceId('Microsoft.Network/virtualNetworks', parameters('vnetName'))]" + ] + }, + { + "type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks", + "apiVersion": "2024-06-01", + "name": "[format('{0}/{1}', 'privatelink.cognitiveservices.azure.com', 'aiServicesCognitiveServices-link')]", + "location": "global", + "properties": { + "virtualNetwork": { + "id": "[resourceId('Microsoft.Network/virtualNetworks', parameters('vnetName'))]" + }, + "registrationEnabled": false + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/privateDnsZones', 'privatelink.cognitiveservices.azure.com')]", + "[resourceId('Microsoft.Network/virtualNetworks', parameters('vnetName'))]" + ] + }, + { + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2024-05-01", + "name": "[format('{0}/{1}', format('{0}-private-endpoint', parameters('aiFoundryName')), format('{0}-dns-group', parameters('aiFoundryName')))]", + "properties": { + "privateDnsZoneConfigs": [ + { + "name": "[format('{0}-dns-aiserv-config', parameters('aiFoundryName'))]", + "properties": { + "privateDnsZoneId": "[resourceId('Microsoft.Network/privateDnsZones', 'privatelink.services.ai.azure.com')]" + } + }, + { + "name": "[format('{0}-dns-openai-config', parameters('aiFoundryName'))]", + "properties": { + "privateDnsZoneId": "[resourceId('Microsoft.Network/privateDnsZones', 'privatelink.openai.azure.com')]" + } + }, + { + "name": "[format('{0}-dns-cogserv-config', parameters('aiFoundryName'))]", + "properties": { + "privateDnsZoneId": "[resourceId('Microsoft.Network/privateDnsZones', 'privatelink.cognitiveservices.azure.com')]" + } + } + ] + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/privateEndpoints', format('{0}-private-endpoint', parameters('aiFoundryName')))]", + "[resourceId('Microsoft.Network/privateDnsZones/virtualNetworkLinks', 'privatelink.openai.azure.com', 'aiServicesOpenAI-link')]", + "[resourceId('Microsoft.Network/privateDnsZones/virtualNetworkLinks', 'privatelink.services.ai.azure.com', 'aiServices-link')]", + "[resourceId('Microsoft.Network/privateDnsZones', 'privatelink.services.ai.azure.com')]", + "[resourceId('Microsoft.Network/privateDnsZones/virtualNetworkLinks', 'privatelink.cognitiveservices.azure.com', 'aiServicesCognitiveServices-link')]", + "[resourceId('Microsoft.Network/privateDnsZones', 'privatelink.cognitiveservices.azure.com')]", + "[resourceId('Microsoft.Network/privateDnsZones', 'privatelink.openai.azure.com')]" + ] + }, { "type": "Microsoft.CognitiveServices/accounts/deployments", "apiVersion": "2024-10-01", @@ -80,17 +280,13 @@ }, { "type": "Microsoft.CognitiveServices/accounts/projects", - "apiVersion": "2025-04-01-preview", + "apiVersion": "2025-06-01", "name": "[format('{0}/{1}', parameters('aiFoundryName'), parameters('defaultProjectName'))]", "location": "[parameters('location')]", "identity": { "type": "SystemAssigned" }, - "properties": { - "displayName": "[parameters('defaultProjectDisplayName')]", - "description": "[parameters('defaultProjectDescription')]", - "isDefault": true - }, + "properties": {}, "dependsOn": [ "[resourceId('Microsoft.CognitiveServices/accounts', parameters('aiFoundryName'))]" ] diff --git a/infrastructure/infrastructure-setup-bicep/11-private-network-basic-vnet/azuredeploy.json b/infrastructure/infrastructure-setup-bicep/11-private-network-basic-vnet/azuredeploy.json index 49a8bfbf9..072081d49 100644 --- a/infrastructure/infrastructure-setup-bicep/11-private-network-basic-vnet/azuredeploy.json +++ b/infrastructure/infrastructure-setup-bicep/11-private-network-basic-vnet/azuredeploy.json @@ -5,38 +5,45 @@ "_generator": { "name": "bicep", "version": "0.44.1.10279", - "templateHash": "6646415653041588209" + "templateHash": "2110640118335440235" } }, "parameters": { "location": { "type": "string", - "defaultValue": "eastus", + "defaultValue": "[resourceGroup().location]", "allowedValues": [ - "westus", + "australiaeast", + "brazilsouth", + "canadacentral", + "canadaeast", + "centralindia", + "centralus", + "eastasia", "eastus", - "eastus2", - "japaneast", "francecentral", - "spaincentral", - "uaenorth", - "southcentralus", - "italynorth", "germanywestcentral", - "brazilsouth", + "italynorth", + "japaneast", + "koreacentral", + "northcentralus", + "northeurope", + "norwayeast", + "qatarcentral", "southafricanorth", - "australiaeast", + "southcentralus", + "southindia", + "southeastasia", + "spaincentral", "swedencentral", - "canadaeast", - "canadacentral", + "switzerlandnorth", + "uaenorth", + "uksouth", "westeurope", + "westus", "westus3", - "uksouth", - "southindia", - "koreacentral", - "polandcentral", - "switzerlandnorth", - "norwayeast" + "usgovarizona", + "usgovvirginia" ], "metadata": { "description": "Location for all resources." @@ -187,6 +194,18 @@ "description": "Object mapping DNS zone names to their resource group, or empty string to indicate creation" } }, + "existingMonitorDnsZones": { + "type": "object", + "defaultValue": { + "privatelink.monitor.azure.com": "", + "privatelink.oms.opinsights.azure.com": "", + "privatelink.ods.opinsights.azure.com": "", + "privatelink.agentsvc.azure-automation.net": "" + }, + "metadata": { + "description": "Object mapping Azure Monitor private DNS zone names to the resource group of an existing zone, or empty string to create it. Use to bring your own centralized Private DNS Zones (e.g. an Azure Landing Zone connectivity subscription) for agent tracing." + } + }, "dnsZoneNames": { "type": "array", "defaultValue": [ @@ -248,9 +267,6 @@ }, "mode": "Incremental", "parameters": { - "location": { - "value": "[parameters('location')]" - }, "vnetName": { "value": "[variables('trimVnetName')]" }, @@ -277,6 +293,9 @@ }, "existingVnetSubscriptionId": { "value": "[variables('vnetSubscriptionId')]" + }, + "location": { + "value": "[parameters('location')]" } }, "template": { @@ -892,9 +911,6 @@ "accountName": { "value": "[variables('accountName')]" }, - "location": { - "value": "[parameters('location')]" - }, "modelName": { "value": "[parameters('modelName')]" }, @@ -921,16 +937,13 @@ "_generator": { "name": "bicep", "version": "0.44.1.10279", - "templateHash": "8297556890969361359" + "templateHash": "14793506092119170443" } }, "parameters": { "accountName": { "type": "string" }, - "location": { - "type": "string" - }, "modelName": { "type": "string" }, @@ -959,7 +972,7 @@ "type": "Microsoft.CognitiveServices/accounts", "apiVersion": "2025-04-01-preview", "name": "[parameters('accountName')]", - "location": "[parameters('location')]", + "location": "[resourceGroup().location]", "sku": { "name": "S0" }, @@ -1519,6 +1532,411 @@ "[resourceId('Microsoft.Resources/deployments', format('vnet-{0}-{1}-deployment', variables('trimVnetName'), variables('uniqueSuffix')))]" ] }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2025-04-01", + "name": "[format('app-insights-{0}-deployment', variables('uniqueSuffix'))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "location": { + "value": "[parameters('location')]" + }, + "suffix": { + "value": "[variables('uniqueSuffix')]" + }, + "aiAccountName": { + "value": "[reference(resourceId('Microsoft.Resources/deployments', format('{0}-{1}-deployment', variables('accountName'), variables('uniqueSuffix'))), '2025-04-01').outputs.accountName.value]" + }, + "disablePublicIngestion": { + "value": true + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.44.1.10279", + "templateHash": "10644740557362119851" + } + }, + "parameters": { + "location": { + "type": "string", + "metadata": { + "description": "Azure region for the tracing resources." + } + }, + "suffix": { + "type": "string", + "metadata": { + "description": "Suffix for unique resource names (the template uniqueSuffix)." + } + }, + "aiAccountName": { + "type": "string", + "metadata": { + "description": "Name of the Foundry (AI Services) account to connect Application Insights to." + } + }, + "disablePublicIngestion": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "When true, disable public ingestion (reach Application Insights privately via AMPLS). Set false for public templates." + } + }, + "logAnalyticsName": { + "type": "string", + "defaultValue": "[format('law-tracing-{0}', parameters('suffix'))]", + "metadata": { + "description": "Name of the Log Analytics workspace to create." + } + }, + "appInsightsName": { + "type": "string", + "defaultValue": "[format('appi-tracing-{0}', parameters('suffix'))]", + "metadata": { + "description": "Name of the Application Insights component to create." + } + } + }, + "resources": [ + { + "type": "Microsoft.OperationalInsights/workspaces", + "apiVersion": "2023-09-01", + "name": "[parameters('logAnalyticsName')]", + "location": "[parameters('location')]", + "properties": { + "sku": { + "name": "PerGB2018" + }, + "retentionInDays": 30 + } + }, + { + "type": "Microsoft.Insights/components", + "apiVersion": "2020-02-02", + "name": "[parameters('appInsightsName')]", + "location": "[parameters('location')]", + "kind": "web", + "properties": { + "Application_Type": "web", + "WorkspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('logAnalyticsName'))]", + "publicNetworkAccessForIngestion": "[if(parameters('disablePublicIngestion'), 'Disabled', 'Enabled')]", + "publicNetworkAccessForQuery": "Enabled" + }, + "dependsOn": [ + "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('logAnalyticsName'))]" + ] + }, + { + "type": "Microsoft.CognitiveServices/accounts/connections", + "apiVersion": "2025-04-01-preview", + "name": "[format('{0}/{1}', parameters('aiAccountName'), format('{0}-appinsights', parameters('aiAccountName')))]", + "properties": { + "category": "AppInsights", + "target": "[resourceId('Microsoft.Insights/components', parameters('appInsightsName'))]", + "authType": "ApiKey", + "isSharedToAll": true, + "credentials": { + "key": "[reference(resourceId('Microsoft.Insights/components', parameters('appInsightsName')), '2020-02-02').ConnectionString]" + }, + "metadata": { + "ApiType": "Azure", + "ResourceId": "[resourceId('Microsoft.Insights/components', parameters('appInsightsName'))]" + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Insights/components', parameters('appInsightsName'))]" + ] + } + ], + "outputs": { + "appInsightsId": { + "type": "string", + "metadata": { + "description": "Resource ID of the Application Insights component." + }, + "value": "[resourceId('Microsoft.Insights/components', parameters('appInsightsName'))]" + }, + "appInsightsAppId": { + "type": "string", + "metadata": { + "description": "Application ID of the Application Insights component (for trace queries)." + }, + "value": "[reference(resourceId('Microsoft.Insights/components', parameters('appInsightsName')), '2020-02-02').AppId]" + }, + "logAnalyticsId": { + "type": "string", + "metadata": { + "description": "Resource ID of the Log Analytics workspace backing Application Insights." + }, + "value": "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('logAnalyticsName'))]" + } + } + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', format('{0}-{1}-deployment', variables('accountName'), variables('uniqueSuffix')))]" + ] + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2025-04-01", + "name": "[format('monitor-pls-{0}-deployment', variables('uniqueSuffix'))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "location": { + "value": "[parameters('location')]" + }, + "suffix": { + "value": "[variables('uniqueSuffix')]" + }, + "appInsightsId": { + "value": "[reference(resourceId('Microsoft.Resources/deployments', format('app-insights-{0}-deployment', variables('uniqueSuffix'))), '2025-04-01').outputs.appInsightsId.value]" + }, + "logAnalyticsId": { + "value": "[reference(resourceId('Microsoft.Resources/deployments', format('app-insights-{0}-deployment', variables('uniqueSuffix'))), '2025-04-01').outputs.logAnalyticsId.value]" + }, + "vnetId": { + "value": "[reference(resourceId('Microsoft.Resources/deployments', format('vnet-{0}-{1}-deployment', variables('trimVnetName'), variables('uniqueSuffix'))), '2025-04-01').outputs.virtualNetworkId.value]" + }, + "peSubnetId": { + "value": "[reference(resourceId('Microsoft.Resources/deployments', format('vnet-{0}-{1}-deployment', variables('trimVnetName'), variables('uniqueSuffix'))), '2025-04-01').outputs.peSubnetId.value]" + }, + "existingDnsZones": { + "value": "[parameters('existingMonitorDnsZones')]" + }, + "dnsZonesSubscriptionId": { + "value": "[variables('resolvedDnsZonesSubscriptionId')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.44.1.10279", + "templateHash": "14873214704014114490" + } + }, + "parameters": { + "location": { + "type": "string", + "metadata": { + "description": "Azure region for the private endpoint." + } + }, + "suffix": { + "type": "string", + "metadata": { + "description": "Suffix for unique resource names (the template uniqueSuffix)." + } + }, + "appInsightsId": { + "type": "string", + "metadata": { + "description": "Resource ID of the Application Insights component to scope into the AMPLS." + } + }, + "logAnalyticsId": { + "type": "string", + "metadata": { + "description": "Resource ID of the Log Analytics workspace to scope into the AMPLS." + } + }, + "vnetId": { + "type": "string", + "metadata": { + "description": "Resource ID of the Virtual Network." + } + }, + "peSubnetId": { + "type": "string", + "metadata": { + "description": "Resource ID of the Private Endpoint subnet." + } + }, + "existingDnsZones": { + "type": "object", + "defaultValue": { + "privatelink.monitor.azure.com": "", + "privatelink.oms.opinsights.azure.com": "", + "privatelink.ods.opinsights.azure.com": "", + "privatelink.agentsvc.azure-automation.net": "" + }, + "metadata": { + "description": "Map of Azure Monitor private DNS zone name to the resource group of an existing zone. An empty string for a zone means the module creates and links it in this resource group; a non-empty resource group means bring your own existing (e.g. centralized Azure Landing Zone) zone, which is referenced instead of recreated." + } + }, + "dnsZonesSubscriptionId": { + "type": "string", + "defaultValue": "[subscription().subscriptionId]", + "metadata": { + "description": "Subscription ID where existing Azure Monitor private DNS zones are located. Defaults to the current subscription." + } + } + }, + "variables": { + "copy": [ + { + "name": "monitorDnsZoneIds", + "count": "[length(variables('monitorDnsZoneNames'))]", + "input": "[if(empty(parameters('existingDnsZones')[variables('monitorDnsZoneNames')[copyIndex('monitorDnsZoneIds')]]), resourceId('Microsoft.Network/privateDnsZones', variables('monitorDnsZoneNames')[copyIndex('monitorDnsZoneIds')]), extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('dnsZonesSubscriptionId'), parameters('existingDnsZones')[variables('monitorDnsZoneNames')[copyIndex('monitorDnsZoneIds')]]), 'Microsoft.Network/privateDnsZones', variables('monitorDnsZoneNames')[copyIndex('monitorDnsZoneIds')]))]" + } + ], + "monitorDnsZoneNames": [ + "privatelink.monitor.azure.com", + "privatelink.oms.opinsights.azure.com", + "privatelink.ods.opinsights.azure.com", + "privatelink.agentsvc.azure-automation.net" + ] + }, + "resources": [ + { + "type": "microsoft.insights/privateLinkScopes", + "apiVersion": "2021-07-01-preview", + "name": "[format('ampls-tracing-{0}', parameters('suffix'))]", + "location": "global", + "properties": { + "accessModeSettings": { + "ingestionAccessMode": "PrivateOnly", + "queryAccessMode": "Open" + } + } + }, + { + "type": "Microsoft.Insights/privateLinkScopes/scopedResources", + "apiVersion": "2021-07-01-preview", + "name": "[format('{0}/{1}', format('ampls-tracing-{0}', parameters('suffix')), 'appinsights-scoped')]", + "properties": { + "linkedResourceId": "[parameters('appInsightsId')]" + }, + "dependsOn": [ + "[resourceId('microsoft.insights/privateLinkScopes', format('ampls-tracing-{0}', parameters('suffix')))]" + ] + }, + { + "type": "Microsoft.Insights/privateLinkScopes/scopedResources", + "apiVersion": "2021-07-01-preview", + "name": "[format('{0}/{1}', format('ampls-tracing-{0}', parameters('suffix')), 'law-scoped')]", + "properties": { + "linkedResourceId": "[parameters('logAnalyticsId')]" + }, + "dependsOn": [ + "[resourceId('microsoft.insights/privateLinkScopes', format('ampls-tracing-{0}', parameters('suffix')))]" + ] + }, + { + "copy": { + "name": "monitorDnsZones", + "count": "[length(variables('monitorDnsZoneNames'))]" + }, + "condition": "[empty(parameters('existingDnsZones')[variables('monitorDnsZoneNames')[copyIndex()]])]", + "type": "Microsoft.Network/privateDnsZones", + "apiVersion": "2020-06-01", + "name": "[variables('monitorDnsZoneNames')[copyIndex()]]", + "location": "global" + }, + { + "copy": { + "name": "monitorDnsZoneLinks", + "count": "[length(variables('monitorDnsZoneNames'))]" + }, + "condition": "[empty(parameters('existingDnsZones')[variables('monitorDnsZoneNames')[copyIndex()]])]", + "type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks", + "apiVersion": "2024-06-01", + "name": "[format('{0}/{1}', variables('monitorDnsZoneNames')[copyIndex()], format('{0}-link', replace(variables('monitorDnsZoneNames')[copyIndex()], '.', '-')))]", + "location": "global", + "properties": { + "virtualNetwork": { + "id": "[parameters('vnetId')]" + }, + "registrationEnabled": false + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/privateDnsZones', variables('monitorDnsZoneNames')[copyIndex()])]" + ] + }, + { + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2024-05-01", + "name": "[format('ampls-tracing-{0}-pe', parameters('suffix'))]", + "location": "[parameters('location')]", + "properties": { + "subnet": { + "id": "[parameters('peSubnetId')]" + }, + "privateLinkServiceConnections": [ + { + "name": "ampls-connection", + "properties": { + "privateLinkServiceId": "[resourceId('microsoft.insights/privateLinkScopes', format('ampls-tracing-{0}', parameters('suffix')))]", + "groupIds": [ + "azuremonitor" + ] + } + } + ] + }, + "dependsOn": [ + "[resourceId('microsoft.insights/privateLinkScopes', format('ampls-tracing-{0}', parameters('suffix')))]", + "[resourceId('Microsoft.Insights/privateLinkScopes/scopedResources', format('ampls-tracing-{0}', parameters('suffix')), 'appinsights-scoped')]", + "[resourceId('Microsoft.Insights/privateLinkScopes/scopedResources', format('ampls-tracing-{0}', parameters('suffix')), 'law-scoped')]" + ] + }, + { + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2024-05-01", + "name": "[format('{0}/{1}', format('ampls-tracing-{0}-pe', parameters('suffix')), 'ampls-dns')]", + "properties": { + "copy": [ + { + "name": "privateDnsZoneConfigs", + "count": "[length(variables('monitorDnsZoneNames'))]", + "input": { + "name": "[replace(variables('monitorDnsZoneNames')[copyIndex('privateDnsZoneConfigs')], '.', '-')]", + "properties": { + "privateDnsZoneId": "[variables('monitorDnsZoneIds')[copyIndex('privateDnsZoneConfigs')]]" + } + } + } + ] + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/privateEndpoints', format('ampls-tracing-{0}-pe', parameters('suffix')))]", + "monitorDnsZoneLinks" + ] + } + ], + "outputs": { + "amplsId": { + "type": "string", + "metadata": { + "description": "Resource ID of the Azure Monitor Private Link Scope." + }, + "value": "[resourceId('microsoft.insights/privateLinkScopes', format('ampls-tracing-{0}', parameters('suffix')))]" + } + } + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', format('app-insights-{0}-deployment', variables('uniqueSuffix')))]", + "[resourceId('Microsoft.Resources/deployments', format('{0}-private-endpoint', variables('uniqueSuffix')))]", + "[resourceId('Microsoft.Resources/deployments', format('vnet-{0}-{1}-deployment', variables('trimVnetName'), variables('uniqueSuffix')))]" + ] + }, { "type": "Microsoft.Resources/deployments", "apiVersion": "2025-04-01", diff --git a/infrastructure/infrastructure-setup-bicep/11-private-network-basic-vnet/main.bicep b/infrastructure/infrastructure-setup-bicep/11-private-network-basic-vnet/main.bicep index 4c32c16b3..4e15d227a 100644 --- a/infrastructure/infrastructure-setup-bicep/11-private-network-basic-vnet/main.bicep +++ b/infrastructure/infrastructure-setup-bicep/11-private-network-basic-vnet/main.bicep @@ -15,34 +15,39 @@ are used instead. */ @description('Location for all resources.') @allowed([ - 'westus' + 'australiaeast' + 'brazilsouth' + 'canadacentral' + 'canadaeast' + 'centralindia' + 'centralus' + 'eastasia' 'eastus' - 'eastus2' - 'japaneast' 'francecentral' - 'spaincentral' - 'uaenorth' - 'southcentralus' - 'italynorth' 'germanywestcentral' - 'brazilsouth' + 'italynorth' + 'japaneast' + 'koreacentral' + 'northcentralus' + 'northeurope' + 'norwayeast' + 'qatarcentral' 'southafricanorth' - 'australiaeast' + 'southcentralus' + 'southindia' + 'southeastasia' + 'spaincentral' 'swedencentral' - 'canadaeast' - 'canadacentral' + 'switzerlandnorth' + 'uaenorth' + 'uksouth' 'westeurope' + 'westus' 'westus3' - 'uksouth' - 'southindia' - - //only class B and C - 'koreacentral' - 'polandcentral' - 'switzerlandnorth' - 'norwayeast' + 'usgovarizona' + 'usgovvirginia' ]) -param location string = 'eastus' +param location string = any(resourceGroup().location) @description('Name for your AI Services resource.') param aiServices string = 'aiservices' @@ -157,7 +162,6 @@ var resolvedDnsZonesSubscriptionId = empty(dnsZonesSubscriptionId) ? subscriptio module vnet 'modules-network-secured/network-agent-vnet.bicep' = { name: 'vnet-${trimVnetName}-${uniqueSuffix}-deployment' params: { - location: location vnetName: trimVnetName useExistingVnet: existingVnetPassedIn existingVnetResourceGroupName: vnetResourceGroupName @@ -167,6 +171,7 @@ module vnet 'modules-network-secured/network-agent-vnet.bicep' = { agentSubnetPrefix: agentSubnetPrefix peSubnetPrefix: peSubnetPrefix existingVnetSubscriptionId: vnetSubscriptionId + location: location } } diff --git a/infrastructure/infrastructure-setup-bicep/11-private-network-basic-vnet/main.json b/infrastructure/infrastructure-setup-bicep/11-private-network-basic-vnet/main.json index 479d4be92..0bcbfa24a 100644 --- a/infrastructure/infrastructure-setup-bicep/11-private-network-basic-vnet/main.json +++ b/infrastructure/infrastructure-setup-bicep/11-private-network-basic-vnet/main.json @@ -5,38 +5,45 @@ "_generator": { "name": "bicep", "version": "0.43.8.12551", - "templateHash": "1439992269587931650" + "templateHash": "12427516200668814305" } }, "parameters": { "location": { "type": "string", - "defaultValue": "eastus", + "defaultValue": "[resourceGroup().location]", "allowedValues": [ - "westus", + "australiaeast", + "brazilsouth", + "canadacentral", + "canadaeast", + "centralindia", + "centralus", + "eastasia", "eastus", - "eastus2", - "japaneast", "francecentral", - "spaincentral", - "uaenorth", - "southcentralus", - "italynorth", "germanywestcentral", - "brazilsouth", + "italynorth", + "japaneast", + "koreacentral", + "northcentralus", + "northeurope", + "norwayeast", + "qatarcentral", "southafricanorth", - "australiaeast", + "southcentralus", + "southindia", + "southeastasia", + "spaincentral", "swedencentral", - "canadaeast", - "canadacentral", + "switzerlandnorth", + "uaenorth", + "uksouth", "westeurope", + "westus", "westus3", - "uksouth", - "southindia", - "koreacentral", - "polandcentral", - "switzerlandnorth", - "norwayeast" + "usgovarizona", + "usgovvirginia" ], "metadata": { "description": "Location for all resources." @@ -187,6 +194,18 @@ "description": "Object mapping DNS zone names to their resource group, or empty string to indicate creation" } }, + "existingMonitorDnsZones": { + "type": "object", + "defaultValue": { + "privatelink.monitor.azure.com": "", + "privatelink.oms.opinsights.azure.com": "", + "privatelink.ods.opinsights.azure.com": "", + "privatelink.agentsvc.azure-automation.net": "" + }, + "metadata": { + "description": "Object mapping Azure Monitor private DNS zone names to the resource group of an existing zone, or empty string to create it. Use to bring your own centralized Private DNS Zones (e.g. an Azure Landing Zone connectivity subscription) for agent tracing." + } + }, "dnsZoneNames": { "type": "array", "defaultValue": [ @@ -248,9 +267,6 @@ }, "mode": "Incremental", "parameters": { - "location": { - "value": "[parameters('location')]" - }, "vnetName": { "value": "[variables('trimVnetName')]" }, @@ -277,6 +293,9 @@ }, "existingVnetSubscriptionId": { "value": "[variables('vnetSubscriptionId')]" + }, + "location": { + "value": "[parameters('location')]" } }, "template": { @@ -921,7 +940,7 @@ "_generator": { "name": "bicep", "version": "0.43.8.12551", - "templateHash": "1400943577065869287" + "templateHash": "10415108349705677394" } }, "parameters": { @@ -1519,6 +1538,411 @@ "[resourceId('Microsoft.Resources/deployments', format('vnet-{0}-{1}-deployment', variables('trimVnetName'), variables('uniqueSuffix')))]" ] }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2025-04-01", + "name": "[format('app-insights-{0}-deployment', variables('uniqueSuffix'))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "location": { + "value": "[parameters('location')]" + }, + "suffix": { + "value": "[variables('uniqueSuffix')]" + }, + "aiAccountName": { + "value": "[reference(resourceId('Microsoft.Resources/deployments', format('{0}-{1}-deployment', variables('accountName'), variables('uniqueSuffix'))), '2025-04-01').outputs.accountName.value]" + }, + "disablePublicIngestion": { + "value": true + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.43.8.12551", + "templateHash": "14903937882087600421" + } + }, + "parameters": { + "location": { + "type": "string", + "metadata": { + "description": "Azure region for the tracing resources." + } + }, + "suffix": { + "type": "string", + "metadata": { + "description": "Suffix for unique resource names (the template uniqueSuffix)." + } + }, + "aiAccountName": { + "type": "string", + "metadata": { + "description": "Name of the Foundry (AI Services) account to connect Application Insights to." + } + }, + "disablePublicIngestion": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "When true, disable public ingestion (reach Application Insights privately via AMPLS). Set false for public templates." + } + }, + "logAnalyticsName": { + "type": "string", + "defaultValue": "[format('law-tracing-{0}', parameters('suffix'))]", + "metadata": { + "description": "Name of the Log Analytics workspace to create." + } + }, + "appInsightsName": { + "type": "string", + "defaultValue": "[format('appi-tracing-{0}', parameters('suffix'))]", + "metadata": { + "description": "Name of the Application Insights component to create." + } + } + }, + "resources": [ + { + "type": "Microsoft.OperationalInsights/workspaces", + "apiVersion": "2023-09-01", + "name": "[parameters('logAnalyticsName')]", + "location": "[parameters('location')]", + "properties": { + "sku": { + "name": "PerGB2018" + }, + "retentionInDays": 30 + } + }, + { + "type": "Microsoft.Insights/components", + "apiVersion": "2020-02-02", + "name": "[parameters('appInsightsName')]", + "location": "[parameters('location')]", + "kind": "web", + "properties": { + "Application_Type": "web", + "WorkspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('logAnalyticsName'))]", + "publicNetworkAccessForIngestion": "[if(parameters('disablePublicIngestion'), 'Disabled', 'Enabled')]", + "publicNetworkAccessForQuery": "Enabled" + }, + "dependsOn": [ + "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('logAnalyticsName'))]" + ] + }, + { + "type": "Microsoft.CognitiveServices/accounts/connections", + "apiVersion": "2025-04-01-preview", + "name": "[format('{0}/{1}', parameters('aiAccountName'), format('{0}-appinsights', parameters('aiAccountName')))]", + "properties": { + "category": "AppInsights", + "target": "[resourceId('Microsoft.Insights/components', parameters('appInsightsName'))]", + "authType": "ApiKey", + "isSharedToAll": true, + "credentials": { + "key": "[reference(resourceId('Microsoft.Insights/components', parameters('appInsightsName')), '2020-02-02').ConnectionString]" + }, + "metadata": { + "ApiType": "Azure", + "ResourceId": "[resourceId('Microsoft.Insights/components', parameters('appInsightsName'))]" + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Insights/components', parameters('appInsightsName'))]" + ] + } + ], + "outputs": { + "appInsightsId": { + "type": "string", + "metadata": { + "description": "Resource ID of the Application Insights component." + }, + "value": "[resourceId('Microsoft.Insights/components', parameters('appInsightsName'))]" + }, + "appInsightsAppId": { + "type": "string", + "metadata": { + "description": "Application ID of the Application Insights component (for trace queries)." + }, + "value": "[reference(resourceId('Microsoft.Insights/components', parameters('appInsightsName')), '2020-02-02').AppId]" + }, + "logAnalyticsId": { + "type": "string", + "metadata": { + "description": "Resource ID of the Log Analytics workspace backing Application Insights." + }, + "value": "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('logAnalyticsName'))]" + } + } + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', format('{0}-{1}-deployment', variables('accountName'), variables('uniqueSuffix')))]" + ] + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2025-04-01", + "name": "[format('monitor-pls-{0}-deployment', variables('uniqueSuffix'))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "location": { + "value": "[parameters('location')]" + }, + "suffix": { + "value": "[variables('uniqueSuffix')]" + }, + "appInsightsId": { + "value": "[reference(resourceId('Microsoft.Resources/deployments', format('app-insights-{0}-deployment', variables('uniqueSuffix'))), '2025-04-01').outputs.appInsightsId.value]" + }, + "logAnalyticsId": { + "value": "[reference(resourceId('Microsoft.Resources/deployments', format('app-insights-{0}-deployment', variables('uniqueSuffix'))), '2025-04-01').outputs.logAnalyticsId.value]" + }, + "vnetId": { + "value": "[reference(resourceId('Microsoft.Resources/deployments', format('vnet-{0}-{1}-deployment', variables('trimVnetName'), variables('uniqueSuffix'))), '2025-04-01').outputs.virtualNetworkId.value]" + }, + "peSubnetId": { + "value": "[reference(resourceId('Microsoft.Resources/deployments', format('vnet-{0}-{1}-deployment', variables('trimVnetName'), variables('uniqueSuffix'))), '2025-04-01').outputs.peSubnetId.value]" + }, + "existingDnsZones": { + "value": "[parameters('existingMonitorDnsZones')]" + }, + "dnsZonesSubscriptionId": { + "value": "[variables('resolvedDnsZonesSubscriptionId')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.43.8.12551", + "templateHash": "2109142665252549485" + } + }, + "parameters": { + "location": { + "type": "string", + "metadata": { + "description": "Azure region for the private endpoint." + } + }, + "suffix": { + "type": "string", + "metadata": { + "description": "Suffix for unique resource names (the template uniqueSuffix)." + } + }, + "appInsightsId": { + "type": "string", + "metadata": { + "description": "Resource ID of the Application Insights component to scope into the AMPLS." + } + }, + "logAnalyticsId": { + "type": "string", + "metadata": { + "description": "Resource ID of the Log Analytics workspace to scope into the AMPLS." + } + }, + "vnetId": { + "type": "string", + "metadata": { + "description": "Resource ID of the Virtual Network." + } + }, + "peSubnetId": { + "type": "string", + "metadata": { + "description": "Resource ID of the Private Endpoint subnet." + } + }, + "existingDnsZones": { + "type": "object", + "defaultValue": { + "privatelink.monitor.azure.com": "", + "privatelink.oms.opinsights.azure.com": "", + "privatelink.ods.opinsights.azure.com": "", + "privatelink.agentsvc.azure-automation.net": "" + }, + "metadata": { + "description": "Map of Azure Monitor private DNS zone name to the resource group of an existing zone. An empty string for a zone means the module creates and links it in this resource group; a non-empty resource group means bring your own existing (e.g. centralized Azure Landing Zone) zone, which is referenced instead of recreated." + } + }, + "dnsZonesSubscriptionId": { + "type": "string", + "defaultValue": "[subscription().subscriptionId]", + "metadata": { + "description": "Subscription ID where existing Azure Monitor private DNS zones are located. Defaults to the current subscription." + } + } + }, + "variables": { + "copy": [ + { + "name": "monitorDnsZoneIds", + "count": "[length(variables('monitorDnsZoneNames'))]", + "input": "[if(empty(parameters('existingDnsZones')[variables('monitorDnsZoneNames')[copyIndex('monitorDnsZoneIds')]]), resourceId('Microsoft.Network/privateDnsZones', variables('monitorDnsZoneNames')[copyIndex('monitorDnsZoneIds')]), extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('dnsZonesSubscriptionId'), parameters('existingDnsZones')[variables('monitorDnsZoneNames')[copyIndex('monitorDnsZoneIds')]]), 'Microsoft.Network/privateDnsZones', variables('monitorDnsZoneNames')[copyIndex('monitorDnsZoneIds')]))]" + } + ], + "monitorDnsZoneNames": [ + "privatelink.monitor.azure.com", + "privatelink.oms.opinsights.azure.com", + "privatelink.ods.opinsights.azure.com", + "privatelink.agentsvc.azure-automation.net" + ] + }, + "resources": [ + { + "type": "microsoft.insights/privateLinkScopes", + "apiVersion": "2021-07-01-preview", + "name": "[format('ampls-tracing-{0}', parameters('suffix'))]", + "location": "global", + "properties": { + "accessModeSettings": { + "ingestionAccessMode": "PrivateOnly", + "queryAccessMode": "Open" + } + } + }, + { + "type": "Microsoft.Insights/privateLinkScopes/scopedResources", + "apiVersion": "2021-07-01-preview", + "name": "[format('{0}/{1}', format('ampls-tracing-{0}', parameters('suffix')), 'appinsights-scoped')]", + "properties": { + "linkedResourceId": "[parameters('appInsightsId')]" + }, + "dependsOn": [ + "[resourceId('microsoft.insights/privateLinkScopes', format('ampls-tracing-{0}', parameters('suffix')))]" + ] + }, + { + "type": "Microsoft.Insights/privateLinkScopes/scopedResources", + "apiVersion": "2021-07-01-preview", + "name": "[format('{0}/{1}', format('ampls-tracing-{0}', parameters('suffix')), 'law-scoped')]", + "properties": { + "linkedResourceId": "[parameters('logAnalyticsId')]" + }, + "dependsOn": [ + "[resourceId('microsoft.insights/privateLinkScopes', format('ampls-tracing-{0}', parameters('suffix')))]" + ] + }, + { + "copy": { + "name": "monitorDnsZones", + "count": "[length(variables('monitorDnsZoneNames'))]" + }, + "condition": "[empty(parameters('existingDnsZones')[variables('monitorDnsZoneNames')[copyIndex()]])]", + "type": "Microsoft.Network/privateDnsZones", + "apiVersion": "2020-06-01", + "name": "[variables('monitorDnsZoneNames')[copyIndex()]]", + "location": "global" + }, + { + "copy": { + "name": "monitorDnsZoneLinks", + "count": "[length(variables('monitorDnsZoneNames'))]" + }, + "condition": "[empty(parameters('existingDnsZones')[variables('monitorDnsZoneNames')[copyIndex()]])]", + "type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks", + "apiVersion": "2024-06-01", + "name": "[format('{0}/{1}', variables('monitorDnsZoneNames')[copyIndex()], format('{0}-link', replace(variables('monitorDnsZoneNames')[copyIndex()], '.', '-')))]", + "location": "global", + "properties": { + "virtualNetwork": { + "id": "[parameters('vnetId')]" + }, + "registrationEnabled": false + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/privateDnsZones', variables('monitorDnsZoneNames')[copyIndex()])]" + ] + }, + { + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2024-05-01", + "name": "[format('ampls-tracing-{0}-pe', parameters('suffix'))]", + "location": "[parameters('location')]", + "properties": { + "subnet": { + "id": "[parameters('peSubnetId')]" + }, + "privateLinkServiceConnections": [ + { + "name": "ampls-connection", + "properties": { + "privateLinkServiceId": "[resourceId('microsoft.insights/privateLinkScopes', format('ampls-tracing-{0}', parameters('suffix')))]", + "groupIds": [ + "azuremonitor" + ] + } + } + ] + }, + "dependsOn": [ + "[resourceId('microsoft.insights/privateLinkScopes', format('ampls-tracing-{0}', parameters('suffix')))]", + "[resourceId('Microsoft.Insights/privateLinkScopes/scopedResources', format('ampls-tracing-{0}', parameters('suffix')), 'appinsights-scoped')]", + "[resourceId('Microsoft.Insights/privateLinkScopes/scopedResources', format('ampls-tracing-{0}', parameters('suffix')), 'law-scoped')]" + ] + }, + { + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2024-05-01", + "name": "[format('{0}/{1}', format('ampls-tracing-{0}-pe', parameters('suffix')), 'ampls-dns')]", + "properties": { + "copy": [ + { + "name": "privateDnsZoneConfigs", + "count": "[length(variables('monitorDnsZoneNames'))]", + "input": { + "name": "[replace(variables('monitorDnsZoneNames')[copyIndex('privateDnsZoneConfigs')], '.', '-')]", + "properties": { + "privateDnsZoneId": "[variables('monitorDnsZoneIds')[copyIndex('privateDnsZoneConfigs')]]" + } + } + } + ] + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/privateEndpoints', format('ampls-tracing-{0}-pe', parameters('suffix')))]", + "monitorDnsZoneLinks" + ] + } + ], + "outputs": { + "amplsId": { + "type": "string", + "metadata": { + "description": "Resource ID of the Azure Monitor Private Link Scope." + }, + "value": "[resourceId('microsoft.insights/privateLinkScopes', format('ampls-tracing-{0}', parameters('suffix')))]" + } + } + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', format('app-insights-{0}-deployment', variables('uniqueSuffix')))]", + "[resourceId('Microsoft.Resources/deployments', format('{0}-private-endpoint', variables('uniqueSuffix')))]", + "[resourceId('Microsoft.Resources/deployments', format('vnet-{0}-{1}-deployment', variables('trimVnetName'), variables('uniqueSuffix')))]" + ] + }, { "type": "Microsoft.Resources/deployments", "apiVersion": "2025-04-01", diff --git a/infrastructure/infrastructure-setup-bicep/15-private-network-standard-agent-setup/azuredeploy.json b/infrastructure/infrastructure-setup-bicep/15-private-network-standard-agent-setup/azuredeploy.json index 996387de9..0f27cbf60 100644 --- a/infrastructure/infrastructure-setup-bicep/15-private-network-standard-agent-setup/azuredeploy.json +++ b/infrastructure/infrastructure-setup-bicep/15-private-network-standard-agent-setup/azuredeploy.json @@ -5,38 +5,45 @@ "_generator": { "name": "bicep", "version": "0.44.1.10279", - "templateHash": "9826847652772805128" + "templateHash": "10515888316830505882" } }, "parameters": { "location": { "type": "string", - "defaultValue": "eastus", + "defaultValue": "[resourceGroup().location]", "allowedValues": [ - "westus", + "australiaeast", + "brazilsouth", + "canadacentral", + "canadaeast", + "centralindia", + "centralus", + "eastasia", "eastus", - "eastus2", - "japaneast", "francecentral", - "spaincentral", - "uaenorth", - "southcentralus", - "italynorth", "germanywestcentral", - "brazilsouth", + "italynorth", + "japaneast", + "koreacentral", + "northcentralus", + "northeurope", + "norwayeast", + "qatarcentral", "southafricanorth", - "australiaeast", + "southcentralus", + "southindia", + "southeastasia", + "spaincentral", "swedencentral", - "canadaeast", - "canadacentral", + "switzerlandnorth", + "uaenorth", + "uksouth", "westeurope", + "westus", "westus3", - "uksouth", - "southindia", - "koreacentral", - "polandcentral", - "switzerlandnorth", - "norwayeast" + "usgovarizona", + "usgovvirginia" ], "metadata": { "description": "Location for all resources." @@ -175,6 +182,13 @@ "description": "Optional. When true, skip the model deployment. Recommended when reusing an existing account that already has the required model deployments." } }, + "disableLocalAuth": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. When true (default), disables API-key (local) authentication on the account. Set to false to enable API-key auth." + } + }, "enableContainerRegistry": { "type": "bool", "defaultValue": true, @@ -193,7 +207,7 @@ "type": "bool", "defaultValue": false, "metadata": { - "description": "Optional. Create the account-level capability host explicitly. Leave false for fresh deployments (platform auto-creates it via networkInjections). Set true only for a BYO account with no capability host, or to recreate after running deleteCapHost.sh." + "description": "Optional. Create the account-level capability host explicitly. Leave false for fresh deployments (the platform auto-creates {account}@aml_aiagentservice via networkInjections.scenario=agent). Set true only for a BYO account with no capability host, or to recreate after running deleteCapHost.sh." } }, "aiSearchResourceId": { @@ -308,7 +322,8 @@ "vnetResourceGroupName": "[if(variables('existingVnetPassedIn'), variables('vnetParts')[4], resourceGroup().name)]", "existingVnetName": "[if(variables('existingVnetPassedIn'), last(variables('vnetParts')), parameters('vnetName'))]", "trimVnetName": "[trim(variables('existingVnetName'))]", - "normalizedDnsZonesSubscriptionId": "[if(empty(parameters('dnsZonesSubscriptionId')), '', if(startsWith(toLower(parameters('dnsZonesSubscriptionId')), '/subscriptions/'), split(parameters('dnsZonesSubscriptionId'), '/')[2], parameters('dnsZonesSubscriptionId')))]", + "trimmedDnsZonesSubscriptionId": "[trim(parameters('dnsZonesSubscriptionId'))]", + "normalizedDnsZonesSubscriptionId": "[if(empty(variables('trimmedDnsZonesSubscriptionId')), '', if(startsWith(toLower(variables('trimmedDnsZonesSubscriptionId')), '/subscriptions/'), trim(split(variables('trimmedDnsZonesSubscriptionId'), '/')[2]), variables('trimmedDnsZonesSubscriptionId')))]", "resolvedDnsZonesSubscriptionId": "[if(empty(variables('normalizedDnsZonesSubscriptionId')), subscription().subscriptionId, variables('normalizedDnsZonesSubscriptionId'))]" }, "resources": [ @@ -1014,6 +1029,9 @@ }, "skipModelDeployment": { "value": "[parameters('skipModelDeployment')]" + }, + "disableLocalAuth": { + "value": "[parameters('disableLocalAuth')]" } }, "template": { @@ -1023,7 +1041,7 @@ "_generator": { "name": "bicep", "version": "0.44.1.10279", - "templateHash": "16030204193894738620" + "templateHash": "11271143357343719419" } }, "parameters": { @@ -1068,6 +1086,13 @@ "metadata": { "description": "Optional. When true, skip the model deployment. Recommended when reusing an existing account that already has the required model deployments." } + }, + "disableLocalAuth": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. When true (default), disables API-key (local) authentication on the account. Set to false to enable API-key auth." + } } }, "variables": { @@ -1102,7 +1127,7 @@ }, "publicNetworkAccess": "Disabled", "networkInjections": "[if(equals(parameters('networkInjection'), 'true'), createArray(createObject('scenario', 'agent', 'subnetArmId', parameters('agentSubnetId'), 'useMicrosoftManagedNetwork', false())), null())]", - "disableLocalAuth": false + "disableLocalAuth": "[parameters('disableLocalAuth')]" } }, { @@ -1634,6 +1659,9 @@ "aiAccountName": { "value": "[reference(resourceId('Microsoft.Resources/deployments', format('{0}-{1}-deployment', variables('accountName'), variables('uniqueSuffix'))), '2025-04-01').outputs.accountName.value]" }, + "location": { + "value": "[parameters('location')]" + }, "aiSearchName": { "value": "[reference(resourceId('Microsoft.Resources/deployments', format('dependencies-{0}-deployment', variables('uniqueSuffix'))), '2025-04-01').outputs.aiSearchName.value]" }, @@ -1690,10 +1718,17 @@ "_generator": { "name": "bicep", "version": "0.44.1.10279", - "templateHash": "698272236681194869" + "templateHash": "8364807033973878778" } }, "parameters": { + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Azure region for the private endpoints. Defaults to the resource group location for backward compatibility; pass the deployment location so private endpoints are co-located with their target resources when the resource group is in a different region." + } + }, "aiAccountName": { "type": "string", "metadata": { @@ -1838,7 +1873,7 @@ "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2024-05-01", "name": "[format('{0}-private-endpoint', parameters('aiAccountName'))]", - "location": "[resourceGroup().location]", + "location": "[parameters('location')]", "properties": { "subnet": { "id": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('vnetSubscriptionId'), parameters('vnetResourceGroupName')), 'Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('peSubnetName'))]" @@ -1860,7 +1895,7 @@ "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2024-05-01", "name": "[format('{0}-private-endpoint', parameters('aiSearchName'))]", - "location": "[resourceGroup().location]", + "location": "[parameters('location')]", "properties": { "subnet": { "id": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('vnetSubscriptionId'), parameters('vnetResourceGroupName')), 'Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('peSubnetName'))]" @@ -1882,7 +1917,7 @@ "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2024-05-01", "name": "[format('{0}-private-endpoint', parameters('storageName'))]", - "location": "[resourceGroup().location]", + "location": "[parameters('location')]", "properties": { "subnet": { "id": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('vnetSubscriptionId'), parameters('vnetResourceGroupName')), 'Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('peSubnetName'))]" @@ -1904,7 +1939,7 @@ "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2024-05-01", "name": "[format('{0}-private-endpoint', parameters('cosmosDBName'))]", - "location": "[resourceGroup().location]", + "location": "[parameters('location')]", "properties": { "subnet": { "id": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('vnetSubscriptionId'), parameters('vnetResourceGroupName')), 'Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('peSubnetName'))]" diff --git a/infrastructure/infrastructure-setup-bicep/15-private-network-standard-agent-setup/main.bicep b/infrastructure/infrastructure-setup-bicep/15-private-network-standard-agent-setup/main.bicep index a24054bbc..7a87b3006 100644 --- a/infrastructure/infrastructure-setup-bicep/15-private-network-standard-agent-setup/main.bicep +++ b/infrastructure/infrastructure-setup-bicep/15-private-network-standard-agent-setup/main.bicep @@ -4,34 +4,39 @@ Standard Setup Network Secured Steps for main.bicep */ @description('Location for all resources.') @allowed([ - 'westus' + 'australiaeast' + 'brazilsouth' + 'canadacentral' + 'canadaeast' + 'centralindia' + 'centralus' + 'eastasia' 'eastus' - 'eastus2' - 'japaneast' 'francecentral' - 'spaincentral' - 'uaenorth' - 'southcentralus' - 'italynorth' 'germanywestcentral' - 'brazilsouth' + 'italynorth' + 'japaneast' + 'koreacentral' + 'northcentralus' + 'northeurope' + 'norwayeast' + 'qatarcentral' 'southafricanorth' - 'australiaeast' + 'southcentralus' + 'southindia' + 'southeastasia' + 'spaincentral' 'swedencentral' - 'canadaeast' - 'canadacentral' + 'switzerlandnorth' + 'uaenorth' + 'uksouth' 'westeurope' + 'westus' 'westus3' - 'uksouth' - 'southindia' - - //only class B and C - 'koreacentral' - 'polandcentral' - 'switzerlandnorth' - 'norwayeast' + 'usgovarizona' + 'usgovvirginia' ]) -param location string = 'eastus' +param location string = any(resourceGroup().location) @description('Name for your AI Services resource.') param aiServices string = 'aiservices' diff --git a/infrastructure/infrastructure-setup-bicep/15a-private-network-evaluation-only-setup/azuredeploy.json b/infrastructure/infrastructure-setup-bicep/15a-private-network-evaluation-only-setup/azuredeploy.json index c7961011b..1caddb166 100644 --- a/infrastructure/infrastructure-setup-bicep/15a-private-network-evaluation-only-setup/azuredeploy.json +++ b/infrastructure/infrastructure-setup-bicep/15a-private-network-evaluation-only-setup/azuredeploy.json @@ -5,37 +5,46 @@ "_generator": { "name": "bicep", "version": "0.44.1.10279", - "templateHash": "1049320424415381171" + "templateHash": "4021946098953778789" } }, "parameters": { "location": { "type": "string", - "defaultValue": "eastus", + "defaultValue": "[resourceGroup().location]", "allowedValues": [ - "westus", + "australiaeast", + "brazilsouth", + "westeurope", + "canadaeast", + "canadacentral", + "centralindia", + "centralus", + "eastasia", "eastus", - "eastus2", - "japaneast", "francecentral", - "spaincentral", - "uaenorth", - "southcentralus", - "italynorth", "germanywestcentral", - "brazilsouth", + "italynorth", + "japaneast", + "koreacentral", + "northcentralus", + "northeurope", + "norwayeast", + "qatarcentral", "southafricanorth", - "australiaeast", + "southcentralus", + "southindia", + "southeastasia", + "spaincentral", "swedencentral", - "canadaeast", + "switzerlandnorth", + "uaenorth", + "uksouth", "westeurope", + "westus", "westus3", - "uksouth", - "southindia", - "koreacentral", - "polandcentral", - "switzerlandnorth", - "norwayeast" + "usgovarizona", + "usgovvirginia" ], "metadata": { "description": "Location for all resources." @@ -1262,6 +1271,9 @@ "aiAccountName": { "value": "[reference(resourceId('Microsoft.Resources/deployments', format('{0}-{1}-deployment', variables('accountName'), variables('uniqueSuffix'))), '2025-04-01').outputs.accountName.value]" }, + "location": { + "value": "[parameters('location')]" + }, "storageName": { "value": "[reference(resourceId('Microsoft.Resources/deployments', format('dependencies-{0}-deployment', variables('uniqueSuffix'))), '2025-04-01').outputs.azureStorageName.value]" }, @@ -1300,10 +1312,17 @@ "_generator": { "name": "bicep", "version": "0.44.1.10279", - "templateHash": "11525768866797919522" + "templateHash": "2137547566661638544" } }, "parameters": { + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Azure region for the private endpoints. Defaults to the resource group location for backward compatibility; pass the deployment location so private endpoints are co-located with their target resources when the resource group is in a different region." + } + }, "aiAccountName": { "type": "string", "metadata": { @@ -1400,7 +1419,7 @@ "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2024-05-01", "name": "[format('{0}-private-endpoint', parameters('aiAccountName'))]", - "location": "[resourceGroup().location]", + "location": "[parameters('location')]", "properties": { "subnet": { "id": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('vnetSubscriptionId'), parameters('vnetResourceGroupName')), 'Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('peSubnetName'))]" @@ -1422,7 +1441,7 @@ "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2024-05-01", "name": "[format('{0}-private-endpoint', parameters('storageName'))]", - "location": "[resourceGroup().location]", + "location": "[parameters('location')]", "properties": { "subnet": { "id": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('vnetSubscriptionId'), parameters('vnetResourceGroupName')), 'Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('peSubnetName'))]" diff --git a/infrastructure/infrastructure-setup-bicep/15a-private-network-evaluation-only-setup/foundry-private-setup/assets/bicep/account.bicep b/infrastructure/infrastructure-setup-bicep/15a-private-network-evaluation-only-setup/foundry-private-setup/assets/bicep/account.bicep index dae749cde..1c4946de2 100644 --- a/infrastructure/infrastructure-setup-bicep/15a-private-network-evaluation-only-setup/foundry-private-setup/assets/bicep/account.bicep +++ b/infrastructure/infrastructure-setup-bicep/15a-private-network-evaluation-only-setup/foundry-private-setup/assets/bicep/account.bicep @@ -1,4 +1,37 @@ -param location string +@allowed([ + 'australiaeast' + 'brazilsouth' + 'canadacentral' + 'canadaeast' + 'centralindia' + 'centralus' + 'eastasia' + 'eastus' + 'francecentral' + 'germanywestcentral' + 'italynorth' + 'japaneast' + 'koreacentral' + 'northcentralus' + 'northeurope' + 'norwayeast' + 'qatarcentral' + 'southafricanorth' + 'southcentralus' + 'southindia' + 'southeastasia' + 'spaincentral' + 'swedencentral' + 'switzerlandnorth' + 'uaenorth' + 'uksouth' + 'westeurope' + 'westus' + 'westus3' + 'usgovarizona' + 'usgovvirginia' +]) +param location string = any(resourceGroup().location) param config object resource account 'Microsoft.CognitiveServices/accounts@2025-04-01-preview' = { diff --git a/infrastructure/infrastructure-setup-bicep/15a-private-network-evaluation-only-setup/main.bicep b/infrastructure/infrastructure-setup-bicep/15a-private-network-evaluation-only-setup/main.bicep index 34c8e8dc2..455c781a5 100644 --- a/infrastructure/infrastructure-setup-bicep/15a-private-network-evaluation-only-setup/main.bicep +++ b/infrastructure/infrastructure-setup-bicep/15a-private-network-evaluation-only-setup/main.bicep @@ -11,33 +11,40 @@ use the hosted-agent runtime. */ @description('Location for all resources.') @allowed([ - 'westus' + 'australiaeast' + 'brazilsouth' + 'westeurope' + 'canadaeast' + 'canadacentral' + 'centralindia' + 'centralus' + 'eastasia' 'eastus' - 'eastus2' - 'japaneast' 'francecentral' - 'spaincentral' - 'uaenorth' - 'southcentralus' - 'italynorth' 'germanywestcentral' - 'brazilsouth' + 'italynorth' + 'japaneast' + 'koreacentral' + 'northcentralus' + 'northeurope' + 'norwayeast' + 'qatarcentral' 'southafricanorth' - 'australiaeast' + 'southcentralus' + 'southindia' + 'southeastasia' + 'spaincentral' 'swedencentral' - 'canadaeast' + 'switzerlandnorth' + 'uaenorth' + 'uksouth' 'westeurope' + 'westus' 'westus3' - 'uksouth' - 'southindia' - - //only class B and C - 'koreacentral' - 'polandcentral' - 'switzerlandnorth' - 'norwayeast' + 'usgovarizona' + 'usgovvirginia' ]) -param location string = 'eastus' +param location string = any(resourceGroup().location) @description('Name for your AI Services resource.') param aiServices string = 'aiservices' diff --git a/infrastructure/infrastructure-setup-bicep/16-private-network-standard-agent-apim-setup/azuredeploy.json b/infrastructure/infrastructure-setup-bicep/16-private-network-standard-agent-apim-setup/azuredeploy.json index 10b63f589..b3e1cc756 100644 --- a/infrastructure/infrastructure-setup-bicep/16-private-network-standard-agent-apim-setup/azuredeploy.json +++ b/infrastructure/infrastructure-setup-bicep/16-private-network-standard-agent-apim-setup/azuredeploy.json @@ -5,37 +5,47 @@ "_generator": { "name": "bicep", "version": "0.44.1.10279", - "templateHash": "9994558897589976517" + "templateHash": "3569752191722183606" } }, "parameters": { "location": { "type": "string", - "defaultValue": "eastus", + "defaultValue": "[resourceGroup().location]", "allowedValues": [ - "westus", + "australiaeast", + "brazilsouth", + "westeurope", + "canadaeast", + "canadacentral", + "centralindia", + "centralus", + "eastasia", "eastus", "eastus2", - "japaneast", "francecentral", - "spaincentral", - "uaenorth", - "southcentralus", - "italynorth", "germanywestcentral", - "brazilsouth", + "italynorth", + "japaneast", + "koreacentral", + "northcentralus", + "northeurope", + "norwayeast", + "qatarcentral", "southafricanorth", - "australiaeast", + "southcentralus", + "southindia", + "southeastasia", + "spaincentral", "swedencentral", - "canadaeast", + "switzerlandnorth", + "uaenorth", + "uksouth", "westeurope", + "westus", "westus3", - "uksouth", - "southindia", - "koreacentral", - "polandcentral", - "switzerlandnorth", - "norwayeast" + "usgovarizona", + "usgovvirginia" ], "metadata": { "description": "Location for all resources." @@ -967,7 +977,7 @@ "_generator": { "name": "bicep", "version": "0.44.1.10279", - "templateHash": "2739330245977037380" + "templateHash": "11729420280716349512" } }, "parameters": { @@ -998,6 +1008,13 @@ "networkInjection": { "type": "string", "defaultValue": "true" + }, + "developerIpCidr": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional caller CIDR for authenticated project SDK access. Leave empty for private-only access." + } } }, "resources": [ @@ -1019,10 +1036,10 @@ "networkAcls": { "defaultAction": "Deny", "virtualNetworkRules": [], - "ipRules": [], + "ipRules": "[if(empty(parameters('developerIpCidr')), createArray(), createArray(createObject('value', if(endsWith(parameters('developerIpCidr'), '/32'), split(parameters('developerIpCidr'), '/')[0], parameters('developerIpCidr')))))]", "bypass": "AzureServices" }, - "publicNetworkAccess": "Disabled", + "publicNetworkAccess": "[if(empty(parameters('developerIpCidr')), 'Disabled', 'Enabled')]", "networkInjections": "[if(equals(parameters('networkInjection'), 'true'), createArray(createObject('scenario', 'agent', 'subnetArmId', parameters('agentSubnetId'), 'useMicrosoftManagedNetwork', false())), null())]", "disableLocalAuth": true } @@ -1575,7 +1592,7 @@ "_generator": { "name": "bicep", "version": "0.44.1.10279", - "templateHash": "17319375375259513982" + "templateHash": "3037675488852350266" } }, "parameters": { @@ -1616,6 +1633,13 @@ "description": "Name of the Vnet" } }, + "privateEndpointLocation": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Azure region of the VNet and its private endpoints" + } + }, "peSubnetName": { "type": "string", "metadata": { @@ -1742,7 +1766,7 @@ "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2024-05-01", "name": "[format('{0}-private-endpoint', parameters('aiAccountName'))]", - "location": "[resourceGroup().location]", + "location": "[parameters('privateEndpointLocation')]", "properties": { "subnet": { "id": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('vnetSubscriptionId'), parameters('vnetResourceGroupName')), 'Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('peSubnetName'))]" @@ -1764,7 +1788,7 @@ "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2024-05-01", "name": "[format('{0}-private-endpoint', parameters('aiSearchName'))]", - "location": "[resourceGroup().location]", + "location": "[parameters('privateEndpointLocation')]", "properties": { "subnet": { "id": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('vnetSubscriptionId'), parameters('vnetResourceGroupName')), 'Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('peSubnetName'))]" @@ -1786,7 +1810,7 @@ "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2024-05-01", "name": "[format('{0}-private-endpoint', parameters('storageName'))]", - "location": "[resourceGroup().location]", + "location": "[parameters('privateEndpointLocation')]", "properties": { "subnet": { "id": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('vnetSubscriptionId'), parameters('vnetResourceGroupName')), 'Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('peSubnetName'))]" @@ -1808,7 +1832,7 @@ "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2024-05-01", "name": "[format('{0}-private-endpoint', parameters('cosmosDBName'))]", - "location": "[resourceGroup().location]", + "location": "[parameters('privateEndpointLocation')]", "properties": { "subnet": { "id": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('vnetSubscriptionId'), parameters('vnetResourceGroupName')), 'Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('peSubnetName'))]" @@ -1831,7 +1855,7 @@ "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2024-05-01", "name": "[format('{0}-private-endpoint', parameters('apiManagementName'))]", - "location": "[resourceGroup().location]", + "location": "[parameters('privateEndpointLocation')]", "properties": { "subnet": { "id": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('vnetSubscriptionId'), parameters('vnetResourceGroupName')), 'Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('peSubnetName'))]" diff --git a/infrastructure/infrastructure-setup-bicep/16-private-network-standard-agent-apim-setup/extensions/ai-gateway-tier-private/azuredeploy.json b/infrastructure/infrastructure-setup-bicep/16-private-network-standard-agent-apim-setup/extensions/ai-gateway-tier-private/azuredeploy.json index 2d23dbfda..506f1e957 100644 --- a/infrastructure/infrastructure-setup-bicep/16-private-network-standard-agent-apim-setup/extensions/ai-gateway-tier-private/azuredeploy.json +++ b/infrastructure/infrastructure-setup-bicep/16-private-network-standard-agent-apim-setup/extensions/ai-gateway-tier-private/azuredeploy.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.46.1.21595", - "templateHash": "9097858196024894984" + "templateHash": "2291527954509146527" } }, "parameters": { @@ -13,11 +13,10 @@ "type": "string", "defaultValue": "swedencentral", "allowedValues": [ - "eastus2", "swedencentral" ], "metadata": { - "description": "Region for every resource in this sample. The AIGateway SKU is a release-gated preview available only in East US 2 / Sweden Central, and its outbound integration needs a co-regional VNet, so the whole sample deploys in one of these regions." + "description": "Region for resources that require the AI Gateway tier and its co-regional VNet." } }, "aiServices": { @@ -378,7 +377,7 @@ "type": "Microsoft.CognitiveServices/accounts", "apiVersion": "2025-04-01-preview", "name": "[variables('hubName')]", - "location": "[parameters('region')]", + "location": "[resourceGroup().location]", "sku": { "name": "S0" }, diff --git a/infrastructure/infrastructure-setup-bicep/16-private-network-standard-agent-apim-setup/extensions/ai-gateway-tier-private/main.bicep b/infrastructure/infrastructure-setup-bicep/16-private-network-standard-agent-apim-setup/extensions/ai-gateway-tier-private/main.bicep index bfbfd13e8..a9709bec6 100644 --- a/infrastructure/infrastructure-setup-bicep/16-private-network-standard-agent-apim-setup/extensions/ai-gateway-tier-private/main.bicep +++ b/infrastructure/infrastructure-setup-bicep/16-private-network-standard-agent-apim-setup/extensions/ai-gateway-tier-private/main.bicep @@ -35,9 +35,9 @@ - The ModelGateway "Admin-connected models" connection on the project, so an agent references the model as /. - Single region: the AIGateway SKU deploys only in East US 2 / Sweden Central, and - outbound integration requires the VNet in the SAME region, so the whole sample - deploys in one of those regions (default swedencentral). The region parameter is + Single region: the AIGateway SKU is release-gated, and outbound integration + requires the VNet in the SAME region, so the whole sample deploys in Sweden + Central. The region parameter is named `region` (not `location`) so generic tooling that rewrites `location` cannot relocate an AIGateway sample out of its supported regions. @@ -60,10 +60,9 @@ targetScope = 'resourceGroup' // cannot relocate an AIGateway sample out of its supported regions. // --------------------------------------------------------------------------- @allowed([ - 'eastus2' 'swedencentral' ]) -@description('Region for every resource in this sample. The AIGateway SKU is a release-gated preview available only in East US 2 / Sweden Central, and its outbound integration needs a co-regional VNet, so the whole sample deploys in one of these regions.') +@description('Region for resources that require the AI Gateway tier and its co-regional VNet.') param region string = 'swedencentral' // =========================================================================== diff --git a/infrastructure/infrastructure-setup-bicep/16-private-network-standard-agent-apim-setup/extensions/ai-gateway-tier-private/main.json b/infrastructure/infrastructure-setup-bicep/16-private-network-standard-agent-apim-setup/extensions/ai-gateway-tier-private/main.json index 956824942..506f1e957 100644 --- a/infrastructure/infrastructure-setup-bicep/16-private-network-standard-agent-apim-setup/extensions/ai-gateway-tier-private/main.json +++ b/infrastructure/infrastructure-setup-bicep/16-private-network-standard-agent-apim-setup/extensions/ai-gateway-tier-private/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.46.1.21595", - "templateHash": "8402656451811108928" + "templateHash": "2291527954509146527" } }, "parameters": { @@ -13,11 +13,10 @@ "type": "string", "defaultValue": "swedencentral", "allowedValues": [ - "eastus2", "swedencentral" ], "metadata": { - "description": "Region for every resource in this sample. The AIGateway SKU is a release-gated preview available only in East US 2 / Sweden Central, and its outbound integration needs a co-regional VNet, so the whole sample deploys in one of these regions." + "description": "Region for resources that require the AI Gateway tier and its co-regional VNet." } }, "aiServices": { @@ -378,7 +377,7 @@ "type": "Microsoft.CognitiveServices/accounts", "apiVersion": "2025-04-01-preview", "name": "[variables('hubName')]", - "location": "[parameters('region')]", + "location": "[resourceGroup().location]", "sku": { "name": "S0" }, @@ -1867,6 +1866,9 @@ "peSubnetName": { "value": "[reference(resourceId('Microsoft.Resources/deployments', format('vnet-{0}-{1}-deployment', variables('trimVnetName'), variables('uniqueSuffix'))), '2025-04-01').outputs.peSubnetName.value]" }, + "privateEndpointLocation": { + "value": "[parameters('region')]" + }, "suffix": { "value": "[variables('uniqueSuffix')]" }, diff --git a/infrastructure/infrastructure-setup-bicep/16-private-network-standard-agent-apim-setup/main.bicep b/infrastructure/infrastructure-setup-bicep/16-private-network-standard-agent-apim-setup/main.bicep index b5dca56c2..bc3fa68c3 100644 --- a/infrastructure/infrastructure-setup-bicep/16-private-network-standard-agent-apim-setup/main.bicep +++ b/infrastructure/infrastructure-setup-bicep/16-private-network-standard-agent-apim-setup/main.bicep @@ -4,33 +4,41 @@ Standard Setup Network Secured Steps for main.bicep */ @description('Location for all resources.') @allowed([ - 'westus' + 'australiaeast' + 'brazilsouth' + 'westeurope' + 'canadaeast' + 'canadacentral' + 'centralindia' + 'centralus' + 'eastasia' 'eastus' 'eastus2' - 'japaneast' 'francecentral' - 'spaincentral' - 'uaenorth' - 'southcentralus' - 'italynorth' 'germanywestcentral' - 'brazilsouth' + 'italynorth' + 'japaneast' + 'koreacentral' + 'northcentralus' + 'northeurope' + 'norwayeast' + 'qatarcentral' 'southafricanorth' - 'australiaeast' + 'southcentralus' + 'southindia' + 'southeastasia' + 'spaincentral' 'swedencentral' - 'canadaeast' + 'switzerlandnorth' + 'uaenorth' + 'uksouth' 'westeurope' + 'westus' 'westus3' - 'uksouth' - 'southindia' - - //only class B and C - 'koreacentral' - 'polandcentral' - 'switzerlandnorth' - 'norwayeast' + 'usgovarizona' + 'usgovvirginia' ]) -param location string = 'eastus' +param location string = any(resourceGroup().location) @description('Name for your AI Services resource.') param aiServices string = 'aiservices' diff --git a/infrastructure/infrastructure-setup-bicep/17-private-network-standard-user-assigned-identity-agent-setup/azuredeploy.json b/infrastructure/infrastructure-setup-bicep/17-private-network-standard-user-assigned-identity-agent-setup/azuredeploy.json index 3c81141da..74fd7b14b 100644 --- a/infrastructure/infrastructure-setup-bicep/17-private-network-standard-user-assigned-identity-agent-setup/azuredeploy.json +++ b/infrastructure/infrastructure-setup-bicep/17-private-network-standard-user-assigned-identity-agent-setup/azuredeploy.json @@ -5,37 +5,47 @@ "_generator": { "name": "bicep", "version": "0.44.1.10279", - "templateHash": "3200715244185012959" + "templateHash": "9928725688431345567" } }, "parameters": { "location": { "type": "string", - "defaultValue": "eastus", + "defaultValue": "[resourceGroup().location]", "allowedValues": [ - "westus", + "australiaeast", + "brazilsouth", + "westeurope", + "canadaeast", + "canadacentral", + "centralindia", + "centralus", + "eastasia", "eastus", "eastus2", - "japaneast", "francecentral", - "spaincentral", - "uaenorth", - "southcentralus", - "italynorth", "germanywestcentral", - "brazilsouth", + "italynorth", + "japaneast", + "koreacentral", + "northcentralus", + "northeurope", + "norwayeast", + "qatarcentral", "southafricanorth", - "australiaeast", + "southcentralus", + "southindia", + "southeastasia", + "spaincentral", "swedencentral", - "canadaeast", + "switzerlandnorth", + "uaenorth", + "uksouth", "westeurope", + "westus", "westus3", - "uksouth", - "southindia", - "koreacentral", - "polandcentral", - "switzerlandnorth", - "norwayeast" + "usgovarizona", + "usgovvirginia" ], "metadata": { "description": "Location for all resources." diff --git a/infrastructure/infrastructure-setup-bicep/17-private-network-standard-user-assigned-identity-agent-setup/main.bicep b/infrastructure/infrastructure-setup-bicep/17-private-network-standard-user-assigned-identity-agent-setup/main.bicep index b310c6b58..0a719e061 100644 --- a/infrastructure/infrastructure-setup-bicep/17-private-network-standard-user-assigned-identity-agent-setup/main.bicep +++ b/infrastructure/infrastructure-setup-bicep/17-private-network-standard-user-assigned-identity-agent-setup/main.bicep @@ -4,33 +4,41 @@ Standard Setup Network Secured Steps for main.bicep */ @description('Location for all resources.') @allowed([ - 'westus' + 'australiaeast' + 'brazilsouth' + 'westeurope' + 'canadaeast' + 'canadacentral' + 'centralindia' + 'centralus' + 'eastasia' 'eastus' 'eastus2' - 'japaneast' 'francecentral' - 'spaincentral' - 'uaenorth' - 'southcentralus' - 'italynorth' 'germanywestcentral' - 'brazilsouth' + 'italynorth' + 'japaneast' + 'koreacentral' + 'northcentralus' + 'northeurope' + 'norwayeast' + 'qatarcentral' 'southafricanorth' - 'australiaeast' + 'southcentralus' + 'southindia' + 'southeastasia' + 'spaincentral' 'swedencentral' - 'canadaeast' + 'switzerlandnorth' + 'uaenorth' + 'uksouth' 'westeurope' + 'westus' 'westus3' - 'uksouth' - 'southindia' - - //only class B and C - 'koreacentral' - 'polandcentral' - 'switzerlandnorth' - 'norwayeast' + 'usgovarizona' + 'usgovvirginia' ]) -param location string = 'eastus' +param location string = any(resourceGroup().location) @description('Name for your AI Services resource.') param aiServices string = 'aiservices' diff --git a/infrastructure/infrastructure-setup-bicep/18-managed-virtual-network/azuredeploy.json b/infrastructure/infrastructure-setup-bicep/18-managed-virtual-network/azuredeploy.json index 37309d909..b5dec65ec 100644 --- a/infrastructure/infrastructure-setup-bicep/18-managed-virtual-network/azuredeploy.json +++ b/infrastructure/infrastructure-setup-bicep/18-managed-virtual-network/azuredeploy.json @@ -5,13 +5,46 @@ "_generator": { "name": "bicep", "version": "0.46.1.21595", - "templateHash": "4680182353959664514" + "templateHash": "444853625905726767" } }, "parameters": { "location": { "type": "string", "defaultValue": "[resourceGroup().location]", + "allowedValues": [ + "australiaeast", + "brazilsouth", + "canadacentral", + "canadaeast", + "centralindia", + "centralus", + "eastasia", + "eastus", + "francecentral", + "germanywestcentral", + "italynorth", + "japaneast", + "koreacentral", + "northcentralus", + "northeurope", + "norwayeast", + "qatarcentral", + "southafricanorth", + "southcentralus", + "southindia", + "southeastasia", + "spaincentral", + "swedencentral", + "switzerlandnorth", + "uaenorth", + "uksouth", + "westeurope", + "westus", + "westus3", + "usgovarizona", + "usgovvirginia" + ], "metadata": { "description": "Location for all resources. Defaults to the resource group location." } @@ -761,7 +794,7 @@ "_generator": { "name": "bicep", "version": "0.46.1.21595", - "templateHash": "15908440120408802045" + "templateHash": "16980511502916134372" } }, "parameters": { @@ -1532,7 +1565,7 @@ "_generator": { "name": "bicep", "version": "0.46.1.21595", - "templateHash": "4721773589020153145" + "templateHash": "15999961836015539705" } }, "parameters": { @@ -1738,10 +1771,10 @@ }, "dependsOn": [ "[resourceId('Microsoft.Network/privateEndpoints', format('ampls-pe-{0}', parameters('suffix')))]", - "[resourceId('Microsoft.Network/privateDnsZones', variables('amplsDnsZones')[0])]", "[resourceId('Microsoft.Network/privateDnsZones', variables('amplsDnsZones')[1])]", + "[resourceId('Microsoft.Network/privateDnsZones', variables('amplsDnsZones')[2])]", "[resourceId('Microsoft.Network/privateDnsZones', variables('amplsDnsZones')[3])]", - "[resourceId('Microsoft.Network/privateDnsZones', variables('amplsDnsZones')[2])]" + "[resourceId('Microsoft.Network/privateDnsZones', variables('amplsDnsZones')[0])]" ] } ], diff --git a/infrastructure/infrastructure-setup-bicep/18-managed-virtual-network/main.bicep b/infrastructure/infrastructure-setup-bicep/18-managed-virtual-network/main.bicep index 716892fef..c0f9b33e7 100644 --- a/infrastructure/infrastructure-setup-bicep/18-managed-virtual-network/main.bicep +++ b/infrastructure/infrastructure-setup-bicep/18-managed-virtual-network/main.bicep @@ -3,7 +3,40 @@ Standard Setup Managed Network Secured Steps for main.bicep ----------------------------------- */ @description('Location for all resources. Defaults to the resource group location.') -param location string = resourceGroup().location +@allowed([ + 'australiaeast' + 'brazilsouth' + 'canadacentral' + 'canadaeast' + 'centralindia' + 'centralus' + 'eastasia' + 'eastus' + 'francecentral' + 'germanywestcentral' + 'italynorth' + 'japaneast' + 'koreacentral' + 'northcentralus' + 'northeurope' + 'norwayeast' + 'qatarcentral' + 'southafricanorth' + 'southcentralus' + 'southindia' + 'southeastasia' + 'spaincentral' + 'swedencentral' + 'switzerlandnorth' + 'uaenorth' + 'uksouth' + 'westeurope' + 'westus' + 'westus3' + 'usgovarizona' + 'usgovvirginia' +]) +param location string = any(resourceGroup().location) @description('The isolation mode for the managed network') @allowed([ diff --git a/infrastructure/infrastructure-setup-bicep/19-private-network-agent-tools/azuredeploy.json b/infrastructure/infrastructure-setup-bicep/19-private-network-agent-tools/azuredeploy.json index 223561bde..f9c435c6e 100644 --- a/infrastructure/infrastructure-setup-bicep/19-private-network-agent-tools/azuredeploy.json +++ b/infrastructure/infrastructure-setup-bicep/19-private-network-agent-tools/azuredeploy.json @@ -5,39 +5,46 @@ "_generator": { "name": "bicep", "version": "0.48.1.52935", - "templateHash": "1473442548359709863" + "templateHash": "12442000905807844856" } }, "parameters": { "location": { "type": "string", - "defaultValue": "eastus2", + "defaultValue": "[resourceGroup().location]", "allowedValues": [ - "westus", - "westus2", + "australiaeast", + "brazilsouth", + "canadacentral", + "canadaeast", + "centralindia", + "centralus", + "eastasia", "eastus", "eastus2", - "japaneast", "francecentral", - "spaincentral", - "uaenorth", - "southcentralus", - "italynorth", "germanywestcentral", - "brazilsouth", + "italynorth", + "japaneast", + "koreacentral", + "northcentralus", + "northeurope", + "norwayeast", + "qatarcentral", "southafricanorth", - "australiaeast", + "southcentralus", + "southindia", + "southeastasia", + "spaincentral", "swedencentral", - "canadaeast", - "canadacentral", + "switzerlandnorth", + "uaenorth", + "uksouth", "westeurope", + "westus", "westus3", - "uksouth", - "southindia", - "koreacentral", - "polandcentral", - "switzerlandnorth", - "norwayeast" + "usgovarizona", + "usgovvirginia" ], "metadata": { "description": "Location for all resources." @@ -1942,7 +1949,7 @@ "_generator": { "name": "bicep", "version": "0.48.1.52935", - "templateHash": "5993399431326858546" + "templateHash": "13245946831715248629" } }, "parameters": { @@ -2282,9 +2289,9 @@ }, "dependsOn": [ "[resourceId('Microsoft.Network/privateEndpoints', format('{0}-private-endpoint', parameters('aiAccountName')))]", - "[resourceId('Microsoft.Resources/deployments', format('dns-{0}-{1}', replace(variables('dnsZoneEntries')[indexOf(variables('dnsZoneKeys'), variables('cognitiveServicesDnsZoneName'))].key, '.', '-'), parameters('suffix')))]", + "[resourceId('Microsoft.Resources/deployments', format('dns-{0}-{1}', replace(variables('dnsZoneEntries')[indexOf(variables('dnsZoneKeys'), variables('aiServicesDnsZoneName'))].key, '.', '-'), parameters('suffix')))]", "[resourceId('Microsoft.Resources/deployments', format('dns-{0}-{1}', replace(variables('dnsZoneEntries')[indexOf(variables('dnsZoneKeys'), variables('openAiDnsZoneName'))].key, '.', '-'), parameters('suffix')))]", - "[resourceId('Microsoft.Resources/deployments', format('dns-{0}-{1}', replace(variables('dnsZoneEntries')[indexOf(variables('dnsZoneKeys'), variables('aiServicesDnsZoneName'))].key, '.', '-'), parameters('suffix')))]" + "[resourceId('Microsoft.Resources/deployments', format('dns-{0}-{1}', replace(variables('dnsZoneEntries')[indexOf(variables('dnsZoneKeys'), variables('cognitiveServicesDnsZoneName'))].key, '.', '-'), parameters('suffix')))]" ] }, { diff --git a/infrastructure/infrastructure-setup-bicep/19-private-network-agent-tools/main.bicep b/infrastructure/infrastructure-setup-bicep/19-private-network-agent-tools/main.bicep index 1180c4618..86e6e9760 100644 --- a/infrastructure/infrastructure-setup-bicep/19-private-network-agent-tools/main.bicep +++ b/infrastructure/infrastructure-setup-bicep/19-private-network-agent-tools/main.bicep @@ -18,35 +18,40 @@ Architecture: */ @description('Location for all resources.') @allowed([ - 'westus' - 'westus2' + 'australiaeast' + 'brazilsouth' + 'canadacentral' + 'canadaeast' + 'centralindia' + 'centralus' + 'eastasia' 'eastus' 'eastus2' - 'japaneast' 'francecentral' - 'spaincentral' - 'uaenorth' - 'southcentralus' - 'italynorth' 'germanywestcentral' - 'brazilsouth' + 'italynorth' + 'japaneast' + 'koreacentral' + 'northcentralus' + 'northeurope' + 'norwayeast' + 'qatarcentral' 'southafricanorth' - 'australiaeast' + 'southcentralus' + 'southindia' + 'southeastasia' + 'spaincentral' 'swedencentral' - 'canadaeast' - 'canadacentral' + 'switzerlandnorth' + 'uaenorth' + 'uksouth' 'westeurope' + 'westus' 'westus3' - 'uksouth' - 'southindia' - - //only class B and C - 'koreacentral' - 'polandcentral' - 'switzerlandnorth' - 'norwayeast' + 'usgovarizona' + 'usgovvirginia' ]) -param location string = 'eastus2' +param location string = any(resourceGroup().location) @description('Name prefix for your AI Services (Cognitive Services) resource. Lowercase alphanumeric only; a 4-character random suffix will be appended.') @minLength(2) diff --git a/infrastructure/infrastructure-setup-bicep/20-user-assigned-identity/azuredeploy.json b/infrastructure/infrastructure-setup-bicep/20-user-assigned-identity/azuredeploy.json index 65e3539a4..46d219d99 100644 --- a/infrastructure/infrastructure-setup-bicep/20-user-assigned-identity/azuredeploy.json +++ b/infrastructure/infrastructure-setup-bicep/20-user-assigned-identity/azuredeploy.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.46.1.21595", - "templateHash": "7883696456086450703" + "templateHash": "9897266059106628420" } }, "parameters": { @@ -18,7 +18,40 @@ }, "location": { "type": "string", - "defaultValue": "eastus2", + "defaultValue": "[resourceGroup().location]", + "allowedValues": [ + "australiaeast", + "brazilsouth", + "canadacentral", + "canadaeast", + "centralindia", + "centralus", + "eastasia", + "eastus", + "francecentral", + "germanywestcentral", + "italynorth", + "japaneast", + "koreacentral", + "northcentralus", + "northeurope", + "norwayeast", + "qatarcentral", + "southafricanorth", + "southcentralus", + "southindia", + "southeastasia", + "spaincentral", + "swedencentral", + "switzerlandnorth", + "uaenorth", + "uksouth", + "westeurope", + "westus", + "westus3", + "usgovarizona", + "usgovvirginia" + ], "metadata": { "description": "Location for all resources." } diff --git a/infrastructure/infrastructure-setup-bicep/20-user-assigned-identity/main.bicep b/infrastructure/infrastructure-setup-bicep/20-user-assigned-identity/main.bicep index 029ca6283..7d987c5ba 100644 --- a/infrastructure/infrastructure-setup-bicep/20-user-assigned-identity/main.bicep +++ b/infrastructure/infrastructure-setup-bicep/20-user-assigned-identity/main.bicep @@ -15,7 +15,40 @@ param aiFoundryName string = 'foundry-uai' @description('Location for all resources.') -param location string = 'eastus2' +@allowed([ + 'australiaeast' + 'brazilsouth' + 'canadacentral' + 'canadaeast' + 'centralindia' + 'centralus' + 'eastasia' + 'eastus' + 'francecentral' + 'germanywestcentral' + 'italynorth' + 'japaneast' + 'koreacentral' + 'northcentralus' + 'northeurope' + 'norwayeast' + 'qatarcentral' + 'southafricanorth' + 'southcentralus' + 'southindia' + 'southeastasia' + 'spaincentral' + 'swedencentral' + 'switzerlandnorth' + 'uaenorth' + 'uksouth' + 'westeurope' + 'westus' + 'westus3' + 'usgovarizona' + 'usgovvirginia' +]) +param location string = any(resourceGroup().location) @description('Name of the first project') param defaultProjectName string = '${aiFoundryName}-proj' diff --git a/infrastructure/infrastructure-setup-bicep/20-user-assigned-identity/main.json b/infrastructure/infrastructure-setup-bicep/20-user-assigned-identity/main.json index 65e3539a4..e4473a158 100644 --- a/infrastructure/infrastructure-setup-bicep/20-user-assigned-identity/main.json +++ b/infrastructure/infrastructure-setup-bicep/20-user-assigned-identity/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.46.1.21595", - "templateHash": "7883696456086450703" + "templateHash": "9897266059106628420" } }, "parameters": { @@ -18,7 +18,40 @@ }, "location": { "type": "string", - "defaultValue": "eastus2", + "defaultValue": "[resourceGroup().location]", + "allowedValues": [ + "australiaeast", + "brazilsouth", + "canadacentral", + "canadaeast", + "centralindia", + "centralus", + "eastasia", + "eastus", + "francecentral", + "germanywestcentral", + "italynorth", + "japaneast", + "koreacentral", + "northcentralus", + "northeurope", + "norwayeast", + "qatarcentral", + "southafricanorth", + "southcentralus", + "southindia", + "southeastasia", + "spaincentral", + "swedencentral", + "switzerlandnorth", + "uaenorth", + "uksouth", + "westeurope", + "westus", + "westus3", + "usgovarizona", + "usgovvirginia" + ], "metadata": { "description": "Location for all resources." } @@ -108,7 +141,7 @@ "type": "Microsoft.CognitiveServices/accounts", "apiVersion": "2025-06-01", "name": "[parameters('aiFoundryName')]", - "location": "[parameters('location')]", + "location": "[resourceGroup().location]", "identity": { "type": "UserAssigned", "userAssignedIdentities": { diff --git a/infrastructure/infrastructure-setup-bicep/25-entraid-passthrough/main.bicep b/infrastructure/infrastructure-setup-bicep/25-entraid-passthrough/main.bicep index 50e361e7b..b21423333 100644 --- a/infrastructure/infrastructure-setup-bicep/25-entraid-passthrough/main.bicep +++ b/infrastructure/infrastructure-setup-bicep/25-entraid-passthrough/main.bicep @@ -9,7 +9,40 @@ param aiFoundryName string = 'entraid-foundry' @description('Location for all resources.') -param location string = 'eastus' +@allowed([ + 'australiaeast' + 'brazilsouth' + 'canadacentral' + 'canadaeast' + 'centralindia' + 'centralus' + 'eastasia' + 'eastus' + 'francecentral' + 'germanywestcentral' + 'italynorth' + 'japaneast' + 'koreacentral' + 'northcentralus' + 'northeurope' + 'norwayeast' + 'qatarcentral' + 'southafricanorth' + 'southcentralus' + 'southindia' + 'southeastasia' + 'spaincentral' + 'swedencentral' + 'switzerlandnorth' + 'uaenorth' + 'uksouth' + 'westeurope' + 'westus' + 'westus3' + 'usgovarizona' + 'usgovvirginia' +]) +param location string = any(resourceGroup().location) @description('Name of the first project') param projectName string = '${aiFoundryName}-proj' diff --git a/infrastructure/infrastructure-setup-bicep/30-customer-managed-keys/azuredeploy.json b/infrastructure/infrastructure-setup-bicep/30-customer-managed-keys/azuredeploy.json index 64192cbd4..d83dccffd 100644 --- a/infrastructure/infrastructure-setup-bicep/30-customer-managed-keys/azuredeploy.json +++ b/infrastructure/infrastructure-setup-bicep/30-customer-managed-keys/azuredeploy.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.39.26.7824", - "templateHash": "16694821934772097765" + "templateHash": "16150214514525244564" } }, "parameters": { @@ -20,6 +20,39 @@ "location": { "type": "string", "defaultValue": "[resourceGroup().location]", + "allowedValues": [ + "australiaeast", + "brazilsouth", + "canadacentral", + "canadaeast", + "centralindia", + "centralus", + "eastasia", + "eastus", + "francecentral", + "germanywestcentral", + "italynorth", + "japaneast", + "koreacentral", + "northcentralus", + "northeurope", + "norwayeast", + "qatarcentral", + "southafricanorth", + "southcentralus", + "southindia", + "southeastasia", + "spaincentral", + "swedencentral", + "switzerlandnorth", + "uaenorth", + "uksouth", + "westeurope", + "westus", + "westus3", + "usgovarizona", + "usgovvirginia" + ], "metadata": { "description": "Location for all resources." } diff --git a/infrastructure/infrastructure-setup-bicep/30-customer-managed-keys/main.bicep b/infrastructure/infrastructure-setup-bicep/30-customer-managed-keys/main.bicep index 79ac47182..3fc44f8cf 100644 --- a/infrastructure/infrastructure-setup-bicep/30-customer-managed-keys/main.bicep +++ b/infrastructure/infrastructure-setup-bicep/30-customer-managed-keys/main.bicep @@ -17,7 +17,40 @@ param aiFoundryName string = 'foundry-cmk' param aiProjectName string = '${aiFoundryName}-proj' @description('Location for all resources.') -param location string = resourceGroup().location +@allowed([ + 'australiaeast' + 'brazilsouth' + 'canadacentral' + 'canadaeast' + 'centralindia' + 'centralus' + 'eastasia' + 'eastus' + 'francecentral' + 'germanywestcentral' + 'italynorth' + 'japaneast' + 'koreacentral' + 'northcentralus' + 'northeurope' + 'norwayeast' + 'qatarcentral' + 'southafricanorth' + 'southcentralus' + 'southindia' + 'southeastasia' + 'spaincentral' + 'swedencentral' + 'switzerlandnorth' + 'uaenorth' + 'uksouth' + 'westeurope' + 'westus' + 'westus3' + 'usgovarizona' + 'usgovvirginia' +]) +param location string = any(resourceGroup().location) @description('Name of the Azure Key Vault target') param keyVaultName string = 'foundry-int-cmk-akv' diff --git a/infrastructure/infrastructure-setup-bicep/31-customer-managed-keys-standard-agent/azuredeploy.json b/infrastructure/infrastructure-setup-bicep/31-customer-managed-keys-standard-agent/azuredeploy.json index 4b213588e..a21bf6f89 100644 --- a/infrastructure/infrastructure-setup-bicep/31-customer-managed-keys-standard-agent/azuredeploy.json +++ b/infrastructure/infrastructure-setup-bicep/31-customer-managed-keys-standard-agent/azuredeploy.json @@ -5,13 +5,46 @@ "_generator": { "name": "bicep", "version": "0.39.26.7824", - "templateHash": "6166861745321957187" + "templateHash": "6982876399509904179" } }, "parameters": { "location": { "type": "string", - "defaultValue": "eastus", + "defaultValue": "[resourceGroup().location]", + "allowedValues": [ + "australiaeast", + "brazilsouth", + "canadacentral", + "canadaeast", + "centralindia", + "centralus", + "eastasia", + "eastus", + "francecentral", + "germanywestcentral", + "italynorth", + "japaneast", + "koreacentral", + "northcentralus", + "northeurope", + "norwayeast", + "qatarcentral", + "southafricanorth", + "southcentralus", + "southindia", + "southeastasia", + "spaincentral", + "swedencentral", + "switzerlandnorth", + "uaenorth", + "uksouth", + "westeurope", + "westus", + "westus3", + "usgovarizona", + "usgovvirginia" + ], "metadata": { "description": "The region to deploy your AI Services resource and project" } @@ -547,7 +580,7 @@ "_generator": { "name": "bicep", "version": "0.39.26.7824", - "templateHash": "17728000413021798670" + "templateHash": "6321066101616137510" } }, "parameters": { diff --git a/infrastructure/infrastructure-setup-bicep/31-customer-managed-keys-standard-agent/main.bicep b/infrastructure/infrastructure-setup-bicep/31-customer-managed-keys-standard-agent/main.bicep index 9bfa9d05f..40063b65c 100644 --- a/infrastructure/infrastructure-setup-bicep/31-customer-managed-keys-standard-agent/main.bicep +++ b/infrastructure/infrastructure-setup-bicep/31-customer-managed-keys-standard-agent/main.bicep @@ -1,7 +1,40 @@ // Standard agent setup @description('The region to deploy your AI Services resource and project') -param location string = 'eastus' +@allowed([ + 'australiaeast' + 'brazilsouth' + 'canadacentral' + 'canadaeast' + 'centralindia' + 'centralus' + 'eastasia' + 'eastus' + 'francecentral' + 'germanywestcentral' + 'italynorth' + 'japaneast' + 'koreacentral' + 'northcentralus' + 'northeurope' + 'norwayeast' + 'qatarcentral' + 'southafricanorth' + 'southcentralus' + 'southindia' + 'southeastasia' + 'spaincentral' + 'swedencentral' + 'switzerlandnorth' + 'uaenorth' + 'uksouth' + 'westeurope' + 'westus' + 'westus3' + 'usgovarizona' + 'usgovvirginia' +]) +param location string = any(resourceGroup().location) @description('Name for your AI Services resource.') param aiFoundryName string = 'aifstdcmk4' diff --git a/infrastructure/infrastructure-setup-bicep/32-customer-managed-keys-user-assigned-identity/main.bicep b/infrastructure/infrastructure-setup-bicep/32-customer-managed-keys-user-assigned-identity/main.bicep index bba9bb54c..ff3142df1 100644 --- a/infrastructure/infrastructure-setup-bicep/32-customer-managed-keys-user-assigned-identity/main.bicep +++ b/infrastructure/infrastructure-setup-bicep/32-customer-managed-keys-user-assigned-identity/main.bicep @@ -14,7 +14,40 @@ param aiFoundryName string = 'ai-foundry-complete-cmk' param aiProjectName string = '${aiFoundryName}-proj' @description('Location for all resources.') -param location string = 'eastus2' +@allowed([ + 'australiaeast' + 'brazilsouth' + 'canadacentral' + 'canadaeast' + 'centralindia' + 'centralus' + 'eastasia' + 'eastus' + 'francecentral' + 'germanywestcentral' + 'italynorth' + 'japaneast' + 'koreacentral' + 'northcentralus' + 'northeurope' + 'norwayeast' + 'qatarcentral' + 'southafricanorth' + 'southcentralus' + 'southindia' + 'southeastasia' + 'spaincentral' + 'swedencentral' + 'switzerlandnorth' + 'uaenorth' + 'uksouth' + 'westeurope' + 'westus' + 'westus3' + 'usgovarizona' + 'usgovvirginia' +]) +param location string = any(resourceGroup().location) @description('Name of the Azure Key Vault target') param keyVaultName string diff --git a/infrastructure/infrastructure-setup-bicep/40-basic-agent-setup/azuredeploy.json b/infrastructure/infrastructure-setup-bicep/40-basic-agent-setup/azuredeploy.json index a163246f0..8c14d9fcf 100644 --- a/infrastructure/infrastructure-setup-bicep/40-basic-agent-setup/azuredeploy.json +++ b/infrastructure/infrastructure-setup-bicep/40-basic-agent-setup/azuredeploy.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.48.1.52935", - "templateHash": "12806942303218057804" + "templateHash": "2360111691865640081" } }, "parameters": { @@ -51,32 +51,39 @@ }, "location": { "type": "string", - "defaultValue": "eastus", + "defaultValue": "[resourceGroup().location]", "allowedValues": [ "australiaeast", + "brazilsouth", + "canadacentral", "canadaeast", + "centralindia", + "centralus", + "eastasia", "eastus", - "eastus2", "francecentral", + "germanywestcentral", + "italynorth", "japaneast", "koreacentral", + "northcentralus", + "northeurope", "norwayeast", - "polandcentral", + "qatarcentral", + "southafricanorth", + "southcentralus", "southindia", + "southeastasia", + "spaincentral", "swedencentral", "switzerlandnorth", "uaenorth", "uksouth", + "westeurope", "westus", - "westus2", "westus3", - "westeurope", - "southeastasia", - "brazilsouth", - "germanywestcentral", - "italynorth", - "southafricanorth", - "southcentralus" + "usgovarizona", + "usgovvirginia" ], "metadata": { "description": "The Azure region where your AI Foundry resource and project will be created." diff --git a/infrastructure/infrastructure-setup-bicep/40-basic-agent-setup/main.bicep b/infrastructure/infrastructure-setup-bicep/40-basic-agent-setup/main.bicep index 8b72573d9..b7ddb322c 100644 --- a/infrastructure/infrastructure-setup-bicep/40-basic-agent-setup/main.bicep +++ b/infrastructure/infrastructure-setup-bicep/40-basic-agent-setup/main.bicep @@ -23,34 +23,41 @@ param deployApplicationInsights bool = true var appInsightsName = toLower('${uniqueSuffix}appinsights') var logAnalyticsName = toLower('${uniqueSuffix}loganalytics') +@description('The Azure region where your AI Foundry resource and project will be created.') @allowed([ 'australiaeast' + 'brazilsouth' + 'canadacentral' 'canadaeast' + 'centralindia' + 'centralus' + 'eastasia' 'eastus' - 'eastus2' 'francecentral' + 'germanywestcentral' + 'italynorth' 'japaneast' 'koreacentral' + 'northcentralus' + 'northeurope' 'norwayeast' - 'polandcentral' + 'qatarcentral' + 'southafricanorth' + 'southcentralus' 'southindia' + 'southeastasia' + 'spaincentral' 'swedencentral' 'switzerlandnorth' 'uaenorth' 'uksouth' + 'westeurope' 'westus' - 'westus2' 'westus3' - 'westeurope' - 'southeastasia' - 'brazilsouth' - 'germanywestcentral' - 'italynorth' - 'southafricanorth' - 'southcentralus' + 'usgovarizona' + 'usgovvirginia' ]) -@description('The Azure region where your AI Foundry resource and project will be created.') -param location string = 'eastus' +param location string = any(resourceGroup().location) @description('The name of the OpenAI model you want to deploy') param modelName string = 'gpt-4.1' diff --git a/infrastructure/infrastructure-setup-bicep/41-standard-agent-setup/azuredeploy.json b/infrastructure/infrastructure-setup-bicep/41-standard-agent-setup/azuredeploy.json index ac3c75933..dcebcc6d5 100644 --- a/infrastructure/infrastructure-setup-bicep/41-standard-agent-setup/azuredeploy.json +++ b/infrastructure/infrastructure-setup-bicep/41-standard-agent-setup/azuredeploy.json @@ -5,38 +5,45 @@ "_generator": { "name": "bicep", "version": "0.44.1.10279", - "templateHash": "15348866302693417435" + "templateHash": "1696841767079201030" } }, "parameters": { "location": { "type": "string", - "defaultValue": "eastus", + "defaultValue": "[resourceGroup().location]", "allowedValues": [ "australiaeast", + "brazilsouth", + "canadacentral", "canadaeast", + "centralindia", + "centralus", + "eastasia", "eastus", - "eastus2", "francecentral", + "germanywestcentral", + "italynorth", "japaneast", "koreacentral", + "northcentralus", + "northeurope", "norwayeast", - "polandcentral", + "qatarcentral", + "southafricanorth", + "southcentralus", "southindia", + "southeastasia", + "spaincentral", "swedencentral", "switzerlandnorth", "uaenorth", "uksouth", + "westeurope", "westus", - "westus2", "westus3", - "westeurope", - "southeastasia", - "brazilsouth", - "germanywestcentral", - "italynorth", - "southafricanorth", - "southcentralus" + "usgovarizona", + "usgovvirginia" ], "metadata": { "description": "The Azure region where your AI Foundry resource and project will be created." diff --git a/infrastructure/infrastructure-setup-bicep/41-standard-agent-setup/main.bicep b/infrastructure/infrastructure-setup-bicep/41-standard-agent-setup/main.bicep index 94fe49ff6..89ef3898a 100644 --- a/infrastructure/infrastructure-setup-bicep/41-standard-agent-setup/main.bicep +++ b/infrastructure/infrastructure-setup-bicep/41-standard-agent-setup/main.bicep @@ -1,33 +1,40 @@ // Standard agent setup +@description('The Azure region where your AI Foundry resource and project will be created.') @allowed([ 'australiaeast' + 'brazilsouth' + 'canadacentral' 'canadaeast' + 'centralindia' + 'centralus' + 'eastasia' 'eastus' - 'eastus2' 'francecentral' + 'germanywestcentral' + 'italynorth' 'japaneast' 'koreacentral' + 'northcentralus' + 'northeurope' 'norwayeast' - 'polandcentral' + 'qatarcentral' + 'southafricanorth' + 'southcentralus' 'southindia' + 'southeastasia' + 'spaincentral' 'swedencentral' 'switzerlandnorth' 'uaenorth' 'uksouth' + 'westeurope' 'westus' - 'westus2' 'westus3' - 'westeurope' - 'southeastasia' - 'brazilsouth' - 'germanywestcentral' - 'italynorth' - 'southafricanorth' - 'southcentralus' + 'usgovarizona' + 'usgovvirginia' ]) -@description('The Azure region where your AI Foundry resource and project will be created.') -param location string = 'eastus' +param location string = any(resourceGroup().location) @maxLength(9) @description('The name of the Azure AI Foundry resource.') diff --git a/infrastructure/infrastructure-setup-bicep/42-basic-agent-setup-with-customization/azuredeploy.json b/infrastructure/infrastructure-setup-bicep/42-basic-agent-setup-with-customization/azuredeploy.json index 2f37922c0..d7032b140 100644 --- a/infrastructure/infrastructure-setup-bicep/42-basic-agent-setup-with-customization/azuredeploy.json +++ b/infrastructure/infrastructure-setup-bicep/42-basic-agent-setup-with-customization/azuredeploy.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.48.1.52935", - "templateHash": "7200235384495896128" + "templateHash": "6849510010229597027" } }, "parameters": { @@ -52,32 +52,39 @@ }, "location": { "type": "string", - "defaultValue": "eastus", + "defaultValue": "[resourceGroup().location]", "allowedValues": [ "australiaeast", + "brazilsouth", + "canadacentral", "canadaeast", + "centralindia", + "centralus", + "eastasia", "eastus", - "eastus2", "francecentral", + "germanywestcentral", + "italynorth", "japaneast", "koreacentral", + "northcentralus", + "northeurope", "norwayeast", - "polandcentral", + "qatarcentral", + "southafricanorth", + "southcentralus", "southindia", + "southeastasia", + "spaincentral", "swedencentral", "switzerlandnorth", "uaenorth", "uksouth", + "westeurope", "westus", - "westus2", "westus3", - "westeurope", - "southeastasia", - "brazilsouth", - "germanywestcentral", - "italynorth", - "southafricanorth", - "southcentralus" + "usgovarizona", + "usgovvirginia" ], "metadata": { "description": "The Azure region where your AI Foundry resource and project will be created." diff --git a/infrastructure/infrastructure-setup-bicep/42-basic-agent-setup-with-customization/main.bicep b/infrastructure/infrastructure-setup-bicep/42-basic-agent-setup-with-customization/main.bicep index d6d8ce7a4..31e908477 100644 --- a/infrastructure/infrastructure-setup-bicep/42-basic-agent-setup-with-customization/main.bicep +++ b/infrastructure/infrastructure-setup-bicep/42-basic-agent-setup-with-customization/main.bicep @@ -22,34 +22,41 @@ param projectDescription string = 'some description' @description('The display name of your project') param projectDisplayName string = 'project_display_name' +@description('The Azure region where your AI Foundry resource and project will be created.') @allowed([ 'australiaeast' + 'brazilsouth' + 'canadacentral' 'canadaeast' + 'centralindia' + 'centralus' + 'eastasia' 'eastus' - 'eastus2' 'francecentral' + 'germanywestcentral' + 'italynorth' 'japaneast' 'koreacentral' + 'northcentralus' + 'northeurope' 'norwayeast' - 'polandcentral' + 'qatarcentral' + 'southafricanorth' + 'southcentralus' 'southindia' + 'southeastasia' + 'spaincentral' 'swedencentral' 'switzerlandnorth' 'uaenorth' 'uksouth' + 'westeurope' 'westus' - 'westus2' 'westus3' - 'westeurope' - 'southeastasia' - 'brazilsouth' - 'germanywestcentral' - 'italynorth' - 'southafricanorth' - 'southcentralus' + 'usgovarizona' + 'usgovvirginia' ]) -@description('The Azure region where your AI Foundry resource and project will be created.') -param location string = 'eastus' +param location string = any(resourceGroup().location) // TO DO: Update the resource ID to point to an existing Azure OpenAI resource in your subscription @description('The resource ID of the existing Azure OpenAI resource.') diff --git a/infrastructure/infrastructure-setup-bicep/43-standard-agent-setup-with-customization/azuredeploy.json b/infrastructure/infrastructure-setup-bicep/43-standard-agent-setup-with-customization/azuredeploy.json index 4c1b1ae56..aeed1a480 100644 --- a/infrastructure/infrastructure-setup-bicep/43-standard-agent-setup-with-customization/azuredeploy.json +++ b/infrastructure/infrastructure-setup-bicep/43-standard-agent-setup-with-customization/azuredeploy.json @@ -5,38 +5,45 @@ "_generator": { "name": "bicep", "version": "0.44.1.10279", - "templateHash": "11935496515310596833" + "templateHash": "16745698417344261316" } }, "parameters": { "location": { "type": "string", - "defaultValue": "eastus", + "defaultValue": "[resourceGroup().location]", "allowedValues": [ "australiaeast", + "brazilsouth", + "canadacentral", "canadaeast", + "centralindia", + "centralus", + "eastasia", "eastus", - "eastus2", "francecentral", + "germanywestcentral", + "italynorth", "japaneast", "koreacentral", + "northcentralus", + "northeurope", "norwayeast", - "polandcentral", + "qatarcentral", + "southafricanorth", + "southcentralus", "southindia", + "southeastasia", + "spaincentral", "swedencentral", "switzerlandnorth", "uaenorth", "uksouth", + "westeurope", "westus", - "westus2", "westus3", - "westeurope", - "southeastasia", - "brazilsouth", - "germanywestcentral", - "italynorth", - "southafricanorth", - "southcentralus" + "usgovarizona", + "usgovvirginia" ], "metadata": { "description": "The Azure region where your AI Foundry resource and project will be created." diff --git a/infrastructure/infrastructure-setup-bicep/43-standard-agent-setup-with-customization/main.bicep b/infrastructure/infrastructure-setup-bicep/43-standard-agent-setup-with-customization/main.bicep index 9ab625da3..4c21361cf 100644 --- a/infrastructure/infrastructure-setup-bicep/43-standard-agent-setup-with-customization/main.bicep +++ b/infrastructure/infrastructure-setup-bicep/43-standard-agent-setup-with-customization/main.bicep @@ -1,33 +1,40 @@ // Standard agent setup with customization +@description('The Azure region where your AI Foundry resource and project will be created.') @allowed([ 'australiaeast' + 'brazilsouth' + 'canadacentral' 'canadaeast' + 'centralindia' + 'centralus' + 'eastasia' 'eastus' - 'eastus2' 'francecentral' + 'germanywestcentral' + 'italynorth' 'japaneast' 'koreacentral' + 'northcentralus' + 'northeurope' 'norwayeast' - 'polandcentral' + 'qatarcentral' + 'southafricanorth' + 'southcentralus' 'southindia' + 'southeastasia' + 'spaincentral' 'swedencentral' 'switzerlandnorth' 'uaenorth' 'uksouth' + 'westeurope' 'westus' - 'westus2' 'westus3' - 'westeurope' - 'southeastasia' - 'brazilsouth' - 'germanywestcentral' - 'italynorth' - 'southafricanorth' - 'southcentralus' + 'usgovarizona' + 'usgovvirginia' ]) -@description('The Azure region where your AI Foundry resource and project will be created.') -param location string = 'eastus' +param location string = any(resourceGroup().location) @maxLength(9) @description('The name of the Azure AI Foundry resource.') diff --git a/infrastructure/infrastructure-setup-bicep/45-basic-agent-bing/azuredeploy.json b/infrastructure/infrastructure-setup-bicep/45-basic-agent-bing/azuredeploy.json index c6b568e62..44009a3a5 100644 --- a/infrastructure/infrastructure-setup-bicep/45-basic-agent-bing/azuredeploy.json +++ b/infrastructure/infrastructure-setup-bicep/45-basic-agent-bing/azuredeploy.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.48.1.52935", - "templateHash": "14639074611483032693" + "templateHash": "6417948001258618961" } }, "parameters": { @@ -27,7 +27,40 @@ }, "location": { "type": "string", - "defaultValue": "eastus" + "defaultValue": "[resourceGroup().location]", + "allowedValues": [ + "australiaeast", + "brazilsouth", + "canadacentral", + "canadaeast", + "centralindia", + "centralus", + "eastasia", + "eastus", + "francecentral", + "germanywestcentral", + "italynorth", + "japaneast", + "koreacentral", + "northcentralus", + "northeurope", + "norwayeast", + "qatarcentral", + "southafricanorth", + "southcentralus", + "southindia", + "southeastasia", + "spaincentral", + "swedencentral", + "switzerlandnorth", + "uaenorth", + "uksouth", + "westeurope", + "westus", + "westus3", + "usgovarizona", + "usgovvirginia" + ] }, "modelName": { "type": "string", diff --git a/infrastructure/infrastructure-setup-bicep/45-basic-agent-bing/main.bicep b/infrastructure/infrastructure-setup-bicep/45-basic-agent-bing/main.bicep index 51997c1fb..edab8f4fa 100644 --- a/infrastructure/infrastructure-setup-bicep/45-basic-agent-bing/main.bicep +++ b/infrastructure/infrastructure-setup-bicep/45-basic-agent-bing/main.bicep @@ -2,7 +2,40 @@ param ai_services string = 'aiServices' param project_name string = 'project' param description string = 'some description' param display_name string = 'project_display_name' -param location string = 'eastus' +@allowed([ + 'australiaeast' + 'brazilsouth' + 'canadacentral' + 'canadaeast' + 'centralindia' + 'centralus' + 'eastasia' + 'eastus' + 'francecentral' + 'germanywestcentral' + 'italynorth' + 'japaneast' + 'koreacentral' + 'northcentralus' + 'northeurope' + 'norwayeast' + 'qatarcentral' + 'southafricanorth' + 'southcentralus' + 'southindia' + 'southeastasia' + 'spaincentral' + 'swedencentral' + 'switzerlandnorth' + 'uaenorth' + 'uksouth' + 'westeurope' + 'westus' + 'westus3' + 'usgovarizona' + 'usgovvirginia' +]) +param location string = any(resourceGroup().location) param modelName string = 'gpt-4.1' param modelFormat string = 'OpenAI' diff --git a/infrastructure/infrastructure-setup-bicep/48-bring-own-model-private-ca/azuredeploy.json b/infrastructure/infrastructure-setup-bicep/48-bring-own-model-private-ca/azuredeploy.json index f60721594..929c194a7 100644 --- a/infrastructure/infrastructure-setup-bicep/48-bring-own-model-private-ca/azuredeploy.json +++ b/infrastructure/infrastructure-setup-bicep/48-bring-own-model-private-ca/azuredeploy.json @@ -5,13 +5,47 @@ "_generator": { "name": "bicep", "version": "0.48.1.52935", - "templateHash": "15571043127430806677" + "templateHash": "2730794585217518261" } }, "parameters": { "location": { "type": "string", "defaultValue": "[resourceGroup().location]", + "allowedValues": [ + "australiaeast", + "brazilsouth", + "canadacentral", + "canadaeast", + "centralindia", + "centralus", + "eastasia", + "eastus", + "eastus2", + "francecentral", + "germanywestcentral", + "italynorth", + "japaneast", + "koreacentral", + "northcentralus", + "northeurope", + "norwayeast", + "qatarcentral", + "southafricanorth", + "southcentralus", + "southindia", + "southeastasia", + "spaincentral", + "swedencentral", + "switzerlandnorth", + "uaenorth", + "uksouth", + "westeurope", + "westus", + "westus3", + "usgovarizona", + "usgovvirginia" + ], "metadata": { "description": "Azure region for all resources." } @@ -200,7 +234,7 @@ "roleSearchIndexDataContributor": "8ebe5a00-799e-43f5-93ac-243d3dce84a7", "roleSearchServiceContributor": "7ca78c08-252a-4471-8644-bb5ff32d4ba0", "cosmosBuiltInDataContributorRoleId": "00000000-0000-0000-0000-000000000002", - "nginxConfTemplate": "worker_processes 1;\r\nerror_log /dev/stderr warn;\r\npid /tmp/nginx.pid;\r\nevents { worker_connections 1024; }\r\nhttp {\r\n include /etc/nginx/mime.types;\r\n default_type application/octet-stream;\r\n access_log /dev/stdout;\r\n proxy_http_version 1.1;\r\n server {\r\n listen 443 ssl;\r\n server_name __FQDN__;\r\n ssl_certificate /mnt/certs/server.crt;\r\n ssl_certificate_key /mnt/certs/server.key;\r\n location /__APIPATH__/ {\r\n proxy_pass https://__MODELHOST__/openai/;\r\n proxy_set_header Host __MODELHOST__;\r\n proxy_ssl_server_name on;\r\n proxy_ssl_name __MODELHOST__;\r\n proxy_ssl_verify on;\r\n proxy_ssl_verify_depth 3;\r\n proxy_ssl_trusted_certificate /etc/pki/tls/certs/ca-bundle.crt;\r\n }\r\n location / { return 200 'gateway-ok'; }\r\n }\r\n}\r\n", + "nginxConfTemplate": "worker_processes 1;\nerror_log /dev/stderr warn;\npid /tmp/nginx.pid;\nevents { worker_connections 1024; }\nhttp {\n include /etc/nginx/mime.types;\n default_type application/octet-stream;\n access_log /dev/stdout;\n proxy_http_version 1.1;\n server {\n listen 443 ssl;\n server_name __FQDN__;\n ssl_certificate /mnt/certs/server.crt;\n ssl_certificate_key /mnt/certs/server.key;\n location /__APIPATH__/ {\n proxy_pass https://__MODELHOST__/openai/;\n proxy_set_header Host __MODELHOST__;\n proxy_ssl_server_name on;\n proxy_ssl_name __MODELHOST__;\n proxy_ssl_verify on;\n proxy_ssl_verify_depth 3;\n proxy_ssl_trusted_certificate /etc/pki/tls/certs/ca-bundle.crt;\n }\n location / { return 200 'gateway-ok'; }\n }\n}\n", "nginxConf": "[replace(replace(replace(variables('nginxConfTemplate'), '__FQDN__', variables('customDomainFqdn')), '__APIPATH__', variables('apimApiPath')), '__MODELHOST__', variables('modelHost'))]", "agentAccountBaseProperties": { "allowProjectManagement": true, diff --git a/infrastructure/infrastructure-setup-bicep/48-bring-own-model-private-ca/main.bicep b/infrastructure/infrastructure-setup-bicep/48-bring-own-model-private-ca/main.bicep index f72067f27..b43d52196 100644 --- a/infrastructure/infrastructure-setup-bicep/48-bring-own-model-private-ca/main.bicep +++ b/infrastructure/infrastructure-setup-bicep/48-bring-own-model-private-ca/main.bicep @@ -27,7 +27,41 @@ targetScope = 'resourceGroup' // Parameters // ---------------------------------------------------------------------------- @description('Azure region for all resources.') -param location string = resourceGroup().location +@allowed([ + 'australiaeast' + 'brazilsouth' + 'canadacentral' + 'canadaeast' + 'centralindia' + 'centralus' + 'eastasia' + 'eastus' + 'eastus2' + 'francecentral' + 'germanywestcentral' + 'italynorth' + 'japaneast' + 'koreacentral' + 'northcentralus' + 'northeurope' + 'norwayeast' + 'qatarcentral' + 'southafricanorth' + 'southcentralus' + 'southindia' + 'southeastasia' + 'spaincentral' + 'swedencentral' + 'switzerlandnorth' + 'uaenorth' + 'uksouth' + 'westeurope' + 'westus' + 'westus3' + 'usgovarizona' + 'usgovvirginia' +]) +param location string = any(resourceGroup().location) @description('Region for the Cosmos DB account only. Defaults to location; override (e.g. eastus2) when the main region lacks Cosmos capacity. The Cosmos private endpoint still lands in the spoke VNet in location.') param cosmosLocation string = location diff --git a/infrastructure/infrastructure-setup-bicep/48-bring-own-model-private-ca/main.json b/infrastructure/infrastructure-setup-bicep/48-bring-own-model-private-ca/main.json index f60721594..929c194a7 100644 --- a/infrastructure/infrastructure-setup-bicep/48-bring-own-model-private-ca/main.json +++ b/infrastructure/infrastructure-setup-bicep/48-bring-own-model-private-ca/main.json @@ -5,13 +5,47 @@ "_generator": { "name": "bicep", "version": "0.48.1.52935", - "templateHash": "15571043127430806677" + "templateHash": "2730794585217518261" } }, "parameters": { "location": { "type": "string", "defaultValue": "[resourceGroup().location]", + "allowedValues": [ + "australiaeast", + "brazilsouth", + "canadacentral", + "canadaeast", + "centralindia", + "centralus", + "eastasia", + "eastus", + "eastus2", + "francecentral", + "germanywestcentral", + "italynorth", + "japaneast", + "koreacentral", + "northcentralus", + "northeurope", + "norwayeast", + "qatarcentral", + "southafricanorth", + "southcentralus", + "southindia", + "southeastasia", + "spaincentral", + "swedencentral", + "switzerlandnorth", + "uaenorth", + "uksouth", + "westeurope", + "westus", + "westus3", + "usgovarizona", + "usgovvirginia" + ], "metadata": { "description": "Azure region for all resources." } @@ -200,7 +234,7 @@ "roleSearchIndexDataContributor": "8ebe5a00-799e-43f5-93ac-243d3dce84a7", "roleSearchServiceContributor": "7ca78c08-252a-4471-8644-bb5ff32d4ba0", "cosmosBuiltInDataContributorRoleId": "00000000-0000-0000-0000-000000000002", - "nginxConfTemplate": "worker_processes 1;\r\nerror_log /dev/stderr warn;\r\npid /tmp/nginx.pid;\r\nevents { worker_connections 1024; }\r\nhttp {\r\n include /etc/nginx/mime.types;\r\n default_type application/octet-stream;\r\n access_log /dev/stdout;\r\n proxy_http_version 1.1;\r\n server {\r\n listen 443 ssl;\r\n server_name __FQDN__;\r\n ssl_certificate /mnt/certs/server.crt;\r\n ssl_certificate_key /mnt/certs/server.key;\r\n location /__APIPATH__/ {\r\n proxy_pass https://__MODELHOST__/openai/;\r\n proxy_set_header Host __MODELHOST__;\r\n proxy_ssl_server_name on;\r\n proxy_ssl_name __MODELHOST__;\r\n proxy_ssl_verify on;\r\n proxy_ssl_verify_depth 3;\r\n proxy_ssl_trusted_certificate /etc/pki/tls/certs/ca-bundle.crt;\r\n }\r\n location / { return 200 'gateway-ok'; }\r\n }\r\n}\r\n", + "nginxConfTemplate": "worker_processes 1;\nerror_log /dev/stderr warn;\npid /tmp/nginx.pid;\nevents { worker_connections 1024; }\nhttp {\n include /etc/nginx/mime.types;\n default_type application/octet-stream;\n access_log /dev/stdout;\n proxy_http_version 1.1;\n server {\n listen 443 ssl;\n server_name __FQDN__;\n ssl_certificate /mnt/certs/server.crt;\n ssl_certificate_key /mnt/certs/server.key;\n location /__APIPATH__/ {\n proxy_pass https://__MODELHOST__/openai/;\n proxy_set_header Host __MODELHOST__;\n proxy_ssl_server_name on;\n proxy_ssl_name __MODELHOST__;\n proxy_ssl_verify on;\n proxy_ssl_verify_depth 3;\n proxy_ssl_trusted_certificate /etc/pki/tls/certs/ca-bundle.crt;\n }\n location / { return 200 'gateway-ok'; }\n }\n}\n", "nginxConf": "[replace(replace(replace(variables('nginxConfTemplate'), '__FQDN__', variables('customDomainFqdn')), '__APIPATH__', variables('apimApiPath')), '__MODELHOST__', variables('modelHost'))]", "agentAccountBaseProperties": { "allowProjectManagement": true, diff --git a/infrastructure/infrastructure-setup-terraform/00-basic-azurerm/code/example.tfvars b/infrastructure/infrastructure-setup-terraform/00-basic-azurerm/code/example.tfvars index ca03533e2..cdfa09c19 100644 --- a/infrastructure/infrastructure-setup-terraform/00-basic-azurerm/code/example.tfvars +++ b/infrastructure/infrastructure-setup-terraform/00-basic-azurerm/code/example.tfvars @@ -1 +1 @@ -location = "eastus2" +location = "eastus" diff --git a/infrastructure/infrastructure-setup-terraform/00-basic-azurerm/code/main.tf b/infrastructure/infrastructure-setup-terraform/00-basic-azurerm/code/main.tf index d57a82893..82ae9cee4 100644 --- a/infrastructure/infrastructure-setup-terraform/00-basic-azurerm/code/main.tf +++ b/infrastructure/infrastructure-setup-terraform/00-basic-azurerm/code/main.tf @@ -21,7 +21,7 @@ resource "azurerm_resource_group" "rg" { resource "azurerm_cognitive_account" "ai_foundry" { name = "aifoundry${random_string.unique.result}" - location = var.location + location = coalesce(var.foundry_location, azurerm_resource_group.rg.location) resource_group_name = azurerm_resource_group.rg.name kind = "AIServices" @@ -32,7 +32,7 @@ resource "azurerm_cognitive_account" "ai_foundry" { sku_name = "S0" # required for stateful development in Foundry including agent service - custom_subdomain_name = "aifoundry${random_string.unique.result}" + custom_subdomain_name = "aifoundry${random_string.unique.result}" project_management_enabled = true tags = { @@ -44,7 +44,7 @@ resource "azurerm_cognitive_account" "ai_foundry" { resource "azurerm_cognitive_account_project" "example" { name = "myproject" cognitive_account_id = azurerm_cognitive_account.ai_foundry.id - location = azurerm_resource_group.rg.location + location = azurerm_cognitive_account.ai_foundry.location identity { type = "SystemAssigned" diff --git a/infrastructure/infrastructure-setup-terraform/00-basic-azurerm/code/variables.tf b/infrastructure/infrastructure-setup-terraform/00-basic-azurerm/code/variables.tf index 76351d2b4..1779c54a1 100644 --- a/infrastructure/infrastructure-setup-terraform/00-basic-azurerm/code/variables.tf +++ b/infrastructure/infrastructure-setup-terraform/00-basic-azurerm/code/variables.tf @@ -1,6 +1,60 @@ variable "location" { description = "The name of the location to provision the resources to" type = string + + validation { + condition = contains([ + "australiaeast", + "brazilsouth", + "canadacentral", + "canadaeast", + "centralindia", + "centralus", + "eastasia", + "eastus", + "francecentral", + "germanywestcentral", + "italynorth", + "japaneast", + "koreacentral", + "northcentralus", + "northeurope", + "norwayeast", + "qatarcentral", + "southafricanorth", + "southcentralus", + "southindia", + "southeastasia", + "spaincentral", + "swedencentral", + "switzerlandnorth", + "uaenorth", + "uksouth", + "usgovarizona", + "usgovvirginia", + "westeurope", + "westus", + "westus3", + ], var.location) + error_message = "The location must be a supported Microsoft Foundry region." + } +} + +variable "foundry_location" { + description = "Optional Foundry account location override. Defaults to the resource-group location." + type = string + default = null + + validation { + condition = var.foundry_location == null ? true : contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.foundry_location) + error_message = "The location must be a supported Microsoft Foundry region." + } } variable "subscription_id" { diff --git a/infrastructure/infrastructure-setup-terraform/00-basic/code/example.tfvars b/infrastructure/infrastructure-setup-terraform/00-basic/code/example.tfvars index ca03533e2..d39ef7c14 100644 --- a/infrastructure/infrastructure-setup-terraform/00-basic/code/example.tfvars +++ b/infrastructure/infrastructure-setup-terraform/00-basic/code/example.tfvars @@ -1 +1,3 @@ -location = "eastus2" +location = "eastus" +# Optional Foundry account region override; defaults to the resource-group location. +# foundry_location = "westus3" diff --git a/infrastructure/infrastructure-setup-terraform/00-basic/code/main.tf b/infrastructure/infrastructure-setup-terraform/00-basic/code/main.tf index 506919916..dfefe2947 100644 --- a/infrastructure/infrastructure-setup-terraform/00-basic/code/main.tf +++ b/infrastructure/infrastructure-setup-terraform/00-basic/code/main.tf @@ -12,9 +12,9 @@ resource "random_string" "unique" { ## Create a resource group for the resources to be stored in ## resource "azapi_resource" "rg" { - type = "Microsoft.Resources/resourceGroups@2021-04-01" - name = "tf-319-basic" - location = var.location + type = "Microsoft.Resources/resourceGroups@2021-04-01" + name = "tf-319-basic" + location = var.location } ########## Create AI Foundry resource @@ -26,7 +26,7 @@ resource "azapi_resource" "ai_foundry" { type = "Microsoft.CognitiveServices/accounts@2025-06-01" name = "aifoundry${random_string.unique.result}" parent_id = azapi_resource.rg.id - location = var.location + location = coalesce(var.foundry_location, azapi_resource.rg.location) schema_validation_enabled = false body = { @@ -82,7 +82,7 @@ resource "azapi_resource" "ai_foundry_project" { type = "Microsoft.CognitiveServices/accounts/projects@2025-06-01" name = "project${random_string.unique.result}" parent_id = azapi_resource.ai_foundry.id - location = var.location + location = azapi_resource.ai_foundry.location schema_validation_enabled = false body = { diff --git a/infrastructure/infrastructure-setup-terraform/00-basic/code/variables.tf b/infrastructure/infrastructure-setup-terraform/00-basic/code/variables.tf index 76351d2b4..089b7c9e4 100644 --- a/infrastructure/infrastructure-setup-terraform/00-basic/code/variables.tf +++ b/infrastructure/infrastructure-setup-terraform/00-basic/code/variables.tf @@ -1,8 +1,62 @@ variable "location" { description = "The name of the location to provision the resources to" type = string + + validation { + condition = contains([ + "australiaeast", + "brazilsouth", + "canadacentral", + "canadaeast", + "centralindia", + "centralus", + "eastasia", + "eastus", + "francecentral", + "germanywestcentral", + "italynorth", + "japaneast", + "koreacentral", + "northcentralus", + "northeurope", + "norwayeast", + "qatarcentral", + "southafricanorth", + "southcentralus", + "southindia", + "southeastasia", + "spaincentral", + "swedencentral", + "switzerlandnorth", + "uaenorth", + "uksouth", + "usgovarizona", + "usgovvirginia", + "westeurope", + "westus", + "westus3", + ], var.location) + error_message = "The location must be a supported Microsoft Foundry region." + } } variable "subscription_id" { type = string +} + +variable "foundry_location" { + description = "Optional Foundry account location override. Defaults to the resource-group location." + type = string + default = null + + validation { + condition = var.foundry_location == null ? true : contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.foundry_location) + error_message = "The location must be a supported Microsoft Foundry region." + } } \ No newline at end of file diff --git a/infrastructure/infrastructure-setup-terraform/02-storage-speech-language/README.md b/infrastructure/infrastructure-setup-terraform/02-storage-speech-language/README.md index cdcadd167..597a0572f 100644 --- a/infrastructure/infrastructure-setup-terraform/02-storage-speech-language/README.md +++ b/infrastructure/infrastructure-setup-terraform/02-storage-speech-language/README.md @@ -24,6 +24,7 @@ These examples can be adapted and integrated into your Terraform configurations. This folder now includes a full Terraform sample with: - Microsoft Foundry account configured for user-owned storage +- Microsoft Foundry project under the account - Optional Speech and Language resource deployment switches - Storage RBAC wiring for the account identity diff --git a/infrastructure/infrastructure-setup-terraform/02-storage-speech-language/code/example.tfvars b/infrastructure/infrastructure-setup-terraform/02-storage-speech-language/code/example.tfvars index aa897f13b..7be13366b 100644 --- a/infrastructure/infrastructure-setup-terraform/02-storage-speech-language/code/example.tfvars +++ b/infrastructure/infrastructure-setup-terraform/02-storage-speech-language/code/example.tfvars @@ -1,7 +1,7 @@ # Example configuration for storage-speech-language # Azure region -location = "eastus2" +location = "eastus" # AI Foundry account name ai_foundry_name = "foundry-storage" diff --git a/infrastructure/infrastructure-setup-terraform/02-storage-speech-language/code/main.tf b/infrastructure/infrastructure-setup-terraform/02-storage-speech-language/code/main.tf index 6148db9f2..247657ae3 100644 --- a/infrastructure/infrastructure-setup-terraform/02-storage-speech-language/code/main.tf +++ b/infrastructure/infrastructure-setup-terraform/02-storage-speech-language/code/main.tf @@ -63,7 +63,7 @@ locals { resource "azapi_resource" "ai_foundry" { type = "Microsoft.CognitiveServices/accounts@2025-06-01" name = var.ai_foundry_name - location = var.location + location = coalesce(var.foundry_location, azurerm_resource_group.rg.location) parent_id = azurerm_resource_group.rg.id identity { @@ -89,6 +89,24 @@ resource "azapi_resource" "ai_foundry" { } } +resource "azapi_resource" "ai_foundry_project" { + type = "Microsoft.CognitiveServices/accounts/projects@2025-06-01" + name = "${var.ai_foundry_name}-proj" + parent_id = azapi_resource.ai_foundry.id + location = coalesce(var.foundry_location, azurerm_resource_group.rg.location) + schema_validation_enabled = false + + identity { + type = "SystemAssigned" + } + + body = { + properties = {} + } + + depends_on = [time_sleep.wait_for_ai_foundry] +} + ## Wait for AI Foundry creation to ensure identity is available resource "time_sleep" "wait_for_ai_foundry" { depends_on = [azapi_resource.ai_foundry] diff --git a/infrastructure/infrastructure-setup-terraform/02-storage-speech-language/code/variables.tf b/infrastructure/infrastructure-setup-terraform/02-storage-speech-language/code/variables.tf index da19b5f10..a2f6e9814 100644 --- a/infrastructure/infrastructure-setup-terraform/02-storage-speech-language/code/variables.tf +++ b/infrastructure/infrastructure-setup-terraform/02-storage-speech-language/code/variables.tf @@ -1,7 +1,35 @@ +variable "foundry_location" { + description = "Optional Foundry account location override. Defaults to the resource-group location." + type = string + default = null + + validation { + condition = var.foundry_location == null ? true : contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.foundry_location) + error_message = "The location must be a supported Microsoft Foundry region." + } +} + variable "location" { description = "The Azure region where resources will be deployed" type = string - default = "eastus2" + default = "eastus" + + validation { + condition = contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.location) + error_message = "The location must be a supported Microsoft Foundry region." + } } variable "ai_foundry_name" { diff --git a/infrastructure/infrastructure-setup-terraform/03-custom-dns/code/example.tfvars b/infrastructure/infrastructure-setup-terraform/03-custom-dns/code/example.tfvars index 810dda390..77072918a 100644 --- a/infrastructure/infrastructure-setup-terraform/03-custom-dns/code/example.tfvars +++ b/infrastructure/infrastructure-setup-terraform/03-custom-dns/code/example.tfvars @@ -1,7 +1,7 @@ # Example terraform.tfvars file # Copy this to terraform.tfvars and customize for your deployment -location = "eastus2" +location = "eastus" custom_subdomain_name = "my-unique-foundry-dns" # Must be globally unique ai_project_name = "custom-dns-proj" model_name = "gpt-4.1-mini" diff --git a/infrastructure/infrastructure-setup-terraform/03-custom-dns/code/main.tf b/infrastructure/infrastructure-setup-terraform/03-custom-dns/code/main.tf index 49a4e5c42..f7c14c66f 100644 --- a/infrastructure/infrastructure-setup-terraform/03-custom-dns/code/main.tf +++ b/infrastructure/infrastructure-setup-terraform/03-custom-dns/code/main.tf @@ -24,7 +24,7 @@ resource "azurerm_resource_group" "rg" { resource "azapi_resource" "ai_foundry" { type = "Microsoft.CognitiveServices/accounts@2025-06-01" name = var.custom_subdomain_name - location = var.location + location = coalesce(var.foundry_location, azurerm_resource_group.rg.location) parent_id = azurerm_resource_group.rg.id identity { @@ -49,7 +49,7 @@ resource "azapi_resource" "ai_foundry" { resource "azapi_resource" "ai_project" { type = "Microsoft.CognitiveServices/accounts/projects@2025-06-01" name = var.ai_project_name - location = var.location + location = azapi_resource.ai_foundry.location parent_id = azapi_resource.ai_foundry.id identity { diff --git a/infrastructure/infrastructure-setup-terraform/03-custom-dns/code/variables.tf b/infrastructure/infrastructure-setup-terraform/03-custom-dns/code/variables.tf index e26291d06..9885415fd 100644 --- a/infrastructure/infrastructure-setup-terraform/03-custom-dns/code/variables.tf +++ b/infrastructure/infrastructure-setup-terraform/03-custom-dns/code/variables.tf @@ -1,7 +1,35 @@ +variable "foundry_location" { + description = "Optional Foundry account location override. Defaults to the resource-group location." + type = string + default = null + + validation { + condition = var.foundry_location == null ? true : contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.foundry_location) + error_message = "The location must be a supported Microsoft Foundry region." + } +} + variable "location" { description = "The Azure region where resources will be deployed" type = string - default = "eastus2" + default = "eastus" + + validation { + condition = contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.location) + error_message = "The location must be a supported Microsoft Foundry region." + } } variable "custom_subdomain_name" { diff --git a/infrastructure/infrastructure-setup-terraform/04-disable-local-auth/code/example.tfvars b/infrastructure/infrastructure-setup-terraform/04-disable-local-auth/code/example.tfvars index dddc42eb1..a8294fd67 100644 --- a/infrastructure/infrastructure-setup-terraform/04-disable-local-auth/code/example.tfvars +++ b/infrastructure/infrastructure-setup-terraform/04-disable-local-auth/code/example.tfvars @@ -1,7 +1,7 @@ # Example terraform.tfvars file # Copy this to terraform.tfvars and customize for your deployment -location = "eastus2" +location = "eastus" ai_foundry_name = "foundry-disable-localauth" ai_project_name = "foundry-disable-localauth-proj" model_name = "gpt-4.1-mini" diff --git a/infrastructure/infrastructure-setup-terraform/04-disable-local-auth/code/main.tf b/infrastructure/infrastructure-setup-terraform/04-disable-local-auth/code/main.tf index 61d37fa4e..ad8e15ab3 100644 --- a/infrastructure/infrastructure-setup-terraform/04-disable-local-auth/code/main.tf +++ b/infrastructure/infrastructure-setup-terraform/04-disable-local-auth/code/main.tf @@ -24,7 +24,7 @@ resource "azurerm_resource_group" "rg" { resource "azapi_resource" "ai_foundry" { type = "Microsoft.CognitiveServices/accounts@2025-06-01" name = var.ai_foundry_name - location = var.location + location = coalesce(var.foundry_location, azurerm_resource_group.rg.location) parent_id = azurerm_resource_group.rg.id identity { @@ -49,7 +49,7 @@ resource "azapi_resource" "ai_foundry" { resource "azapi_resource" "ai_project" { type = "Microsoft.CognitiveServices/accounts/projects@2025-06-01" name = coalesce(var.ai_project_name, "${var.ai_foundry_name}-proj") - location = var.location + location = azapi_resource.ai_foundry.location parent_id = azapi_resource.ai_foundry.id identity { diff --git a/infrastructure/infrastructure-setup-terraform/04-disable-local-auth/code/variables.tf b/infrastructure/infrastructure-setup-terraform/04-disable-local-auth/code/variables.tf index 4a14bbc37..f73c6d339 100644 --- a/infrastructure/infrastructure-setup-terraform/04-disable-local-auth/code/variables.tf +++ b/infrastructure/infrastructure-setup-terraform/04-disable-local-auth/code/variables.tf @@ -1,7 +1,35 @@ +variable "foundry_location" { + description = "Optional Foundry account location override. Defaults to the resource-group location." + type = string + default = null + + validation { + condition = var.foundry_location == null ? true : contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.foundry_location) + error_message = "The location must be a supported Microsoft Foundry region." + } +} + variable "location" { description = "The Azure region where resources will be deployed" type = string - default = "eastus2" + default = "eastus" + + validation { + condition = contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.location) + error_message = "The location must be a supported Microsoft Foundry region." + } } variable "ai_foundry_name" { diff --git a/infrastructure/infrastructure-setup-terraform/10-private-network-basic/code/example.tfvars b/infrastructure/infrastructure-setup-terraform/10-private-network-basic/code/example.tfvars index d6c2f233a..af38fd68f 100644 --- a/infrastructure/infrastructure-setup-terraform/10-private-network-basic/code/example.tfvars +++ b/infrastructure/infrastructure-setup-terraform/10-private-network-basic/code/example.tfvars @@ -1,7 +1,7 @@ # Example terraform.tfvars file # Copy this to terraform.tfvars and customize for your deployment -location = "eastus2" +location = "eastus" ai_foundry_name = "foundrypnadisabled" virtual_network_name = "private-vnet" virtual_network_address_space = "192.168.0.0/16" diff --git a/infrastructure/infrastructure-setup-terraform/10-private-network-basic/code/main.tf b/infrastructure/infrastructure-setup-terraform/10-private-network-basic/code/main.tf index d1fc017ef..aad299620 100644 --- a/infrastructure/infrastructure-setup-terraform/10-private-network-basic/code/main.tf +++ b/infrastructure/infrastructure-setup-terraform/10-private-network-basic/code/main.tf @@ -40,7 +40,7 @@ resource "azurerm_subnet" "pe_subnet" { resource "azapi_resource" "ai_foundry" { type = "Microsoft.CognitiveServices/accounts@2025-06-01" name = var.ai_foundry_name - location = var.location + location = coalesce(var.foundry_location, azurerm_resource_group.rg.location) parent_id = azurerm_resource_group.rg.id identity { @@ -136,7 +136,7 @@ resource "azurerm_private_endpoint" "ai_foundry_pe" { resource "azapi_resource" "ai_project" { type = "Microsoft.CognitiveServices/accounts/projects@2025-06-01" name = coalesce(var.ai_project_name, "${var.ai_foundry_name}-proj") - location = var.location + location = azapi_resource.ai_foundry.location parent_id = azapi_resource.ai_foundry.id identity { diff --git a/infrastructure/infrastructure-setup-terraform/10-private-network-basic/code/variables.tf b/infrastructure/infrastructure-setup-terraform/10-private-network-basic/code/variables.tf index c8208e58f..5ead03472 100644 --- a/infrastructure/infrastructure-setup-terraform/10-private-network-basic/code/variables.tf +++ b/infrastructure/infrastructure-setup-terraform/10-private-network-basic/code/variables.tf @@ -1,7 +1,35 @@ +variable "foundry_location" { + description = "Optional Foundry account location override. Defaults to the resource-group location." + type = string + default = null + + validation { + condition = var.foundry_location == null ? true : contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.foundry_location) + error_message = "The location must be a supported Microsoft Foundry region." + } +} + variable "location" { description = "The Azure region where resources will be deployed" type = string - default = "eastus2" + default = "eastus" + + validation { + condition = contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.location) + error_message = "The location must be a supported Microsoft Foundry region." + } } variable "ai_foundry_name" { diff --git a/infrastructure/infrastructure-setup-terraform/11-private-network-basic-vnet/code/main.tf b/infrastructure/infrastructure-setup-terraform/11-private-network-basic-vnet/code/main.tf index 1ad7bc611..3132c4293 100644 --- a/infrastructure/infrastructure-setup-terraform/11-private-network-basic-vnet/code/main.tf +++ b/infrastructure/infrastructure-setup-terraform/11-private-network-basic-vnet/code/main.tf @@ -82,7 +82,7 @@ resource "azapi_resource" "ai_foundry" { type = "Microsoft.CognitiveServices/accounts@2025-06-01" name = "aifoundry${random_string.unique.result}" parent_id = azurerm_resource_group.rg.id - location = var.location + location = coalesce(var.foundry_location, azurerm_resource_group.rg.location) schema_validation_enabled = false body = { @@ -254,7 +254,7 @@ resource "azapi_resource" "ai_foundry_project" { type = "Microsoft.CognitiveServices/accounts/projects@2025-06-01" name = "project${random_string.unique.result}" parent_id = azapi_resource.ai_foundry.id - location = var.location + location = azapi_resource.ai_foundry.location schema_validation_enabled = false body = { diff --git a/infrastructure/infrastructure-setup-terraform/11-private-network-basic-vnet/code/variables.tf b/infrastructure/infrastructure-setup-terraform/11-private-network-basic-vnet/code/variables.tf index b102dcd25..1ade80d7e 100644 --- a/infrastructure/infrastructure-setup-terraform/11-private-network-basic-vnet/code/variables.tf +++ b/infrastructure/infrastructure-setup-terraform/11-private-network-basic-vnet/code/variables.tf @@ -1,3 +1,20 @@ +variable "foundry_location" { + description = "Optional Foundry account location override. Defaults to the resource-group location." + type = string + default = null + + validation { + condition = var.foundry_location == null ? true : contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.foundry_location) + error_message = "The location must be a supported Microsoft Foundry region." + } +} + ## As of 6/2025 the agent subnet is limited to RFC1918 Class B and Class C address space variable "virtual_network_address_space" { description = "The address space for the virtual network" @@ -20,6 +37,17 @@ variable "private_endpoint_subnet_address_prefix" { variable "location" { description = "The name of the location to provision the resources to" type = string + + validation { + condition = contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.location) + error_message = "The location must be a supported Microsoft Foundry region." + } } variable "resource_group_name" { diff --git a/infrastructure/infrastructure-setup-terraform/15a-private-network-standard-agent-setup/code/main.tf b/infrastructure/infrastructure-setup-terraform/15a-private-network-standard-agent-setup/code/main.tf index cee79be36..fadd638cf 100644 --- a/infrastructure/infrastructure-setup-terraform/15a-private-network-standard-agent-setup/code/main.tf +++ b/infrastructure/infrastructure-setup-terraform/15a-private-network-standard-agent-setup/code/main.tf @@ -181,7 +181,7 @@ resource "azapi_resource" "ai_foundry" { type = "Microsoft.CognitiveServices/accounts@2025-06-01" name = "aifoundry${random_string.unique.result}" parent_id = azurerm_resource_group.rg.id - location = var.location + location = coalesce(var.foundry_location, azurerm_resource_group.rg.location) schema_validation_enabled = false body = { @@ -501,7 +501,7 @@ resource "azapi_resource" "ai_foundry_project" { type = "Microsoft.CognitiveServices/accounts/projects@2025-06-01" name = "project${random_string.unique.result}" parent_id = azapi_resource.ai_foundry.id - location = var.location + location = azapi_resource.ai_foundry.location schema_validation_enabled = false body = { diff --git a/infrastructure/infrastructure-setup-terraform/15a-private-network-standard-agent-setup/code/variables.tf b/infrastructure/infrastructure-setup-terraform/15a-private-network-standard-agent-setup/code/variables.tf index 5d324d72a..6a61983ee 100644 --- a/infrastructure/infrastructure-setup-terraform/15a-private-network-standard-agent-setup/code/variables.tf +++ b/infrastructure/infrastructure-setup-terraform/15a-private-network-standard-agent-setup/code/variables.tf @@ -1,3 +1,20 @@ +variable "foundry_location" { + description = "Optional Foundry account location override. Defaults to the resource-group location." + type = string + default = null + + validation { + condition = var.foundry_location == null ? true : contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.foundry_location) + error_message = "The location must be a supported Microsoft Foundry region." + } +} + ## As of 6/2025 this is limited to RFC1918 Class B and Class C address space variable "virtual_network_address_space" { description = "The address space for the virtual network" @@ -20,4 +37,15 @@ variable "private_endpoint_subnet_address_prefix" { variable "location" { description = "The name of the location to provision the resources to" type = string + + validation { + condition = contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.location) + error_message = "The location must be a supported Microsoft Foundry region." + } } diff --git a/infrastructure/infrastructure-setup-terraform/15b-private-network-standard-agent-setup-byovnet/code/main.tf b/infrastructure/infrastructure-setup-terraform/15b-private-network-standard-agent-setup-byovnet/code/main.tf index 564e53325..52ae0de41 100644 --- a/infrastructure/infrastructure-setup-terraform/15b-private-network-standard-agent-setup-byovnet/code/main.tf +++ b/infrastructure/infrastructure-setup-terraform/15b-private-network-standard-agent-setup-byovnet/code/main.tf @@ -12,6 +12,11 @@ resource "random_string" "unique" { upper = false } +data "azurerm_resource_group" "resources" { + provider = azurerm.workload_subscription + name = var.resource_group_name_resources +} + ########## Create resoures required to for agent data storage ########## @@ -85,7 +90,7 @@ resource "azapi_resource" "ai_search" { type = "Microsoft.Search/searchServices@2025-05-01" name = "aifoundry${random_string.unique.result}search" parent_id = "/subscriptions/${var.subscription_id_resources}/resourceGroups/${var.resource_group_name_resources}" - location = var.location + location = data.azurerm_resource_group.resources.location schema_validation_enabled = true body = { @@ -132,7 +137,14 @@ resource "azapi_resource" "ai_foundry" { type = "Microsoft.CognitiveServices/accounts@2025-06-01" name = "aifoundry${random_string.unique.result}" parent_id = "/subscriptions/${var.subscription_id_resources}/resourceGroups/${var.resource_group_name_resources}" - location = var.location + location = coalesce(var.foundry_location, data.azurerm_resource_group.resources.location) + + lifecycle { + precondition { + condition = data.azurerm_resource_group.resources.location == var.location && coalesce(var.foundry_location, data.azurerm_resource_group.resources.location) == var.location + error_message = "The workload resource group, VNet, and Foundry account must all use var.location." + } + } schema_validation_enabled = false body = { @@ -341,7 +353,7 @@ resource "azapi_resource" "ai_foundry_project" { type = "Microsoft.CognitiveServices/accounts/projects@2025-06-01" name = "project${random_string.unique.result}" parent_id = azapi_resource.ai_foundry.id - location = var.location + location = azapi_resource.ai_foundry.location schema_validation_enabled = false body = { @@ -459,7 +471,7 @@ resource "azapi_resource" "conn_aisearch" { ApiType = "Azure" ApiVersion = "2025-05-01-preview" ResourceId = azapi_resource.ai_search.id - location = var.location + location = azapi_resource.ai_search.location } } } diff --git a/infrastructure/infrastructure-setup-terraform/15b-private-network-standard-agent-setup-byovnet/code/variables.tf b/infrastructure/infrastructure-setup-terraform/15b-private-network-standard-agent-setup-byovnet/code/variables.tf index f7e39f0c3..28759b3a0 100644 --- a/infrastructure/infrastructure-setup-terraform/15b-private-network-standard-agent-setup-byovnet/code/variables.tf +++ b/infrastructure/infrastructure-setup-terraform/15b-private-network-standard-agent-setup-byovnet/code/variables.tf @@ -1,3 +1,20 @@ +variable "foundry_location" { + description = "Optional Foundry account location override. Defaults to the resource-group location." + type = string + default = null + + validation { + condition = var.foundry_location == null ? true : contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.foundry_location) + error_message = "The location must be a supported Microsoft Foundry region." + } +} + variable "resource_group_name_resources" { description = "The name of the existing resource group to deploy the resources into" type = string @@ -31,4 +48,15 @@ variable "subscription_id_resources" { variable "location" { description = "The name of the location to provision the resources to" type = string + + validation { + condition = contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.location) + error_message = "The location must be a supported Microsoft Foundry region." + } } diff --git a/infrastructure/infrastructure-setup-terraform/16-private-network-standard-agent-apim-setup-preview/code/example.tfvars b/infrastructure/infrastructure-setup-terraform/16-private-network-standard-agent-apim-setup-preview/code/example.tfvars index 26fa99143..02cec2e30 100644 --- a/infrastructure/infrastructure-setup-terraform/16-private-network-standard-agent-apim-setup-preview/code/example.tfvars +++ b/infrastructure/infrastructure-setup-terraform/16-private-network-standard-agent-apim-setup-preview/code/example.tfvars @@ -1,7 +1,7 @@ # Example configuration for private network standard agent with API Management # Azure region -location = "eastus2" +location = "eastus" # AI Foundry configuration ai_services_name_prefix = "foundry" diff --git a/infrastructure/infrastructure-setup-terraform/16-private-network-standard-agent-apim-setup-preview/code/main.tf b/infrastructure/infrastructure-setup-terraform/16-private-network-standard-agent-apim-setup-preview/code/main.tf index b828beb6b..aaec1c9e0 100644 --- a/infrastructure/infrastructure-setup-terraform/16-private-network-standard-agent-apim-setup-preview/code/main.tf +++ b/infrastructure/infrastructure-setup-terraform/16-private-network-standard-agent-apim-setup-preview/code/main.tf @@ -324,7 +324,7 @@ resource "azurerm_private_endpoint" "cosmos" { resource "azapi_resource" "ai_foundry" { type = "Microsoft.CognitiveServices/accounts@2025-04-01-preview" name = local.account_name - location = var.location + location = coalesce(var.foundry_location, azurerm_resource_group.rg.location) parent_id = azurerm_resource_group.rg.id identity { @@ -436,7 +436,7 @@ resource "time_sleep" "wait_for_resources" { resource "azapi_resource" "ai_project" { type = "Microsoft.CognitiveServices/accounts/projects@2025-04-01-preview" name = var.project_name - location = var.location + location = azapi_resource.ai_foundry.location parent_id = azapi_resource.ai_foundry.id identity { diff --git a/infrastructure/infrastructure-setup-terraform/16-private-network-standard-agent-apim-setup-preview/code/variables.tf b/infrastructure/infrastructure-setup-terraform/16-private-network-standard-agent-apim-setup-preview/code/variables.tf index d0763cb4f..c37be73f9 100644 --- a/infrastructure/infrastructure-setup-terraform/16-private-network-standard-agent-apim-setup-preview/code/variables.tf +++ b/infrastructure/infrastructure-setup-terraform/16-private-network-standard-agent-apim-setup-preview/code/variables.tf @@ -1,7 +1,35 @@ +variable "foundry_location" { + description = "Optional Foundry account location override. Defaults to the resource-group location." + type = string + default = null + + validation { + condition = var.foundry_location == null ? true : contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.foundry_location) + error_message = "The location must be a supported Microsoft Foundry region." + } +} + variable "location" { description = "The Azure region where resources will be deployed" type = string - default = "eastus2" + default = "eastus" + + validation { + condition = contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.location) + error_message = "The location must be a supported Microsoft Foundry region." + } } variable "ai_services_name_prefix" { diff --git a/infrastructure/infrastructure-setup-terraform/17-private-network-standard-user-assigned-identity-agent-setup/code/example.tfvars b/infrastructure/infrastructure-setup-terraform/17-private-network-standard-user-assigned-identity-agent-setup/code/example.tfvars index 16c319a5c..d94184c3b 100644 --- a/infrastructure/infrastructure-setup-terraform/17-private-network-standard-user-assigned-identity-agent-setup/code/example.tfvars +++ b/infrastructure/infrastructure-setup-terraform/17-private-network-standard-user-assigned-identity-agent-setup/code/example.tfvars @@ -1,7 +1,7 @@ # Example configuration for private network standard agent with UAI # Azure region -location = "eastus2" +location = "eastus" # AI Foundry configuration ai_services_name_prefix = "foundry" diff --git a/infrastructure/infrastructure-setup-terraform/17-private-network-standard-user-assigned-identity-agent-setup/code/main.tf b/infrastructure/infrastructure-setup-terraform/17-private-network-standard-user-assigned-identity-agent-setup/code/main.tf index ed8ed2dd4..ea0545a85 100644 --- a/infrastructure/infrastructure-setup-terraform/17-private-network-standard-user-assigned-identity-agent-setup/code/main.tf +++ b/infrastructure/infrastructure-setup-terraform/17-private-network-standard-user-assigned-identity-agent-setup/code/main.tf @@ -223,7 +223,7 @@ resource "azurerm_private_endpoint" "cosmos" { resource "azapi_resource" "ai_foundry" { type = "Microsoft.CognitiveServices/accounts@2025-04-01-preview" name = local.account_name - location = var.location + location = coalesce(var.foundry_location, azurerm_resource_group.rg.location) parent_id = azurerm_resource_group.rg.id identity { @@ -317,7 +317,7 @@ resource "time_sleep" "wait_for_rbac" { resource "azapi_resource" "ai_project" { type = "Microsoft.CognitiveServices/accounts/projects@2025-04-01-preview" name = var.project_name - location = var.location + location = azapi_resource.ai_foundry.location parent_id = azapi_resource.ai_foundry.id identity { diff --git a/infrastructure/infrastructure-setup-terraform/17-private-network-standard-user-assigned-identity-agent-setup/code/variables.tf b/infrastructure/infrastructure-setup-terraform/17-private-network-standard-user-assigned-identity-agent-setup/code/variables.tf index fa2de1118..dfd0ffc15 100644 --- a/infrastructure/infrastructure-setup-terraform/17-private-network-standard-user-assigned-identity-agent-setup/code/variables.tf +++ b/infrastructure/infrastructure-setup-terraform/17-private-network-standard-user-assigned-identity-agent-setup/code/variables.tf @@ -1,7 +1,35 @@ +variable "foundry_location" { + description = "Optional Foundry account location override. Defaults to the resource-group location." + type = string + default = null + + validation { + condition = var.foundry_location == null ? true : contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.foundry_location) + error_message = "The location must be a supported Microsoft Foundry region." + } +} + variable "location" { description = "The Azure region where resources will be deployed" type = string - default = "eastus2" + default = "eastus" + + validation { + condition = contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.location) + error_message = "The location must be a supported Microsoft Foundry region." + } } variable "ai_services_name_prefix" { diff --git a/infrastructure/infrastructure-setup-terraform/18-managed-virtual-network/ai-foundry.tf b/infrastructure/infrastructure-setup-terraform/18-managed-virtual-network/ai-foundry.tf index c33ea9997..3c60e568c 100644 --- a/infrastructure/infrastructure-setup-terraform/18-managed-virtual-network/ai-foundry.tf +++ b/infrastructure/infrastructure-setup-terraform/18-managed-virtual-network/ai-foundry.tf @@ -2,7 +2,7 @@ resource "azapi_resource" "cognitive_account" { type = "Microsoft.CognitiveServices/accounts@2025-10-01-preview" name = local.foundry_name - location = azurerm_resource_group.main.location + location = coalesce(var.foundry_location, azurerm_resource_group.main.location) parent_id = azurerm_resource_group.main.id schema_validation_enabled = false @@ -259,7 +259,7 @@ resource "azapi_resource" "a365_frontdoor_outbound_rule" { resource "azapi_resource" "ai_foundry_project" { type = "Microsoft.CognitiveServices/accounts/projects@2025-04-01-preview" name = "firstProject" - location = var.location + location = azapi_resource.cognitive_account.location parent_id = azapi_resource.cognitive_account.id schema_validation_enabled = false diff --git a/infrastructure/infrastructure-setup-terraform/18-managed-virtual-network/terraform.tfvars.example b/infrastructure/infrastructure-setup-terraform/18-managed-virtual-network/terraform.tfvars.example index 34ccbebd2..98efae7af 100644 --- a/infrastructure/infrastructure-setup-terraform/18-managed-virtual-network/terraform.tfvars.example +++ b/infrastructure/infrastructure-setup-terraform/18-managed-virtual-network/terraform.tfvars.example @@ -2,7 +2,7 @@ # Copy this file to terraform.tfvars and update with your values subscription_id = "%subscription_id%" resource_group_name = "foundry-mvnet-rg" -location = "eastus2" +location = "uaenorth" foundry_identifier = "foundry-v1" # Avoid issues with soft delete, helps make the resource unique # Tags to apply to all resources diff --git a/infrastructure/infrastructure-setup-terraform/18-managed-virtual-network/variables.tf b/infrastructure/infrastructure-setup-terraform/18-managed-virtual-network/variables.tf index 3f4db5731..dfabd81c3 100644 --- a/infrastructure/infrastructure-setup-terraform/18-managed-virtual-network/variables.tf +++ b/infrastructure/infrastructure-setup-terraform/18-managed-virtual-network/variables.tf @@ -1,3 +1,20 @@ +variable "foundry_location" { + description = "Optional Foundry account location override. Defaults to the resource-group location." + type = string + default = null + + validation { + condition = var.foundry_location == null ? true : contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.foundry_location) + error_message = "The location must be a supported Microsoft Foundry region." + } +} + variable "subscription_id" { description = "The Azure subscription ID" type = string @@ -12,6 +29,17 @@ variable "location" { description = "Azure region for resources" type = string default = "uaenorth" + + validation { + condition = contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.location) + error_message = "The location must be a supported Microsoft Foundry region." + } } variable "foundry_identifier" { diff --git a/infrastructure/infrastructure-setup-terraform/19-private-network-agent-setup-with-tools/code/data.tf b/infrastructure/infrastructure-setup-terraform/19-private-network-agent-setup-with-tools/code/data.tf index 8588c231c..85e22a012 100644 --- a/infrastructure/infrastructure-setup-terraform/19-private-network-agent-setup-with-tools/code/data.tf +++ b/infrastructure/infrastructure-setup-terraform/19-private-network-agent-setup-with-tools/code/data.tf @@ -2,6 +2,11 @@ ########## These are only instantiated when using existing resources (count = 0 by default). ########## +data "azurerm_resource_group" "existing" { + count = local.create_rg ? 0 : 1 + name = var.existing_resource_group_name +} + ## Existing Storage Account — needed for primary_blob_endpoint data "azurerm_storage_account" "existing" { count = local.create_storage ? 0 : 1 @@ -18,8 +23,8 @@ data "azurerm_cosmosdb_account" "existing" { ## Existing AI Search — needed for location metadata in connections data "azapi_resource" "existing_search" { - count = local.create_search ? 0 : 1 - type = "Microsoft.Search/searchServices@2024-06-01-preview" - resource_id = var.existing_ai_search_id + count = local.create_search ? 0 : 1 + type = "Microsoft.Search/searchServices@2024-06-01-preview" + resource_id = var.existing_ai_search_id response_export_values = ["location"] } diff --git a/infrastructure/infrastructure-setup-terraform/19-private-network-agent-setup-with-tools/code/locals.tf b/infrastructure/infrastructure-setup-terraform/19-private-network-agent-setup-with-tools/code/locals.tf index 6469701fd..c00895d83 100644 --- a/infrastructure/infrastructure-setup-terraform/19-private-network-agent-setup-with-tools/code/locals.tf +++ b/infrastructure/infrastructure-setup-terraform/19-private-network-agent-setup-with-tools/code/locals.tf @@ -23,17 +23,18 @@ locals { create_fabric = var.existing_fabric_workspace_id != "" ## DNS zones — create when no existing resource group provided - create_dns_zones = var.existing_dns_zones_resource_group == "" - dns_zones_sub_id = coalesce(var.existing_dns_zones_subscription_id, data.azurerm_client_config.current.subscription_id) - dns_zones_rg = var.existing_dns_zones_resource_group + create_dns_zones = var.existing_dns_zones_resource_group == "" + dns_zones_sub_id = coalesce(var.existing_dns_zones_subscription_id, data.azurerm_client_config.current.subscription_id) + dns_zones_rg = var.existing_dns_zones_resource_group ########## Unified resource references ########## All downstream code uses these locals instead of direct resource references. ########## ## Resource Group - rg_name = local.create_rg ? azurerm_resource_group.rg[0].name : var.existing_resource_group_name - rg_id = local.create_rg ? azurerm_resource_group.rg[0].id : "/subscriptions/${data.azurerm_client_config.current.subscription_id}/resourceGroups/${var.existing_resource_group_name}" + rg_name = local.create_rg ? azurerm_resource_group.rg[0].name : var.existing_resource_group_name + rg_id = local.create_rg ? azurerm_resource_group.rg[0].id : "/subscriptions/${data.azurerm_client_config.current.subscription_id}/resourceGroups/${var.existing_resource_group_name}" + rg_location = local.create_rg ? azurerm_resource_group.rg[0].location : data.azurerm_resource_group.existing[0].location ## VNet vnet_id = local.create_vnet ? azurerm_virtual_network.vnet[0].id : var.existing_vnet_id @@ -61,7 +62,7 @@ locals { ## AI Search search_id = local.create_search ? azapi_resource.ai_search[0].id : var.existing_ai_search_id search_name = local.create_search ? azapi_resource.ai_search[0].name : split("/", var.existing_ai_search_id)[8] - search_location = local.create_search ? var.location : data.azapi_resource.existing_search[0].output.location + search_location = local.create_search ? azapi_resource.ai_search[0].location : data.azapi_resource.existing_search[0].output.location ## Fabric (BYO-only, never created — only PE + DNS when workspace ID provided) fabric_name = local.create_fabric ? split("/", var.existing_fabric_workspace_id)[8] : "" diff --git a/infrastructure/infrastructure-setup-terraform/19-private-network-agent-setup-with-tools/code/main.tf b/infrastructure/infrastructure-setup-terraform/19-private-network-agent-setup-with-tools/code/main.tf index 82f072306..da813ff05 100644 --- a/infrastructure/infrastructure-setup-terraform/19-private-network-agent-setup-with-tools/code/main.tf +++ b/infrastructure/infrastructure-setup-terraform/19-private-network-agent-setup-with-tools/code/main.tf @@ -151,7 +151,7 @@ resource "azapi_resource" "ai_search" { type = "Microsoft.Search/searchServices@2024-06-01-preview" name = "aifoundry${random_string.unique.result}search" parent_id = local.rg_id - location = var.location + location = local.rg_location schema_validation_enabled = false body = { @@ -211,7 +211,14 @@ resource "azapi_resource" "ai_foundry" { type = "Microsoft.CognitiveServices/accounts@2025-04-01-preview" name = local.account_name parent_id = local.rg_id - location = var.location + location = coalesce(var.foundry_location, local.rg_location) + + lifecycle { + precondition { + condition = local.rg_location == var.location && coalesce(var.foundry_location, local.rg_location) == var.location + error_message = "The workload resource group, VNet, and Foundry account must all use var.location." + } + } schema_validation_enabled = false identity { @@ -524,7 +531,7 @@ resource "azapi_resource" "ai_project" { ] type = "Microsoft.CognitiveServices/accounts/projects@2025-04-01-preview" name = var.project_name - location = var.location + location = azapi_resource.ai_foundry.location parent_id = azapi_resource.ai_foundry.id schema_validation_enabled = false diff --git a/infrastructure/infrastructure-setup-terraform/19-private-network-agent-setup-with-tools/code/variables.tf b/infrastructure/infrastructure-setup-terraform/19-private-network-agent-setup-with-tools/code/variables.tf index 8a6947f02..7c96fa420 100644 --- a/infrastructure/infrastructure-setup-terraform/19-private-network-agent-setup-with-tools/code/variables.tf +++ b/infrastructure/infrastructure-setup-terraform/19-private-network-agent-setup-with-tools/code/variables.tf @@ -1,6 +1,34 @@ +variable "foundry_location" { + description = "Optional Foundry account location override. Defaults to the resource-group location." + type = string + default = null + + validation { + condition = var.foundry_location == null ? true : contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.foundry_location) + error_message = "The location must be a supported Microsoft Foundry region." + } +} + variable "location" { description = "The Azure region where resources will be deployed" type = string + + validation { + condition = contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.location) + error_message = "The location must be a supported Microsoft Foundry region." + } } variable "ai_services_name_prefix" { diff --git a/infrastructure/infrastructure-setup-terraform/20-user-assigned-identity/code/example.tfvars b/infrastructure/infrastructure-setup-terraform/20-user-assigned-identity/code/example.tfvars index a72b95b71..62a20b17d 100644 --- a/infrastructure/infrastructure-setup-terraform/20-user-assigned-identity/code/example.tfvars +++ b/infrastructure/infrastructure-setup-terraform/20-user-assigned-identity/code/example.tfvars @@ -1,7 +1,7 @@ # Example terraform.tfvars file # Copy this to terraform.tfvars and customize for your deployment -location = "eastus2" +location = "eastus" ai_foundry_name = "foundry-uai" ai_project_name = "foundry-uai-proj" create_user_assigned_identity = true diff --git a/infrastructure/infrastructure-setup-terraform/20-user-assigned-identity/code/main.tf b/infrastructure/infrastructure-setup-terraform/20-user-assigned-identity/code/main.tf index c872780ed..10fb47343 100644 --- a/infrastructure/infrastructure-setup-terraform/20-user-assigned-identity/code/main.tf +++ b/infrastructure/infrastructure-setup-terraform/20-user-assigned-identity/code/main.tf @@ -48,7 +48,7 @@ locals { resource "azapi_resource" "ai_foundry" { type = "Microsoft.CognitiveServices/accounts@2025-06-01" name = var.ai_foundry_name - location = var.location + location = coalesce(var.foundry_location, azurerm_resource_group.rg.location) parent_id = azurerm_resource_group.rg.id identity { @@ -74,7 +74,7 @@ resource "azapi_resource" "ai_foundry" { resource "azapi_resource" "ai_project" { type = "Microsoft.CognitiveServices/accounts/projects@2025-06-01" name = coalesce(var.ai_project_name, "${var.ai_foundry_name}-proj") - location = var.location + location = azapi_resource.ai_foundry.location parent_id = azapi_resource.ai_foundry.id identity { diff --git a/infrastructure/infrastructure-setup-terraform/20-user-assigned-identity/code/variables.tf b/infrastructure/infrastructure-setup-terraform/20-user-assigned-identity/code/variables.tf index 5cce5399f..d3ae47bd2 100644 --- a/infrastructure/infrastructure-setup-terraform/20-user-assigned-identity/code/variables.tf +++ b/infrastructure/infrastructure-setup-terraform/20-user-assigned-identity/code/variables.tf @@ -1,7 +1,35 @@ +variable "foundry_location" { + description = "Optional Foundry account location override. Defaults to the resource-group location." + type = string + default = null + + validation { + condition = var.foundry_location == null ? true : contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.foundry_location) + error_message = "The location must be a supported Microsoft Foundry region." + } +} + variable "location" { description = "The Azure region where resources will be deployed" type = string - default = "eastus2" + default = "eastus" + + validation { + condition = contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.location) + error_message = "The location must be a supported Microsoft Foundry region." + } } variable "ai_foundry_name" { diff --git a/infrastructure/infrastructure-setup-terraform/25-entraid-passthrough/code/example.tfvars b/infrastructure/infrastructure-setup-terraform/25-entraid-passthrough/code/example.tfvars index a5bdd861e..302e34575 100644 --- a/infrastructure/infrastructure-setup-terraform/25-entraid-passthrough/code/example.tfvars +++ b/infrastructure/infrastructure-setup-terraform/25-entraid-passthrough/code/example.tfvars @@ -1,4 +1,4 @@ -location = "eastus2" +location = "eastus" ai_foundry_name = "foundry-entraid" ai_project_name = "foundry-entraid-proj" model_name = "gpt-4.1-mini" diff --git a/infrastructure/infrastructure-setup-terraform/25-entraid-passthrough/code/main.tf b/infrastructure/infrastructure-setup-terraform/25-entraid-passthrough/code/main.tf index 40300b6e3..6d3df0109 100644 --- a/infrastructure/infrastructure-setup-terraform/25-entraid-passthrough/code/main.tf +++ b/infrastructure/infrastructure-setup-terraform/25-entraid-passthrough/code/main.tf @@ -45,7 +45,7 @@ resource "azurerm_storage_account" "storage" { resource "azapi_resource" "ai_foundry" { type = "Microsoft.CognitiveServices/accounts@2025-04-01-preview" name = var.ai_foundry_name - location = var.location + location = coalesce(var.foundry_location, azurerm_resource_group.rg.location) parent_id = azurerm_resource_group.rg.id identity { @@ -70,7 +70,7 @@ resource "azapi_resource" "ai_foundry" { resource "azapi_resource" "ai_project" { type = "Microsoft.CognitiveServices/accounts/projects@2025-04-01-preview" name = var.ai_project_name - location = var.location + location = azapi_resource.ai_foundry.location parent_id = azapi_resource.ai_foundry.id identity { diff --git a/infrastructure/infrastructure-setup-terraform/25-entraid-passthrough/code/variables.tf b/infrastructure/infrastructure-setup-terraform/25-entraid-passthrough/code/variables.tf index 0a518ad58..845d001d5 100644 --- a/infrastructure/infrastructure-setup-terraform/25-entraid-passthrough/code/variables.tf +++ b/infrastructure/infrastructure-setup-terraform/25-entraid-passthrough/code/variables.tf @@ -1,7 +1,35 @@ +variable "foundry_location" { + description = "Optional Foundry account location override. Defaults to the resource-group location." + type = string + default = null + + validation { + condition = var.foundry_location == null ? true : contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.foundry_location) + error_message = "The location must be a supported Microsoft Foundry region." + } +} + variable "location" { description = "The Azure region where resources will be deployed" type = string - default = "eastus2" + default = "eastus" + + validation { + condition = contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.location) + error_message = "The location must be a supported Microsoft Foundry region." + } } variable "ai_foundry_name" { diff --git a/infrastructure/infrastructure-setup-terraform/30-customer-managed-keys/code/example.tfvars b/infrastructure/infrastructure-setup-terraform/30-customer-managed-keys/code/example.tfvars index 2224815b6..17c13bdda 100644 --- a/infrastructure/infrastructure-setup-terraform/30-customer-managed-keys/code/example.tfvars +++ b/infrastructure/infrastructure-setup-terraform/30-customer-managed-keys/code/example.tfvars @@ -1,7 +1,7 @@ # Example terraform.tfvars file # Copy this to terraform.tfvars and customize for your deployment -location = "eastus2" +location = "eastus" ai_foundry_name = "foundry-cmk" ai_project_name = "foundry-cmk-proj" model_name = "gpt-4.1-mini" diff --git a/infrastructure/infrastructure-setup-terraform/30-customer-managed-keys/code/main.tf b/infrastructure/infrastructure-setup-terraform/30-customer-managed-keys/code/main.tf index 4a1e90b5c..0d5d3e021 100644 --- a/infrastructure/infrastructure-setup-terraform/30-customer-managed-keys/code/main.tf +++ b/infrastructure/infrastructure-setup-terraform/30-customer-managed-keys/code/main.tf @@ -54,7 +54,7 @@ resource "azurerm_key_vault_key" "cmk" { resource "azapi_resource" "ai_foundry" { type = "Microsoft.CognitiveServices/accounts@2025-06-01" name = var.ai_foundry_name - location = var.location + location = coalesce(var.foundry_location, azurerm_resource_group.rg.location) parent_id = azurerm_resource_group.rg.id identity { @@ -67,8 +67,8 @@ resource "azapi_resource" "ai_foundry" { name = "S0" } properties = { - allowProjectManagement = true - customSubDomainName = "aifoundry${random_string.unique.result}" + allowProjectManagement = true + customSubDomainName = "aifoundry${random_string.unique.result}" disableLocalAuth = false publicNetworkAccess = "Enabled" } @@ -113,7 +113,7 @@ resource "azapi_update_resource" "ai_foundry_cmk" { resource "azapi_resource" "ai_project" { type = "Microsoft.CognitiveServices/accounts/projects@2025-06-01" name = coalesce(var.ai_project_name, "${var.ai_foundry_name}-proj") - location = var.location + location = azapi_resource.ai_foundry.location parent_id = azapi_resource.ai_foundry.id identity { diff --git a/infrastructure/infrastructure-setup-terraform/30-customer-managed-keys/code/variables.tf b/infrastructure/infrastructure-setup-terraform/30-customer-managed-keys/code/variables.tf index d90f8cd09..af66f45b0 100644 --- a/infrastructure/infrastructure-setup-terraform/30-customer-managed-keys/code/variables.tf +++ b/infrastructure/infrastructure-setup-terraform/30-customer-managed-keys/code/variables.tf @@ -1,7 +1,35 @@ +variable "foundry_location" { + description = "Optional Foundry account location override. Defaults to the resource-group location." + type = string + default = null + + validation { + condition = var.foundry_location == null ? true : contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.foundry_location) + error_message = "The location must be a supported Microsoft Foundry region." + } +} + variable "location" { description = "The Azure region where resources will be deployed" type = string - default = "eastus2" + default = "eastus" + + validation { + condition = contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.location) + error_message = "The location must be a supported Microsoft Foundry region." + } } variable "ai_foundry_name" { diff --git a/infrastructure/infrastructure-setup-terraform/31-customer-managed-keys-standard-agent/code/example.tfvars b/infrastructure/infrastructure-setup-terraform/31-customer-managed-keys-standard-agent/code/example.tfvars index 5b8cdcb89..4cccc3336 100644 --- a/infrastructure/infrastructure-setup-terraform/31-customer-managed-keys-standard-agent/code/example.tfvars +++ b/infrastructure/infrastructure-setup-terraform/31-customer-managed-keys-standard-agent/code/example.tfvars @@ -1,7 +1,7 @@ # Example configuration for customer-managed keys with standard agent # Azure region -location = "eastus2" +location = "eastus" # AI Foundry configuration ai_services_name_prefix = "foundry" diff --git a/infrastructure/infrastructure-setup-terraform/31-customer-managed-keys-standard-agent/code/main.tf b/infrastructure/infrastructure-setup-terraform/31-customer-managed-keys-standard-agent/code/main.tf index 6900e1786..7c7c68b8e 100644 --- a/infrastructure/infrastructure-setup-terraform/31-customer-managed-keys-standard-agent/code/main.tf +++ b/infrastructure/infrastructure-setup-terraform/31-customer-managed-keys-standard-agent/code/main.tf @@ -109,7 +109,7 @@ resource "azurerm_cosmosdb_account" "cosmos" { resource "azapi_resource" "ai_foundry" { type = "Microsoft.CognitiveServices/accounts@2025-06-01" name = local.account_name - location = var.location + location = coalesce(var.foundry_location, azurerm_resource_group.rg.location) parent_id = azurerm_resource_group.rg.id identity { @@ -221,7 +221,7 @@ resource "time_sleep" "wait_for_rbac" { resource "azapi_resource" "ai_project" { type = "Microsoft.CognitiveServices/accounts/projects@2025-04-01-preview" name = var.project_name - location = var.location + location = azapi_resource.ai_foundry.location parent_id = azapi_resource.ai_foundry.id identity { diff --git a/infrastructure/infrastructure-setup-terraform/31-customer-managed-keys-standard-agent/code/variables.tf b/infrastructure/infrastructure-setup-terraform/31-customer-managed-keys-standard-agent/code/variables.tf index 685d84eed..3f07a656d 100644 --- a/infrastructure/infrastructure-setup-terraform/31-customer-managed-keys-standard-agent/code/variables.tf +++ b/infrastructure/infrastructure-setup-terraform/31-customer-managed-keys-standard-agent/code/variables.tf @@ -1,7 +1,35 @@ +variable "foundry_location" { + description = "Optional Foundry account location override. Defaults to the resource-group location." + type = string + default = null + + validation { + condition = var.foundry_location == null ? true : contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.foundry_location) + error_message = "The location must be a supported Microsoft Foundry region." + } +} + variable "location" { description = "The Azure region where resources will be deployed" type = string - default = "eastus2" + default = "eastus" + + validation { + condition = contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.location) + error_message = "The location must be a supported Microsoft Foundry region." + } } variable "ai_services_name_prefix" { diff --git a/infrastructure/infrastructure-setup-terraform/32-customer-managed-keys-user-assigned-identity/code/example.tfvars b/infrastructure/infrastructure-setup-terraform/32-customer-managed-keys-user-assigned-identity/code/example.tfvars index 9fe051a3c..3fb692c22 100644 --- a/infrastructure/infrastructure-setup-terraform/32-customer-managed-keys-user-assigned-identity/code/example.tfvars +++ b/infrastructure/infrastructure-setup-terraform/32-customer-managed-keys-user-assigned-identity/code/example.tfvars @@ -1,7 +1,7 @@ # Example configuration for customer-managed keys with user-assigned identity # Azure region -location = "eastus2" +location = "eastus" # AI Foundry configuration ai_foundry_name = "foundry-cmk-uai" diff --git a/infrastructure/infrastructure-setup-terraform/32-customer-managed-keys-user-assigned-identity/code/main.tf b/infrastructure/infrastructure-setup-terraform/32-customer-managed-keys-user-assigned-identity/code/main.tf index d7c9a9052..15a8f1aaa 100644 --- a/infrastructure/infrastructure-setup-terraform/32-customer-managed-keys-user-assigned-identity/code/main.tf +++ b/infrastructure/infrastructure-setup-terraform/32-customer-managed-keys-user-assigned-identity/code/main.tf @@ -91,7 +91,7 @@ resource "time_sleep" "wait_for_kv_permissions" { resource "azapi_resource" "ai_foundry" { type = "Microsoft.CognitiveServices/accounts@2025-06-01" name = var.ai_foundry_name - location = var.location + location = coalesce(var.foundry_location, azurerm_resource_group.rg.location) parent_id = azurerm_resource_group.rg.id identity { @@ -140,7 +140,7 @@ resource "azapi_update_resource" "ai_foundry_cmk" { resource "azapi_resource" "ai_project" { type = "Microsoft.CognitiveServices/accounts/projects@2025-06-01" name = coalesce(var.ai_project_name, "${var.ai_foundry_name}-proj") - location = var.location + location = azapi_resource.ai_foundry.location parent_id = azapi_resource.ai_foundry.id identity { diff --git a/infrastructure/infrastructure-setup-terraform/32-customer-managed-keys-user-assigned-identity/code/variables.tf b/infrastructure/infrastructure-setup-terraform/32-customer-managed-keys-user-assigned-identity/code/variables.tf index e96832a93..684770d7d 100644 --- a/infrastructure/infrastructure-setup-terraform/32-customer-managed-keys-user-assigned-identity/code/variables.tf +++ b/infrastructure/infrastructure-setup-terraform/32-customer-managed-keys-user-assigned-identity/code/variables.tf @@ -1,7 +1,35 @@ +variable "foundry_location" { + description = "Optional Foundry account location override. Defaults to the resource-group location." + type = string + default = null + + validation { + condition = var.foundry_location == null ? true : contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.foundry_location) + error_message = "The location must be a supported Microsoft Foundry region." + } +} + variable "location" { description = "The Azure region where resources will be deployed" type = string - default = "eastus2" + default = "eastus" + + validation { + condition = contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.location) + error_message = "The location must be a supported Microsoft Foundry region." + } } variable "ai_foundry_name" { diff --git a/infrastructure/infrastructure-setup-terraform/41-standard-agent-setup/code/example.tfvars b/infrastructure/infrastructure-setup-terraform/41-standard-agent-setup/code/example.tfvars index b5db0b002..d496f8be9 100644 --- a/infrastructure/infrastructure-setup-terraform/41-standard-agent-setup/code/example.tfvars +++ b/infrastructure/infrastructure-setup-terraform/41-standard-agent-setup/code/example.tfvars @@ -1,7 +1,7 @@ # Example terraform.tfvars file # Copy this to terraform.tfvars and customize for your deployment -location = "eastus2" +location = "eastus" ai_services_name_prefix = "foundry" project_name = "standard-agent-project" model_name = "gpt-4.1" diff --git a/infrastructure/infrastructure-setup-terraform/41-standard-agent-setup/code/main.tf b/infrastructure/infrastructure-setup-terraform/41-standard-agent-setup/code/main.tf index d6f6c3d59..2e2678811 100644 --- a/infrastructure/infrastructure-setup-terraform/41-standard-agent-setup/code/main.tf +++ b/infrastructure/infrastructure-setup-terraform/41-standard-agent-setup/code/main.tf @@ -79,7 +79,7 @@ resource "azurerm_cosmosdb_account" "cosmos" { resource "azapi_resource" "ai_foundry" { type = "Microsoft.CognitiveServices/accounts@2025-04-01-preview" name = local.account_name - location = var.location + location = coalesce(var.foundry_location, azurerm_resource_group.rg.location) parent_id = azurerm_resource_group.rg.id identity { @@ -147,7 +147,7 @@ resource "time_sleep" "wait_for_rbac" { resource "azapi_resource" "ai_project" { type = "Microsoft.CognitiveServices/accounts/projects@2025-04-01-preview" name = var.project_name - location = var.location + location = azapi_resource.ai_foundry.location parent_id = azapi_resource.ai_foundry.id identity { diff --git a/infrastructure/infrastructure-setup-terraform/41-standard-agent-setup/code/variables.tf b/infrastructure/infrastructure-setup-terraform/41-standard-agent-setup/code/variables.tf index 4560e2c7d..b58a33c7d 100644 --- a/infrastructure/infrastructure-setup-terraform/41-standard-agent-setup/code/variables.tf +++ b/infrastructure/infrastructure-setup-terraform/41-standard-agent-setup/code/variables.tf @@ -1,7 +1,35 @@ +variable "foundry_location" { + description = "Optional Foundry account location override. Defaults to the resource-group location." + type = string + default = null + + validation { + condition = var.foundry_location == null ? true : contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.foundry_location) + error_message = "The location must be a supported Microsoft Foundry region." + } +} + variable "location" { description = "The Azure region where resources will be deployed" type = string - default = "eastus2" + default = "eastus" + + validation { + condition = contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.location) + error_message = "The location must be a supported Microsoft Foundry region." + } } variable "ai_services_name_prefix" { diff --git a/infrastructure/infrastructure-setup-terraform/45-basic-agent-bing/code/example.tfvars b/infrastructure/infrastructure-setup-terraform/45-basic-agent-bing/code/example.tfvars index 865ff04d9..4371c68c4 100644 --- a/infrastructure/infrastructure-setup-terraform/45-basic-agent-bing/code/example.tfvars +++ b/infrastructure/infrastructure-setup-terraform/45-basic-agent-bing/code/example.tfvars @@ -1,7 +1,7 @@ # Example terraform.tfvars file # Copy this to terraform.tfvars and customize for your deployment -location = "eastus2" +location = "eastus" ai_foundry_name = "foundry-bing" ai_project_name = "foundry-bing-proj" bing_api_key = "YOUR_BING_API_KEY_HERE" # Replace with your actual Bing API key diff --git a/infrastructure/infrastructure-setup-terraform/45-basic-agent-bing/code/main.tf b/infrastructure/infrastructure-setup-terraform/45-basic-agent-bing/code/main.tf index d1b3bef58..8581743b9 100644 --- a/infrastructure/infrastructure-setup-terraform/45-basic-agent-bing/code/main.tf +++ b/infrastructure/infrastructure-setup-terraform/45-basic-agent-bing/code/main.tf @@ -28,7 +28,7 @@ resource "azurerm_resource_group" "rg" { resource "azapi_resource" "ai_foundry" { type = "Microsoft.CognitiveServices/accounts@2025-04-01-preview" name = local.account_name - location = var.location + location = coalesce(var.foundry_location, azurerm_resource_group.rg.location) parent_id = azurerm_resource_group.rg.id identity { @@ -78,7 +78,7 @@ resource "azapi_resource" "model_deployment" { resource "azapi_resource" "ai_project" { type = "Microsoft.CognitiveServices/accounts/projects@2025-04-01-preview" name = var.project_name - location = var.location + location = azapi_resource.ai_foundry.location parent_id = azapi_resource.ai_foundry.id identity { diff --git a/infrastructure/infrastructure-setup-terraform/45-basic-agent-bing/code/variables.tf b/infrastructure/infrastructure-setup-terraform/45-basic-agent-bing/code/variables.tf index 50ce0d9e0..bcbc3462a 100644 --- a/infrastructure/infrastructure-setup-terraform/45-basic-agent-bing/code/variables.tf +++ b/infrastructure/infrastructure-setup-terraform/45-basic-agent-bing/code/variables.tf @@ -1,7 +1,35 @@ +variable "foundry_location" { + description = "Optional Foundry account location override. Defaults to the resource-group location." + type = string + default = null + + validation { + condition = var.foundry_location == null ? true : contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.foundry_location) + error_message = "The location must be a supported Microsoft Foundry region." + } +} + variable "location" { description = "The Azure region where resources will be deployed" type = string - default = "eastus2" + default = "eastus" + + validation { + condition = contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.location) + error_message = "The location must be a supported Microsoft Foundry region." + } } variable "ai_services_name" { diff --git a/infrastructure/infrastructure-setup-terraform/46-bring-your-own-models/code/development-foundry.tf b/infrastructure/infrastructure-setup-terraform/46-bring-your-own-models/code/development-foundry.tf index 3e568902e..81d513e40 100644 --- a/infrastructure/infrastructure-setup-terraform/46-bring-your-own-models/code/development-foundry.tf +++ b/infrastructure/infrastructure-setup-terraform/46-bring-your-own-models/code/development-foundry.tf @@ -8,7 +8,7 @@ resource "azapi_resource" "foundry_agent_account" { provider = azapi.development type = "Microsoft.CognitiveServices/accounts@2025-04-01-preview" name = local.foundry_agent_account_name - location = var.location + location = coalesce(var.foundry_location, azurerm_resource_group.development.location) parent_id = azurerm_resource_group.development.id identity { diff --git a/infrastructure/infrastructure-setup-terraform/46-bring-your-own-models/code/development-projects.tf b/infrastructure/infrastructure-setup-terraform/46-bring-your-own-models/code/development-projects.tf index f64bbcdc3..25b7c023e 100644 --- a/infrastructure/infrastructure-setup-terraform/46-bring-your-own-models/code/development-projects.tf +++ b/infrastructure/infrastructure-setup-terraform/46-bring-your-own-models/code/development-projects.tf @@ -7,7 +7,7 @@ resource "azapi_resource" "project_alpha" { provider = azapi.development type = "Microsoft.CognitiveServices/accounts/projects@2025-04-01-preview" name = "alpha" - location = var.location + location = azapi_resource.foundry_agent_account.location parent_id = azapi_resource.foundry_agent_account.id identity { @@ -26,7 +26,7 @@ resource "azapi_resource" "project_beta" { provider = azapi.development type = "Microsoft.CognitiveServices/accounts/projects@2025-04-01-preview" name = "beta" - location = var.location + location = azapi_resource.foundry_agent_account.location parent_id = azapi_resource.foundry_agent_account.id identity { diff --git a/infrastructure/infrastructure-setup-terraform/46-bring-your-own-models/code/example.tfvars b/infrastructure/infrastructure-setup-terraform/46-bring-your-own-models/code/example.tfvars index c94388c2d..b2dbeba69 100644 --- a/infrastructure/infrastructure-setup-terraform/46-bring-your-own-models/code/example.tfvars +++ b/infrastructure/infrastructure-setup-terraform/46-bring-your-own-models/code/example.tfvars @@ -10,7 +10,7 @@ development_subscription_id = "11111111-1111-1111-1111-111111111111" tenant_id = "33333333-3333-3333-3333-333333333333" # --- Common --- -location = "eastus2" +location = "eastus" name_prefix = "contoso-byom" # --- APIM publisher metadata (required by APIM at create time) --- @@ -35,7 +35,7 @@ groq_api_key = "REPLACE_ME_WITH_GROQ_KEY" # groq_alias = "llama-3-70b" # --- Governance knobs --- -quota_tokens_per_minute = 167 # ~10K tokens/hour per project — demo-friendly +quota_tokens_per_minute = 167 # ~10K tokens/hour per project — demo-friendly # --- Developer group (Sub B) --- # Object ID of the Entra group whose members will get read/use access on diff --git a/infrastructure/infrastructure-setup-terraform/46-bring-your-own-models/code/platform-foundry.tf b/infrastructure/infrastructure-setup-terraform/46-bring-your-own-models/code/platform-foundry.tf index 569c0f0f9..bd298c7e8 100644 --- a/infrastructure/infrastructure-setup-terraform/46-bring-your-own-models/code/platform-foundry.tf +++ b/infrastructure/infrastructure-setup-terraform/46-bring-your-own-models/code/platform-foundry.tf @@ -5,7 +5,7 @@ resource "azapi_resource" "foundry_model_account" { provider = azapi.platform type = "Microsoft.CognitiveServices/accounts@2025-04-01-preview" name = local.foundry_model_account_name - location = var.location + location = coalesce(var.foundry_location, azurerm_resource_group.platform.location) parent_id = azurerm_resource_group.platform.id identity { diff --git a/infrastructure/infrastructure-setup-terraform/46-bring-your-own-models/code/variables.tf b/infrastructure/infrastructure-setup-terraform/46-bring-your-own-models/code/variables.tf index 0799b86cd..7a64e2a89 100644 --- a/infrastructure/infrastructure-setup-terraform/46-bring-your-own-models/code/variables.tf +++ b/infrastructure/infrastructure-setup-terraform/46-bring-your-own-models/code/variables.tf @@ -1,3 +1,20 @@ +variable "foundry_location" { + description = "Optional Foundry account location override. Defaults to each account's resource-group location." + type = string + default = null + + validation { + condition = var.foundry_location == null ? true : contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.foundry_location) + error_message = "The location must be a supported Microsoft Foundry region." + } +} + # ============================================================================ # Subscription and location inputs # ============================================================================ @@ -20,7 +37,18 @@ variable "tenant_id" { variable "location" { description = "Azure region for all resources in both subscriptions." type = string - default = "eastus2" + default = "eastus" + + validation { + condition = contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.location) + error_message = "The location must be a supported Microsoft Foundry region." + } } variable "name_prefix" { diff --git a/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/01-hub-base/variables.tf b/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/01-hub-base/variables.tf index 9724f11a5..a90313df6 100644 --- a/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/01-hub-base/variables.tf +++ b/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/01-hub-base/variables.tf @@ -16,6 +16,17 @@ variable "location" { description = "Azure region for all hub resources." type = string default = "swedencentral" + + validation { + condition = contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.location) + error_message = "The location must be a supported Microsoft Foundry region." + } } variable "name_prefix" { diff --git a/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/02-spoke-base/variables.tf b/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/02-spoke-base/variables.tf index e6e38cfd6..4d1308d4c 100644 --- a/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/02-spoke-base/variables.tf +++ b/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/02-spoke-base/variables.tf @@ -16,6 +16,17 @@ variable "location" { description = "Azure region. Must match hub-base's location (private DNS zones and peering assume same region)." type = string default = "swedencentral" + + validation { + condition = contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.location) + error_message = "The location must be a supported Microsoft Foundry region." + } } variable "name_prefix" { diff --git a/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/04-hub-workload/foundry-account.tf b/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/04-hub-workload/foundry-account.tf index 45dd3b65d..7ab25f53e 100644 --- a/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/04-hub-workload/foundry-account.tf +++ b/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/04-hub-workload/foundry-account.tf @@ -3,10 +3,14 @@ # in snet-pe. Local auth is disabled per H4 so APIM authenticates as its # system-assigned MI. +data "azurerm_resource_group" "hub" { + name = local.hub_rg_name +} + resource "azapi_resource" "foundry_model_account" { type = "Microsoft.CognitiveServices/accounts@2025-04-01-preview" name = local.foundry_model_account_name - location = local.location + location = coalesce(var.foundry_location, data.azurerm_resource_group.hub.location) parent_id = local.hub_rg_id identity { diff --git a/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/04-hub-workload/variables.tf b/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/04-hub-workload/variables.tf index 102964abf..a9d4ee2ef 100644 --- a/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/04-hub-workload/variables.tf +++ b/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/04-hub-workload/variables.tf @@ -12,6 +12,23 @@ variable "tenant_id" { type = string } +variable "foundry_location" { + description = "Optional Foundry account location override. Defaults to the hub resource-group location." + type = string + default = null + + validation { + condition = var.foundry_location == null ? true : contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.foundry_location) + error_message = "The location must be a supported Microsoft Foundry region." + } +} + variable "name_prefix" { description = "Same as hub-base's name_prefix. Used for names of workload resources placed alongside hub-base's resources." type = string diff --git a/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/05-spoke-workload-project/foundry-account.tf b/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/05-spoke-workload-project/foundry-account.tf index 1fc667e83..742452668 100644 --- a/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/05-spoke-workload-project/foundry-account.tf +++ b/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/05-spoke-workload-project/foundry-account.tf @@ -8,10 +8,14 @@ # through the platform APIM gateway to either the Foundry model account in # the hub or to third-party providers. +data "azurerm_resource_group" "spoke" { + name = local.spoke_rg_name +} + resource "azapi_resource" "foundry_agent_account" { type = "Microsoft.CognitiveServices/accounts@2025-04-01-preview" name = local.foundry_agent_account_name - location = local.location + location = coalesce(var.foundry_location, data.azurerm_resource_group.spoke.location) parent_id = local.spoke_rg_id tags = local.common_tags diff --git a/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/05-spoke-workload-project/project.tf b/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/05-spoke-workload-project/project.tf index 6c4483937..8a1b14040 100644 --- a/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/05-spoke-workload-project/project.tf +++ b/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/05-spoke-workload-project/project.tf @@ -7,7 +7,7 @@ resource "azapi_resource" "project" { type = "Microsoft.CognitiveServices/accounts/projects@2025-04-01-preview" name = var.project_name - location = local.location + location = azapi_resource.foundry_agent_account.location parent_id = azapi_resource.foundry_agent_account.id tags = local.common_tags diff --git a/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/05-spoke-workload-project/variables.tf b/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/05-spoke-workload-project/variables.tf index 1aa8cf543..beea58a9a 100644 --- a/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/05-spoke-workload-project/variables.tf +++ b/infrastructure/infrastructure-setup-terraform/47-bring-your-own-models-platform-lob/05-spoke-workload-project/variables.tf @@ -8,6 +8,23 @@ variable "tenant_id" { type = string } +variable "foundry_location" { + description = "Optional Foundry account location override. Defaults to the spoke resource-group location." + type = string + default = null + + validation { + condition = var.foundry_location == null ? true : contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.foundry_location) + error_message = "The location must be a supported Microsoft Foundry region." + } +} + variable "name_prefix" { description = "Same as spoke-base's name_prefix." type = string diff --git a/infrastructure/infrastructure-setup-terraform/48-bring-own-model-private-ca/code/foundry-agent.tf b/infrastructure/infrastructure-setup-terraform/48-bring-own-model-private-ca/code/foundry-agent.tf index d71c6605a..31dde0245 100644 --- a/infrastructure/infrastructure-setup-terraform/48-bring-own-model-private-ca/code/foundry-agent.tf +++ b/infrastructure/infrastructure-setup-terraform/48-bring-own-model-private-ca/code/foundry-agent.tf @@ -39,10 +39,17 @@ locals { resource "azapi_resource" "foundry_agent_account" { type = "Microsoft.CognitiveServices/accounts@2026-11-15-preview" name = local.foundry_agent_account_name - location = var.location + location = coalesce(var.foundry_location, local.create_rg ? azurerm_resource_group.rg[0].location : data.azurerm_resource_group.existing[0].location) parent_id = local.rg_id tags = local.common_tags + lifecycle { + precondition { + condition = coalesce(var.foundry_location, local.create_rg ? azurerm_resource_group.rg[0].location : data.azurerm_resource_group.existing[0].location) == var.location + error_message = "The Foundry account, its injected agent subnet, and the spoke VNet must all use var.location." + } + } + # trustedCertificateSources is a public-preview property that may not be in # the azapi embedded schema; skip client-side validation. schema_validation_enabled = false diff --git a/infrastructure/infrastructure-setup-terraform/48-bring-own-model-private-ca/code/foundry-model.tf b/infrastructure/infrastructure-setup-terraform/48-bring-own-model-private-ca/code/foundry-model.tf index 96924f430..a1d8762c9 100644 --- a/infrastructure/infrastructure-setup-terraform/48-bring-own-model-private-ca/code/foundry-model.tf +++ b/infrastructure/infrastructure-setup-terraform/48-bring-own-model-private-ca/code/foundry-model.tf @@ -10,7 +10,7 @@ resource "azapi_resource" "foundry_model_account" { type = "Microsoft.CognitiveServices/accounts@2025-04-01-preview" name = local.foundry_model_account_name - location = var.location + location = coalesce(var.foundry_location, local.create_rg ? azurerm_resource_group.rg[0].location : data.azurerm_resource_group.existing[0].location) parent_id = local.rg_id tags = local.common_tags diff --git a/infrastructure/infrastructure-setup-terraform/48-bring-own-model-private-ca/code/project.tf b/infrastructure/infrastructure-setup-terraform/48-bring-own-model-private-ca/code/project.tf index 1dee9fb8e..a61c73415 100644 --- a/infrastructure/infrastructure-setup-terraform/48-bring-own-model-private-ca/code/project.tf +++ b/infrastructure/infrastructure-setup-terraform/48-bring-own-model-private-ca/code/project.tf @@ -8,7 +8,7 @@ resource "azapi_resource" "project" { type = "Microsoft.CognitiveServices/accounts/projects@2025-04-01-preview" name = "${var.name_prefix}-project" - location = var.location + location = azapi_resource.foundry_agent_account.location parent_id = azapi_resource.foundry_agent_account.id tags = local.common_tags diff --git a/infrastructure/infrastructure-setup-terraform/48-bring-own-model-private-ca/code/terraform.tfvars.example b/infrastructure/infrastructure-setup-terraform/48-bring-own-model-private-ca/code/terraform.tfvars.example index a70b770e6..e0b8465e2 100644 --- a/infrastructure/infrastructure-setup-terraform/48-bring-own-model-private-ca/code/terraform.tfvars.example +++ b/infrastructure/infrastructure-setup-terraform/48-bring-own-model-private-ca/code/terraform.tfvars.example @@ -11,7 +11,7 @@ apim_publisher_email = "admin@contoso.example" # existing_resource_group_name = "" # reuse a group without managing its lifecycle # foundry_allowed_ip_ranges = [] # your client egress IP(s) to reach Foundry for testing # foundry_public_network_access_enabled = false # open Foundry to all networks (prefer the IP list) -# location = "eastus2" # avoid uksouth (trustedCertificates bug) +# location = "swedencentral" # avoid uksouth (trustedCertificates bug) # name_prefix = "byomca" # foundry_model_name = "gpt-4.1" # pick a model offered in your region # foundry_model_version = "2025-04-14" diff --git a/infrastructure/infrastructure-setup-terraform/48-bring-own-model-private-ca/code/variables.tf b/infrastructure/infrastructure-setup-terraform/48-bring-own-model-private-ca/code/variables.tf index 9e48da470..0c2a87e1b 100644 --- a/infrastructure/infrastructure-setup-terraform/48-bring-own-model-private-ca/code/variables.tf +++ b/infrastructure/infrastructure-setup-terraform/48-bring-own-model-private-ca/code/variables.tf @@ -1,3 +1,20 @@ +variable "foundry_location" { + description = "Optional Foundry account location override. Defaults to the resource-group location." + type = string + default = null + + validation { + condition = var.foundry_location == null ? true : contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.foundry_location) + error_message = "The location must be a supported Microsoft Foundry region." + } +} + # ============================================================================ # Subscription, tenant, location # ============================================================================ @@ -13,9 +30,20 @@ variable "tenant_id" { } variable "location" { - description = "Azure region for all resources. Avoid uksouth for this sample: the account trustedCertificates property has a known silent-discard bug there. eastus2 and swedencentral are validated." - type = string - default = "eastus2" + description = "Azure region for all resources. Avoid uksouth for this sample: the account trustedCertificates property has a known silent-discard bug there." + type = string + default = "swedencentral" + + validation { + condition = contains([ + "australiaeast", "brazilsouth", "canadacentral", "canadaeast", "centralindia", "centralus", + "eastasia", "eastus", "francecentral", "germanywestcentral", "italynorth", "japaneast", + "koreacentral", "northcentralus", "northeurope", "norwayeast", "qatarcentral", "southafricanorth", + "southcentralus", "southindia", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", + "uaenorth", "uksouth", "usgovarizona", "usgovvirginia", "westeurope", "westus", "westus3", + ], var.location) + error_message = "The location must be a supported Microsoft Foundry region." + } } variable "existing_resource_group_name" {