Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,7 @@ jobs:
- name: 'Using test file [${{ matrix.moduleTestFilePaths }}]'
uses: ./.github/actions/templates/validateModuleDeployment
with:
templateFilePath: '${{ env.modulePath }}/deploy.bicep'
parameterFilePath: '${{ env.modulePath }}/${{ matrix.moduleTestFilePaths }}'
templateFilePath: '${{ env.modulePath }}/${{ matrix.moduleTestFilePaths }}'
location: '${{ env.location }}'
resourceGroupName: '${{ env.resourceGroupName }}'
subscriptionId: '${{ secrets.ARM_SUBSCRIPTION_ID }}'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
@description('Optional. The location to deploy to.')
param location string = resourceGroup().location

@description('Required. The name of the Virtual Network to create.')
param virtualNetworkName string

@description('Required. The name of the Key Vault to create.')
param keyVaultName string

@description('Required. The name of the Managed Identity to create.')
param managedIdentityName string

@description('Required. The name of the Application Insights instance to create.')
param applicationInsightsName string

@description('Required. The name of the Storage Account to create.')
param storageAccountName string

resource virtualNetwork 'Microsoft.Network/virtualNetworks@2022-01-01' = {
name: virtualNetworkName
location: location
properties: {
addressSpace: {
addressPrefixes: [
'10.0.0.0/24'
]
}
subnets: [
{
name: 'defaultSubnet'
properties: {
addressPrefix: '10.0.0.0/24'
}
}
]
}
}

resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = {
name: keyVaultName
location: location
properties: {
sku: {
family: 'A'
name: 'standard'
}
tenantId: tenant().tenantId
enablePurgeProtection: null
enabledForTemplateDeployment: true
enabledForDiskEncryption: true
enabledForDeployment: true
enableRbacAuthorization: true
accessPolicies: []
}
}

resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = {
name: managedIdentityName
location: location
}

resource keyVaultServicePermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid('msi-${keyVault.id}-${location}-${managedIdentity.id}-KeyVault-Contributor-RoleAssignment')
scope: keyVault
properties: {
principalId: managedIdentity.properties.principalId
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor
principalType: 'ServicePrincipal'
}
}
resource keyVaultDataPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid('msi-${keyVault.id}-${location}-${managedIdentity.id}-KeyVault-Data-Admin-RoleAssignment')
scope: keyVault
properties: {
principalId: managedIdentity.properties.principalId
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00482a5a-887f-4fb3-b363-3b7fe8e74483') // Key Vault Administrator
principalType: 'ServicePrincipal'
}
}

resource applicationInsights 'Microsoft.Insights/components@2020-02-02' = {
name: applicationInsightsName
location: location
kind: ''
properties: {}
}

resource storageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' = {
name: storageAccountName
location: location
sku: {
name: 'Standard_LRS'
}
kind: 'StorageV2'
}

resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = {
name: 'privatelink.api.azureml.ms'
location: 'global'

resource virtualNetworkLinks 'virtualNetworkLinks@2020-06-01' = {
name: '${virtualNetwork.name}-vnetlink'
location: 'global'
properties: {
virtualNetwork: {
id: virtualNetwork.id
}
registrationEnabled: false
}
}
}

@description('The resource ID of the created Virtual Network Subnet.')
output subnetResourceId string = virtualNetwork.properties.subnets[0].id

@description('The resource ID of the created Key Vault.')
output keyVaultResourceId string = keyVault.id

@description('The principal ID of the created Managed Identity.')
output managedIdentityPrincipalId string = managedIdentity.properties.principalId

@description('The resource ID of the created Managed Identity.')
output managedIdentityResourceId string = managedIdentity.id

@description('The resource ID of the created Application Insights instance.')
output applicationInsightsResourceId string = applicationInsights.id

@description('The resource ID of the created Storage Account.')
output storageAccountResourceId string = storageAccount.id

@description('The resource ID of the created Private DNS Zone.')
output privateDNSZoneResourceId string = privateDNSZone.id
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
targetScope = 'subscription'

// ========== //
// Parameters //
// ========== //
@description('Optional. The name of the resource group to deploy for testing purposes.')
@maxLength(90)
param resourceGroupName string = 'ms.machinelearningservices.workspaces-${serviceShort}-rg'

@description('Optional. The location to deploy resources to.')
param location string = deployment().location

@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.')
param serviceShort string = 'mlswcom'

// =========== //
// Deployments //
// =========== //

// General resources
// =================
resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = {
name: resourceGroupName
location: location
}

module resourceGroupResources 'dependencies.bicep' = {
scope: resourceGroup
name: '${uniqueString(deployment().name, location)}-paramNested'
params: {
virtualNetworkName: 'dep-<<namePrefix>>-vnet-${serviceShort}'
managedIdentityName: 'dep-<<namePrefix>>-msi-${serviceShort}'
keyVaultName: 'dep-<<namePrefix>>-kv-${serviceShort}'
applicationInsightsName: 'dep-<<namePrefix>>-appi-${serviceShort}'
storageAccountName: 'dep<<namePrefix>>st${serviceShort}'
}
}

// Diagnostics
// ===========
module diagnosticDependencies '../../../../.shared/dependencyConstructs/diagnostic.dependencies.bicep' = {
scope: resourceGroup
name: '${uniqueString(deployment().name, location)}-diagnosticDependencies'
params: {
storageAccountName: 'dep<<namePrefix>>diasa${serviceShort}01'
logAnalyticsWorkspaceName: 'dep-<<namePrefix>>-law-${serviceShort}'
eventHubNamespaceEventHubName: 'dep-<<namePrefix>>-evh-${serviceShort}'
eventHubNamespaceName: 'dep-<<namePrefix>>-evhns-${serviceShort}'
location: location
}
}

// ============== //
// Test Execution //
// ============== //

module testDeployment '../../deploy.bicep' = {
scope: resourceGroup
name: '${uniqueString(deployment().name)}-test-${serviceShort}'
params: {
name: '<<namePrefix>>${serviceShort}001'
associatedApplicationInsightsResourceId: resourceGroupResources.outputs.applicationInsightsResourceId
associatedKeyVaultResourceId: resourceGroupResources.outputs.keyVaultResourceId
associatedStorageAccountResourceId: resourceGroupResources.outputs.storageAccountResourceId
sku: 'Basic'
computes: [
{
computeLocation: 'westeurope'
computeType: 'AmlCompute'
description: 'Default CPU Cluster'
disableLocalAuth: false
location: 'westeurope'
name: 'DefaultCPU'
properties: {
enableNodePublicIp: true
isolatedNetwork: false
osType: 'Linux'
remoteLoginPortPublicAccess: 'Disabled'
scaleSettings: {
maxNodeCount: 3
minNodeCount: 0
nodeIdleTimeBeforeScaleDown: 'PT5M'
}
vmPriority: 'Dedicated'
vmSize: 'STANDARD_DS11_V2'
}
sku: 'Basic'
// Must be false if `primaryUserAssignedIdentity` is provided
systemAssignedIdentity: false
userAssignedIdentities: {
'${resourceGroupResources.outputs.managedIdentityResourceId}': {}
}
}
]
description: 'The cake is a lie.'
diagnosticLogsRetentionInDays: 7
diagnosticStorageAccountId: diagnosticDependencies.outputs.storageAccountResourceId
diagnosticWorkspaceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId
diagnosticEventHubAuthorizationRuleId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId
diagnosticEventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName
discoveryUrl: 'http://example.com'
imageBuildCompute: 'testcompute'
lock: 'CanNotDelete'
primaryUserAssignedIdentity: resourceGroupResources.outputs.managedIdentityResourceId
privateEndpoints: [
{
service: 'amlworkspace'
subnetResourceId: resourceGroupResources.outputs.subnetResourceId
privateDnsZoneGroup: {
privateDNSResourceIds: [
resourceGroupResources.outputs.privateDNSZoneResourceId
]
}
}
]
roleAssignments: [
{
principalIds: [
resourceGroupResources.outputs.managedIdentityPrincipalId
]
roleDefinitionIdOrName: 'Reader'
}
]
systemAssignedIdentity: false
userAssignedIdentities: {
'${resourceGroupResources.outputs.managedIdentityResourceId}': {}
}
}
}

This file was deleted.

Loading