Skip to content

Commit 35ce6e9

Browse files
provision key vault and use apikey for ai search
1 parent b4db122 commit 35ce6e9

File tree

5 files changed

+143
-5
lines changed

5 files changed

+143
-5
lines changed

azure.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ metadata:
55
requiredVersions:
66
azd: ">=1.15.0 !=1.17.1"
77
hooks:
8-
postprovision:
8+
postdeploy:
99
windows:
1010
run: |
1111
Write-Host "To upload Team Configurations to Cosmos. Run the following command in PowerShell:"

azure_custom.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ services:
4141
continueOnError: false
4242

4343
hooks:
44-
postprovision:
44+
postdeploy:
4545
windows:
4646
run: |
4747
Write-Host "To upload Team Configurations to Cosmos. Run the following command in PowerShell:"

infra/main.bicep

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -919,13 +919,15 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:0.17.0' = if (e
919919
}
920920

921921
// ========== Private DNS Zones ========== //
922+
var keyVaultPrivateDNSZone = 'privatelink.${toLower(environment().name) == 'azureusgovernment' ? 'vaultcore.usgovcloudapi.net' : 'vaultcore.azure.net'}'
922923
var privateDnsZones = [
923924
'privatelink.cognitiveservices.azure.com'
924925
'privatelink.openai.azure.com'
925926
'privatelink.services.ai.azure.com'
926927
'privatelink.documents.azure.com'
927928
'privatelink.blob.core.windows.net'
928929
'privatelink.search.windows.net'
930+
keyVaultPrivateDNSZone
929931
]
930932

931933
// DNS Zone Index Constants
@@ -936,6 +938,7 @@ var dnsZoneIndex = {
936938
cosmosDb: 3
937939
blob: 4
938940
search: 5
941+
keyVault: 6
939942
}
940943

941944
// List of DNS zone indices that correspond to AI-related services.
@@ -1483,7 +1486,7 @@ module containerApp 'br/public:avm/res/app/container-app:0.18.1' = {
14831486
}
14841487
{
14851488
name: 'AZURE_AI_SEARCH_API_KEY'
1486-
value: ''
1489+
secretRef: 'azure-ai-search-api-key'
14871490
}
14881491
{
14891492
name: 'BING_CONNECTION_NAME'
@@ -1498,6 +1501,14 @@ module containerApp 'br/public:avm/res/app/container-app:0.18.1' = {
14981501
value: storageContainerName
14991502
}
15001503
]
1504+
1505+
}
1506+
]
1507+
secrets: [
1508+
{
1509+
name: 'azure-ai-search-api-key'
1510+
keyVaultUrl: keyvault.outputs.secrets[0].uriWithVersion
1511+
identity: userAssignedIdentity.outputs.resourceId
15011512
}
15021513
]
15031514
}
@@ -1838,13 +1849,68 @@ module aiSearchFoundryConnection 'modules/aifp-connections.bicep' = {
18381849
searchServiceResourceId: searchService.outputs.resourceId
18391850
searchServiceLocation: searchService.outputs.location
18401851
searchServiceName: searchService.outputs.name
1852+
searchApiKey: searchService.outputs.primaryKey
18411853
}
18421854
dependsOn: [
18431855
aiFoundryAiServices
18441856
]
18451857
}
18461858

18471859

1860+
// ========== KeyVault ========== //
1861+
var keyVaultName = 'kv-${solutionSuffix}'
1862+
module keyvault 'br/public:avm/res/key-vault/vault:0.12.1' = {
1863+
name: take('avm.res.key-vault.vault.${keyVaultName}', 64)
1864+
params: {
1865+
name: keyVaultName
1866+
location: location
1867+
tags: tags
1868+
sku: enableScalability ? 'premium' : 'standard'
1869+
publicNetworkAccess: enablePrivateNetworking ? 'Disabled' : 'Enabled'
1870+
networkAcls: {
1871+
defaultAction: 'Allow'
1872+
}
1873+
enableVaultForDeployment: true
1874+
enableVaultForDiskEncryption: true
1875+
enableVaultForTemplateDeployment: true
1876+
enableRbacAuthorization: true
1877+
enableSoftDelete: true
1878+
softDeleteRetentionInDays: 7
1879+
diagnosticSettings: enableMonitoring
1880+
? [{ workspaceResourceId: logAnalyticsWorkspace!.outputs.resourceId }]
1881+
: []
1882+
// WAF aligned configuration for Private Networking
1883+
privateEndpoints: enablePrivateNetworking
1884+
? [
1885+
{
1886+
name: 'pep-${keyVaultName}'
1887+
customNetworkInterfaceName: 'nic-${keyVaultName}'
1888+
privateDnsZoneGroup: {
1889+
privateDnsZoneGroupConfigs: [{ privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.keyVault]!.outputs.resourceId }]
1890+
}
1891+
service: 'vault'
1892+
subnetResourceId: virtualNetwork!.outputs.subnetResourceIds[0]
1893+
}
1894+
]
1895+
: []
1896+
// WAF aligned configuration for Role-based Access Control
1897+
roleAssignments: [
1898+
{
1899+
principalId: userAssignedIdentity.outputs.principalId
1900+
principalType: 'ServicePrincipal'
1901+
roleDefinitionIdOrName: 'Key Vault Administrator'
1902+
}
1903+
]
1904+
secrets: [
1905+
{
1906+
name: 'AzureAISearchAPIKey'
1907+
value: searchService.outputs.primaryKey
1908+
}
1909+
]
1910+
enableTelemetry: enableTelemetry
1911+
}
1912+
}
1913+
18481914
// ============ //
18491915
// Outputs //
18501916
// ============ //
@@ -1890,3 +1956,4 @@ output REASONING_MODEL_NAME string = 'o3'
18901956
output MCP_SERVER_NAME string = 'MACAE MCP Server'
18911957
output MCP_SERVER_DESCRIPTION string = 'MACAE MCP Server Description'
18921958
output SUPPORTED_MODELS string = '["o3","o4-mini","gpt-4.1","gpt-4.1-mini"]'
1959+
output AZURE_AI_SEARCH_API_KEY string = '<Deployed-Search-ApiKey>'

infra/main_custom.bicep

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -919,13 +919,15 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:0.17.0' = if (e
919919
}
920920

921921
// ========== Private DNS Zones ========== //
922+
var keyVaultPrivateDNSZone = 'privatelink.${toLower(environment().name) == 'azureusgovernment' ? 'vaultcore.usgovcloudapi.net' : 'vaultcore.azure.net'}'
922923
var privateDnsZones = [
923924
'privatelink.cognitiveservices.azure.com'
924925
'privatelink.openai.azure.com'
925926
'privatelink.services.ai.azure.com'
926927
'privatelink.documents.azure.com'
927928
'privatelink.blob.core.windows.net'
928929
'privatelink.search.windows.net'
930+
keyVaultPrivateDNSZone
929931
]
930932

931933
// DNS Zone Index Constants
@@ -936,6 +938,7 @@ var dnsZoneIndex = {
936938
cosmosDb: 3
937939
blob: 4
938940
search: 5
941+
keyVault: 6
939942
}
940943

941944
// List of DNS zone indices that correspond to AI-related services.
@@ -1516,7 +1519,7 @@ module containerApp 'br/public:avm/res/app/container-app:0.18.1' = {
15161519
}
15171520
{
15181521
name: 'AZURE_AI_SEARCH_API_KEY'
1519-
value: ''
1522+
value: 'azure-ai-search-api-key'
15201523
}
15211524
{
15221525
name: 'BING_CONNECTION_NAME'
@@ -1533,6 +1536,13 @@ module containerApp 'br/public:avm/res/app/container-app:0.18.1' = {
15331536
]
15341537
}
15351538
]
1539+
secrets: [
1540+
{
1541+
name: 'azure-ai-search-api-key'
1542+
keyVaultUrl: keyvault.outputs.secrets[0].uriWithVersion
1543+
identity: userAssignedIdentity.outputs.resourceId
1544+
}
1545+
]
15361546
}
15371547
}
15381548

@@ -1880,13 +1890,68 @@ module aiSearchFoundryConnection 'modules/aifp-connections.bicep' = {
18801890
searchServiceResourceId: searchService.outputs.resourceId
18811891
searchServiceLocation: searchService.outputs.location
18821892
searchServiceName: searchService.outputs.name
1893+
searchApiKey: searchService.outputs.primaryKey
18831894
}
18841895
dependsOn: [
18851896
aiFoundryAiServices
18861897
]
18871898
}
18881899

18891900

1901+
// ========== KeyVault ========== //
1902+
var keyVaultName = 'kv-${solutionSuffix}'
1903+
module keyvault 'br/public:avm/res/key-vault/vault:0.12.1' = {
1904+
name: take('avm.res.key-vault.vault.${keyVaultName}', 64)
1905+
params: {
1906+
name: keyVaultName
1907+
location: location
1908+
tags: tags
1909+
sku: enableScalability ? 'premium' : 'standard'
1910+
publicNetworkAccess: enablePrivateNetworking ? 'Disabled' : 'Enabled'
1911+
networkAcls: {
1912+
defaultAction: 'Allow'
1913+
}
1914+
enableVaultForDeployment: true
1915+
enableVaultForDiskEncryption: true
1916+
enableVaultForTemplateDeployment: true
1917+
enableRbacAuthorization: true
1918+
enableSoftDelete: true
1919+
softDeleteRetentionInDays: 7
1920+
diagnosticSettings: enableMonitoring
1921+
? [{ workspaceResourceId: logAnalyticsWorkspace!.outputs.resourceId }]
1922+
: []
1923+
// WAF aligned configuration for Private Networking
1924+
privateEndpoints: enablePrivateNetworking
1925+
? [
1926+
{
1927+
name: 'pep-${keyVaultName}'
1928+
customNetworkInterfaceName: 'nic-${keyVaultName}'
1929+
privateDnsZoneGroup: {
1930+
privateDnsZoneGroupConfigs: [{ privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.keyVault]!.outputs.resourceId }]
1931+
}
1932+
service: 'vault'
1933+
subnetResourceId: virtualNetwork!.outputs.subnetResourceIds[0]
1934+
}
1935+
]
1936+
: []
1937+
// WAF aligned configuration for Role-based Access Control
1938+
roleAssignments: [
1939+
{
1940+
principalId: userAssignedIdentity.outputs.principalId
1941+
principalType: 'ServicePrincipal'
1942+
roleDefinitionIdOrName: 'Key Vault Administrator'
1943+
}
1944+
]
1945+
secrets: [
1946+
{
1947+
name: 'AzureAISearchAPIKey'
1948+
value: searchService.outputs.primaryKey
1949+
}
1950+
]
1951+
enableTelemetry: enableTelemetry
1952+
}
1953+
}
1954+
18901955
// ============ //
18911956
// Outputs //
18921957
// ============ //
@@ -1948,3 +2013,4 @@ output REASONING_MODEL_NAME string = 'o3'
19482013
output MCP_SERVER_NAME string = 'MACAE MCP Server'
19492014
output MCP_SERVER_DESCRIPTION string = 'MACAE MCP Server Description'
19502015
output SUPPORTED_MODELS string = '["o3","o4-mini","gpt-4.1","gpt-4.1-mini"]'
2016+
output AZURE_AI_SEARCH_API_KEY string = '<Deployed-Search-ApiKey>'

infra/modules/aifp-connections.bicep

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,18 @@ param searchServiceResourceId string
44
param searchServiceLocation string
55
param aiFoundryName string
66
param aiFoundryProjectName string
7+
@secure()
8+
param searchApiKey string
79

810
resource aiSearchFoundryConnection 'Microsoft.CognitiveServices/accounts/projects/connections@2025-04-01-preview' = {
911
name: '${aiFoundryName}/${aiFoundryProjectName}/${aifSearchConnectionName}'
1012
properties: {
1113
category: 'CognitiveSearch'
1214
target: 'https://${searchServiceName}.search.windows.net'
13-
authType: 'AAD'
15+
authType: 'ApiKey'
16+
credentials: {
17+
key: searchApiKey
18+
}
1419
isSharedToAll: true
1520
metadata: {
1621
ApiType: 'Azure'

0 commit comments

Comments
 (0)