Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 4 additions & 7 deletions modules/sql/managed-instance/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"_generator": {
"name": "bicep",
"version": "0.22.6.54827",
"templateHash": "7571236887873003427"
"templateHash": "7653568276267549552"
},
"name": "SQL Managed Instances",
"description": "This module deploys a SQL Managed Instance.",
Expand Down Expand Up @@ -1433,7 +1433,7 @@
"_generator": {
"name": "bicep",
"version": "0.22.6.54827",
"templateHash": "16419324698366777740"
"templateHash": "5582620280313265167"
},
"name": "SQL Managed Instance Vulnerability Assessments",
"description": "This module deploys a SQL Managed Instance Vulnerability Assessment.",
Expand Down Expand Up @@ -1501,9 +1501,6 @@
}
}
},
"variables": {
"splitStorageAccountResourceId": "[split(parameters('storageAccountResourceId'), '/')]"
},
"resources": [
{
"condition": "[parameters('enableDefaultTelemetry')]",
Expand Down Expand Up @@ -1538,15 +1535,15 @@
"type": "Microsoft.Resources/deployments",
"apiVersion": "2022-09-01",
"name": "[format('{0}-sbdc-rbac', parameters('managedInstanceName'))]",
"resourceGroup": "[variables('splitStorageAccountResourceId')[4]]",
"resourceGroup": "[split(parameters('storageAccountResourceId'), '/')[4]]",
"properties": {
"expressionEvaluationOptions": {
"scope": "inner"
},
"mode": "Incremental",
"parameters": {
"storageAccountName": {
"value": "[last(variables('splitStorageAccountResourceId'))]"
"value": "[last(split(parameters('storageAccountResourceId'), '/'))]"
},
"managedInstanceIdentityPrincipalId": {
"value": "[reference(resourceId('Microsoft.Sql/managedInstances', parameters('managedInstanceName')), '2022-05-01-preview', 'full').identity.principalId]"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ param createStorageRoleAssignment bool = true
@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).')
param enableDefaultTelemetry bool = true

var splitStorageAccountResourceId = split(storageAccountResourceId, '/')

resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (enableDefaultTelemetry) {
name: 'pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-${uniqueString(deployment().name)}'
properties: {
Expand All @@ -48,11 +46,11 @@ resource managedInstance 'Microsoft.Sql/managedInstances@2022-05-01-preview' exi
}

// Assign SQL MI MSI access to storage account
module storageAccount_sbdc_rbac '.bicep/nested_storageRoleAssignment.bicep' = if (!useStorageAccountAccessKey && createStorageRoleAssignment) {
module storageAccount_sbdc_rbac 'modules/nested_storageRoleAssignment.bicep' = if (!useStorageAccountAccessKey && createStorageRoleAssignment) {
name: '${managedInstance.name}-sbdc-rbac'
scope: resourceGroup(splitStorageAccountResourceId[4])
scope: resourceGroup(split(storageAccountResourceId, '/')[4])
params: {
storageAccountName: last(splitStorageAccountResourceId)
storageAccountName: last(split(storageAccountResourceId, '/'))
managedInstanceIdentityPrincipalId: managedInstance.identity.principalId
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"_generator": {
"name": "bicep",
"version": "0.22.6.54827",
"templateHash": "16419324698366777740"
"templateHash": "5582620280313265167"
},
"name": "SQL Managed Instance Vulnerability Assessments",
"description": "This module deploys a SQL Managed Instance Vulnerability Assessment.",
Expand Down Expand Up @@ -73,9 +73,6 @@
}
}
},
"variables": {
"splitStorageAccountResourceId": "[split(parameters('storageAccountResourceId'), '/')]"
},
"resources": [
{
"condition": "[parameters('enableDefaultTelemetry')]",
Expand Down Expand Up @@ -110,15 +107,15 @@
"type": "Microsoft.Resources/deployments",
"apiVersion": "2022-09-01",
"name": "[format('{0}-sbdc-rbac', parameters('managedInstanceName'))]",
"resourceGroup": "[variables('splitStorageAccountResourceId')[4]]",
"resourceGroup": "[split(parameters('storageAccountResourceId'), '/')[4]]",
"properties": {
"expressionEvaluationOptions": {
"scope": "inner"
},
"mode": "Incremental",
"parameters": {
"storageAccountName": {
"value": "[last(variables('splitStorageAccountResourceId'))]"
"value": "[last(split(parameters('storageAccountResourceId'), '/'))]"
},
"managedInstanceIdentityPrincipalId": {
"value": "[reference(resourceId('Microsoft.Sql/managedInstances', parameters('managedInstanceName')), '2022-05-01-preview', 'full').identity.principalId]"
Expand Down
35 changes: 35 additions & 0 deletions modules/sql/server/.test/vulnAssm/dependencies.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
@description('Required. The name of the Managed Identity to create.')
param managedIdentityName string

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

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

resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: managedIdentityName
location: location
}

resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {
name: storageAccountName
location: location
sku: {
name: 'Standard_LRS'
}
kind: 'StorageV2'
properties: {
allowBlobPublicAccess: false
networkAcls: {
defaultAction: 'Deny'
bypass: 'AzureServices'
}
}
}

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

@description('The resource ID of the created Storage Account.')
output storageAccountResourceId string = storageAccount.id
91 changes: 91 additions & 0 deletions modules/sql/server/.test/vulnAssm/main.test.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
targetScope = 'subscription'

// ========== //
// Parameters //
// ========== //

@description('Optional. The name of the resource group to deploy for testing purposes.')
@maxLength(90)
param resourceGroupName string = 'dep-${namePrefix}-sql.servers-${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 = 'sqlsvln'

@description('Optional. The password to leverage for the login.')
@secure()
param password string = newGuid()

@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).')
param enableDefaultTelemetry bool = true

@description('Optional. A token to inject into the name of each resource.')
param namePrefix string = '[[namePrefix]]'

// ============ //
// Dependencies //
// ============ //

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

module nestedDependencies 'dependencies.bicep' = {
scope: resourceGroup
name: '${uniqueString(deployment().name, location)}-nestedDependencies'
params: {
managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}'
storageAccountName: 'dep${namePrefix}cdnstore${serviceShort}'
location: location
}
}

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

module testDeployment '../../main.bicep' = {
scope: resourceGroup
name: '${uniqueString(deployment().name, location)}-test-${serviceShort}'
params: {
enableDefaultTelemetry: enableDefaultTelemetry
name: '${namePrefix}-${serviceShort}'
primaryUserAssignedIdentityId: nestedDependencies.outputs.managedIdentityResourceId
administratorLogin: 'adminUserName'
administratorLoginPassword: password
location: location
vulnerabilityAssessmentsObj: {
emailSubscriptionAdmins: true
name: 'default'
recurringScansEmails: [
'test1@contoso.com'
'test2@contoso.com'
]
recurringScansIsEnabled: true
storageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId
useStorageAccountAccessKey: false
createStorageRoleAssignment: true
}
securityAlertPolicies: [
{
name: 'Default'
state: 'Enabled'
emailAccountAdmins: true
}
]
systemAssignedIdentity: true
userAssignedIdentities: {
'${nestedDependencies.outputs.managedIdentityResourceId}': {}
}
tags: {
'hidden-title': 'This is visible in the resource name'
Environment: 'Non-Prod'
Role: 'DeploymentValidation'
}
}
}
128 changes: 128 additions & 0 deletions modules/sql/server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ The following section provides usage examples for the module, which were used to
- [Using large parameter set](#example-2-using-large-parameter-set)
- [Pe](#example-3-pe)
- [Secondary](#example-4-secondary)
- [Vulnassm](#example-5-vulnassm)

### Example 1: _Admin_

Expand Down Expand Up @@ -592,6 +593,133 @@ module server 'br:bicep/modules/sql.server:1.0.0' = {
</details>
<p>

### Example 5: _Vulnassm_

<details>

<summary>via Bicep module</summary>

```bicep
module server 'br:bicep/modules/sql.server:1.0.0' = {
name: '${uniqueString(deployment().name, location)}-test-sqlsvln'
params: {
// Required parameters
name: 'sqlsvln'
// Non-required parameters
administratorLogin: 'adminUserName'
administratorLoginPassword: '<administratorLoginPassword>'
enableDefaultTelemetry: '<enableDefaultTelemetry>'
location: '<location>'
primaryUserAssignedIdentityId: '<primaryUserAssignedIdentityId>'
securityAlertPolicies: [
{
emailAccountAdmins: true
name: 'Default'
state: 'Enabled'
}
]
systemAssignedIdentity: true
tags: {
Environment: 'Non-Prod'
'hidden-title': 'This is visible in the resource name'
Role: 'DeploymentValidation'
}
userAssignedIdentities: {
'<managedIdentityResourceId>': {}
}
vulnerabilityAssessmentsObj: {
createStorageRoleAssignment: true
emailSubscriptionAdmins: true
name: 'default'
recurringScansEmails: [
'test1@contoso.com'
'test2@contoso.com'
]
recurringScansIsEnabled: true
storageAccountResourceId: '<storageAccountResourceId>'
useStorageAccountAccessKey: false
}
}
}
```

</details>
<p>

<details>

<summary>via JSON Parameter file</summary>

```json
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
// Required parameters
"name": {
"value": "sqlsvln"
},
// Non-required parameters
"administratorLogin": {
"value": "adminUserName"
},
"administratorLoginPassword": {
"value": "<administratorLoginPassword>"
},
"enableDefaultTelemetry": {
"value": "<enableDefaultTelemetry>"
},
"location": {
"value": "<location>"
},
"primaryUserAssignedIdentityId": {
"value": "<primaryUserAssignedIdentityId>"
},
"securityAlertPolicies": {
"value": [
{
"emailAccountAdmins": true,
"name": "Default",
"state": "Enabled"
}
]
},
"systemAssignedIdentity": {
"value": true
},
"tags": {
"value": {
"Environment": "Non-Prod",
"hidden-title": "This is visible in the resource name",
"Role": "DeploymentValidation"
}
},
"userAssignedIdentities": {
"value": {
"<managedIdentityResourceId>": {}
}
},
"vulnerabilityAssessmentsObj": {
"value": {
"createStorageRoleAssignment": true,
"emailSubscriptionAdmins": true,
"name": "default",
"recurringScansEmails": [
"test1@contoso.com",
"test2@contoso.com"
],
"recurringScansIsEnabled": true,
"storageAccountResourceId": "<storageAccountResourceId>",
"useStorageAccountAccessKey": false
}
}
}
}
```

</details>
<p>


## Parameters

Expand Down
4 changes: 3 additions & 1 deletion modules/sql/server/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,9 @@ module server_vulnerabilityAssessment 'vulnerability-assessment/main.bicep' = if
recurringScansEmails: contains(vulnerabilityAssessmentsObj, 'recurringScansEmails') ? vulnerabilityAssessmentsObj.recurringScansEmails : []
recurringScansEmailSubscriptionAdmins: contains(vulnerabilityAssessmentsObj, 'recurringScansEmailSubscriptionAdmins') ? vulnerabilityAssessmentsObj.recurringScansEmailSubscriptionAdmins : false
recurringScansIsEnabled: contains(vulnerabilityAssessmentsObj, 'recurringScansIsEnabled') ? vulnerabilityAssessmentsObj.recurringScansIsEnabled : false
storageAccountResourceId: contains(vulnerabilityAssessmentsObj, 'storageAccountResourceId') ? vulnerabilityAssessmentsObj.storageAccountResourceId : ''
storageAccountResourceId: vulnerabilityAssessmentsObj.storageAccountResourceId
useStorageAccountAccessKey: contains(vulnerabilityAssessmentsObj, 'useStorageAccountAccessKey') ? vulnerabilityAssessmentsObj.useStorageAccountAccessKey : false
createStorageRoleAssignment: contains(vulnerabilityAssessmentsObj, 'createStorageRoleAssignment') ? vulnerabilityAssessmentsObj.createStorageRoleAssignment : true
enableDefaultTelemetry: enableReferencedModulesTelemetry
}
dependsOn: [
Expand Down
Loading