Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Created keyvault bicep module #58

Merged
merged 96 commits into from
Sep 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
ecf082d
first draft
Sep 22, 2021
9c33a06
first end2end traft
Sep 22, 2021
b89c48c
Merge pull request #1 from MrMCake/users/alsehr/readMePipe
AlexanderSehr Sep 22, 2021
eed36cb
Minor update
Sep 22, 2021
dfef29d
Minor update
Sep 22, 2021
824fd68
Minor update
Sep 22, 2021
04a83d5
Minor update
Sep 22, 2021
9cdbbd1
Minor cleanup
Sep 22, 2021
d71a752
Minor cleanup
Sep 22, 2021
4552821
Minor cleanup
Sep 22, 2021
68afd99
Added version output
Sep 22, 2021
e31aa68
Added output
Sep 22, 2021
c8b89f7
Minor cleanup
Sep 22, 2021
5193495
Added output
Sep 22, 2021
061b6bd
Added output
Sep 22, 2021
99fffba
Added output
Sep 22, 2021
a36cf1a
Simplified logic
Sep 22, 2021
f6f6f15
Added output
Sep 23, 2021
549b231
Added output
Sep 23, 2021
1ace41f
Added output + refactoring
Sep 23, 2021
32324f9
Added output
Sep 23, 2021
6237c3c
Added output
Sep 23, 2021
58bd9d3
Added replacement
Sep 23, 2021
f4068f7
Added replacement v2
Sep 23, 2021
17b66c1
Cleanup
Sep 23, 2021
c751783
Reset trigger
Sep 23, 2021
d70c060
Added output
Sep 23, 2021
ddee0df
Fixed typo
Sep 23, 2021
05d6a46
Added todo.
Sep 23, 2021
fee5954
Merge pull request #2 from MrMCake/users/alsehr/readMePipe
AlexanderSehr Sep 23, 2021
f88ad87
Updated docs
Sep 23, 2021
3b14289
Merge branch 'Azure:main' into main
AlexanderSehr Sep 23, 2021
fbe5348
Added key vault bicep module & fixed minor storage account complains
Sep 23, 2021
ecb19b4
Replaced login with cred
Sep 23, 2021
8314fc8
Replaced cred ref
Sep 23, 2021
ffe9691
added missing func
Sep 23, 2021
648883c
Minor update
Sep 23, 2021
2bd2d1e
Pretest changes
Sep 23, 2021
56e8c2f
Updated remaining tests + extended api tests to exclude preview and a…
Sep 23, 2021
db04e68
Added template translation to test-deployment
Sep 23, 2021
53c8c4e
Temp add publish condition
Sep 24, 2021
6369c7c
Another try
Sep 24, 2021
fcace61
Another try
Sep 24, 2021
cd69596
Another try
Sep 24, 2021
d493a7a
Another try
Sep 24, 2021
77e912f
Undid temp changes
Sep 24, 2021
79f17f4
Merge branch 'Azure:main' into main
AlexanderSehr Sep 24, 2021
e0ea080
Merge branch 'Azure:main' into main
AlexanderSehr Sep 24, 2021
94d02fd
Merge branch 'main' into users/alsehr/bicepPipeline
Sep 24, 2021
b3425bd
Added workaround to acocunt for bicep compile issue [deployments api …
Sep 24, 2021
305e49a
Merge branch 'Azure:main' into main
AlexanderSehr Sep 24, 2021
09cb61f
Shifted bicep handling to native PS commands with bicep cli support +…
Sep 24, 2021
78dfe9f
Updated remaining pipelines to use creds object
Sep 24, 2021
76e80ae
Fixed schema eval
Sep 24, 2021
63d2804
Updated readme
Sep 24, 2021
734df4b
Temp remove arm templates to ensure it runs without
Sep 24, 2021
cc8311a
Updated removal jobs to bicep + added publish workaround to allow for…
Sep 24, 2021
8bdcc93
Minor updates
Sep 24, 2021
de80bf9
Further updates
Sep 24, 2021
ad84732
Further updates
Sep 24, 2021
a04883d
Restored templates
Sep 24, 2021
eaccb21
Merge latest deploy
Sep 24, 2021
063c7b7
Merge pull request #3 from MrMCake/users/alsehr/bicepPipeline
AlexanderSehr Sep 24, 2021
6e5dd28
Moved lock + rg bicep fix
Sep 24, 2021
29fe51c
Fixed path
Sep 24, 2021
cc7f2f3
Temp disabled template spec publish
Sep 24, 2021
4bb68e4
Undo after test
Sep 24, 2021
94a39b3
Aligned bicep templates rbac
Sep 25, 2021
1bf8013
Reduced roles for gallery
Sep 25, 2021
954dc33
Reduced role ref
Sep 25, 2021
c9c4336
Cleanup
Sep 25, 2021
8ae9a3c
Created vmss template
Sep 25, 2021
6104214
Adjusted api tests
Sep 25, 2021
cef5542
Added output
Sep 25, 2021
809a159
Switched ref for vmss to bicep
Sep 25, 2021
b1b5093
Updated param
Sep 25, 2021
6d35c79
Updated api
Sep 25, 2021
b86ec8f
Merged latest main
Sep 25, 2021
9a141e5
Adjusted output
Sep 25, 2021
95569dd
Updated error handling
Sep 25, 2021
a779c33
Updated output
Sep 25, 2021
8adfef9
Updated function input print
Sep 25, 2021
876a231
Finishing touches
Sep 25, 2021
b7e2c0d
Merge pull request #4 from MrMCake/users/alsehr/vmssTemplate
AlexanderSehr Sep 25, 2021
ae3f54b
Small update
Sep 25, 2021
e2e68ff
Fallback scale set to split PRs
Sep 25, 2021
818cf9a
Updated module name
Sep 25, 2021
d05ecc0
Cleanup
Sep 25, 2021
00d2410
Cleanupo
Sep 25, 2021
0206aa5
Cleanup
Sep 26, 2021
80d31a7
Update deploy.bicep
AlexanderSehr Sep 26, 2021
52098fe
Added sql server bicep
Sep 26, 2021
4b59b7c
Undo previous changes
Sep 26, 2021
de2265f
Merge branch 'Azure:main' into main
AlexanderSehr Sep 27, 2021
3c8b0d4
Merge branch 'main' into users/alsehr/bicep_keyvault
Sep 27, 2021
2b8ad04
Updated key vault
Sep 27, 2021
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
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
param privateEndpointResourceId string
param privateEndpointVnetLocation string
param privateEndpointDef object
param tags object

var privateEndpointResourceName = last(split(privateEndpointResourceId, '/'))
var privateEndpoint_var = {
name: (contains(privateEndpointDef, 'name') ? (empty(privateEndpointDef.name) ? '${privateEndpointResourceName}-${privateEndpointDef.service}' : privateEndpointDef.name) : '${privateEndpointResourceName}-${privateEndpointDef.service}')
subnetResourceId: privateEndpointDef.subnetResourceId
service: [
privateEndpointDef.service
]
privateDnsZoneResourceIds: (contains(privateEndpointDef, 'privateDnsZoneResourceIds') ? (empty(privateEndpointDef.privateDnsZoneResourceIds) ? [] : privateEndpointDef.privateDnsZoneResourceIds) : [])
customDnsConfigs: (contains(privateEndpointDef, 'customDnsConfigs') ? (empty(privateEndpointDef.customDnsConfigs) ? json('null') : privateEndpointDef.customDnsConfigs) : json('null'))
}

resource privateEndpoint 'Microsoft.Network/privateEndpoints@2020-05-01' = {
name: privateEndpoint_var.name
location: privateEndpointVnetLocation
tags: tags
properties: {
privateLinkServiceConnections: [
{
name: privateEndpoint_var.name
properties: {
privateLinkServiceId: privateEndpointResourceId
groupIds: privateEndpoint_var.service
}
}
]
manualPrivateLinkServiceConnections: []
subnet: {
id: privateEndpoint_var.subnetResourceId
}
customDnsConfigs: privateEndpoint_var.customDnsConfigs
}
}

resource privateEndpoint_default 'Microsoft.Network/privateEndpoints/privateDnsZoneGroups@2020-05-01' = if (!empty(privateEndpoint_var.privateDnsZoneResourceIds)) {
name: '${privateEndpoint_var.name}/default'
properties: {
privateDnsZoneConfigs: [for j in range(0, length(privateEndpoint_var.privateDnsZoneResourceIds)): {
name: last(split(privateEndpoint_var.privateDnsZoneResourceIds[j], '/'))
properties: {
privateDnsZoneId: privateEndpoint_var.privateDnsZoneResourceIds[j]
}
}]
}
dependsOn: [
privateEndpoint
]
}
13 changes: 13 additions & 0 deletions arm/Microsoft.KeyVault/vaults/.bicep/nested_rbac.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
param roleAssignment object
param builtInRoleNames object
param keyVaultName string


resource nested_rbac 'Microsoft.Storage/storageAccounts/providers/roleAssignments@2020-04-01-preview' = [for principalId in roleAssignment.principalIds: {
name: '${keyVaultName}/Microsoft.Authorization/${guid(keyVaultName, principalId, roleAssignment.roleDefinitionIdOrName)}'
properties: {
roleDefinitionId: (contains(builtInRoleNames, roleAssignment.roleDefinitionIdOrName) ? builtInRoleNames[roleAssignment.roleDefinitionIdOrName] : roleAssignment.roleDefinitionIdOrName)
principalId: principalId
}
dependsOn: []
}]
271 changes: 271 additions & 0 deletions arm/Microsoft.KeyVault/vaults/deploy.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,271 @@
@description('Optional. Name of the Key Vault. If no name is provided, then unique name will be created.')
@maxLength(24)
param keyVaultName string = ''

@description('Optional. Location for all resources.')
param location string = resourceGroup().location

@description('Optional. Array of access policies object')
param accessPolicies array = []

@description('Optional. All secrets [{"secretName":"","secretValue":""} wrapped in a secure object]')
@secure()
param secretsObject object = {
secrets: []
}

@description('Optional. All keys [{"keyName":"","keyType":"","keyOps":"","keySize":"","curvename":""} wrapped in a secure object]')
@secure()
param keysObject object = {
keys: []
}

@description('Optional. Specifies if the vault is enabled for deployment by script or compute')
@allowed([
true
false
])
param enableVaultForDeployment bool = true

@description('Optional. Specifies if the vault is enabled for a template deployment')
@allowed([
true
false
])
param enableVaultForTemplateDeployment bool = true

@description('Optional. Specifies if the azure platform has access to the vault for enabling disk encryption scenarios.')
@allowed([
true
false
])
param enableVaultForDiskEncryption bool = true

@description('Optional. Switch to enable/disable Key Vault\'s soft delete feature.')
param enableSoftDelete bool = true

@description('Optional. softDelete data retention days. It accepts >=7 and <=90.')
param softDeleteRetentionInDays int = 90

@description('Optional. Property that controls how data actions are authorized. When true, the key vault will use Role Based Access Control (RBAC) for authorization of data actions, and the access policies specified in vault properties will be ignored (warning: this is a preview feature). When false, the key vault will use the access policies specified in vault properties, and any policy stored on Azure Resource Manager will be ignored. If null or not specified, the vault is created with the default value of false. Note that management actions are always authorized with RBAC.')
param enableRbacAuthorization bool = false

@description('Optional. The vault\'s create mode to indicate whether the vault need to be recovered or not. - recover or default.')
param createMode string = 'default'

@description('Optional. Provide \'true\' to enable Key Vault\'s purge protection feature.')
param enablePurgeProtection bool = false

@description('Optional. Specifies the SKU for the vault')
@allowed([
'premium'
'standard'
])
param vaultSku string = 'premium'

@description('Optional. Service endpoint object information')
param networkAcls object = {}

@description('Optional. Virtual Network resource identifier, if networkAcls is passed, this value must be passed as well')
param vNetId string = ''

@description('Optional. The name of the Diagnostic setting.')
param diagnosticSettingName string = 'service'

@description('Optional. Specifies the number of days that logs will be kept for; a value of 0 will retain data indefinitely.')
@minValue(0)
@maxValue(365)
param diagnosticLogsRetentionInDays int = 365

@description('Optional. Resource identifier of the Diagnostic Storage Account.')
param diagnosticStorageAccountId string = ''

@description('Optional. Resource identifier of Log Analytics.')
param workspaceId string = ''

@description('Optional. Resource ID of the event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to.')
param eventHubAuthorizationRuleId string = ''

@description('Optional. Name of the event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category.')
param eventHubName string = ''

@description('Optional. Switch to lock Key Vault from deletion.')
param lockForDeletion bool = false

@description('Optional. Array of role assignment objects that contain the \'roleDefinitionIdOrName\' and \'principalId\' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'')
param roleAssignments array = []

@description('Optional. Configuration Details for private endpoints.')
param privateEndpoints array = []

@description('Optional. Resource tags.')
param tags object = {}

@description('Optional. Customer Usage Attribution id (GUID). This GUID must be previously registered')
param cuaId string = ''

@description('Generated. Do not provide a value! This date value is used to generate a SAS token to access the modules.')
param baseTime string = utcNow('u')

var maxNameLength = 24
var uniqueKeyVaultNameUntrim = uniqueString('Key Vault${baseTime}')
var uniqueKeyVaultName = ((length(uniqueKeyVaultNameUntrim) > maxNameLength) ? substring(uniqueKeyVaultNameUntrim, 0, maxNameLength) : uniqueKeyVaultNameUntrim)
var keyVaultName_var = (empty(keyVaultName) ? uniqueKeyVaultName : keyVaultName)
var virtualNetworkRules = [for networkrule in networkAcls.virtualNetworkRules: {
id: '${vNetId}/subnets/${networkrule.subnet}'
}]
var networkAcls_var = {
bypass: (empty(networkAcls) ? json('null') : networkAcls.bypass)
defaultAction: (empty(networkAcls) ? json('null') : networkAcls.defaultAction)
virtualNetworkRules: (empty(networkAcls) ? json('null') : virtualNetworkRules)
ipRules: (empty(networkAcls) ? json('null') : ((length(networkAcls.ipRules) == 0) ? [] : networkAcls.ipRules))
}
var diagnosticsMetrics = [
{
category: 'AllMetrics'
timeGrain: null
enabled: true
retentionPolicy: {
enabled: true
days: diagnosticLogsRetentionInDays
}
}
]
var diagnosticsLogs = [
{
category: 'AuditEvent'
enabled: true
retentionPolicy: {
enabled: true
days: diagnosticLogsRetentionInDays
}
}
]
var builtInRoleNames = {
Owner: '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635'
Contributor: '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c'
Reader: '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7'
'Key Vault Administrator (preview)': '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/00482a5a-887f-4fb3-b363-3b7fe8e74483'
'Key Vault Certificates Officer (preview)': '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/a4417e6f-fecd-4de8-b567-7b0420556985'
'Key Vault Contributor': '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/f25e0fa2-a7c8-4377-a976-54943a77a395'
'Key Vault Crypto Officer (preview)': '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/14b46e9e-c2b7-41b4-b07b-48a6ebf60603'
'Key Vault Crypto Service Encryption User (preview)': '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/e147488a-f6f5-4113-8e2d-b22465e65bf6'
'Key Vault Crypto User (preview)': '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/12338af0-0e69-4776-bea7-57ae8d297424'
'Key Vault Reader (preview)': '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/21090545-7ca7-4776-b22c-e363652d74d2'
'Key Vault Secrets Officer (preview)': '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/b86a8fe4-44ce-4948-aee5-eccb2c155cd7'
'Key Vault Secrets User (preview)': '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/4633458b-17de-408a-b874-0445c86b69e6'
'Log Analytics Contributor': '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/92aaf0da-9dab-42b6-94a3-d43ce8d16293'
'Log Analytics Reader': '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/73c42c96-874c-492b-b04d-ab87d138a893'
'Managed Application Contributor Role': '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/641177b8-a67a-45b9-a033-47bc880bb21e'
'Managed Application Operator Role': '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/c7393b34-138c-406f-901b-d8cf2b17e6ae'
'Managed Applications Reader': '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/b9331d33-8a36-4f8c-b097-4f54124fdb44'
'Monitoring Contributor': '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/749f88d5-cbae-40b8-bcfc-e573ddc772fa'
'Monitoring Metrics Publisher': '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/3913510d-42f4-4e42-8a64-420c390055eb'
'Monitoring Reader': '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/43d0d8ad-25c7-4714-9337-8ba259a9fe05'
'Resource Policy Contributor': '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/36243c78-bf99-498c-9df9-86d9f8d28608'
'User Access Administrator': '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/18d7d88d-d35e-4fb5-a5c3-7773c20a72d9'
'Azure Service Deploy Release Management Contributor': '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/21d96096-b162-414a-8302-d8354f9d91b2'
masterreader: '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/a48d7796-14b4-4889-afef-fbb65a93e5a2'
}

module pid_cuaId './.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) {
name: 'pid-${cuaId}'
params: {}
}

resource keyVault 'Microsoft.KeyVault/vaults@2019-09-01' = {
name: keyVaultName_var
location: location
tags: tags
properties: {
enabledForDeployment: enableVaultForDeployment
enabledForTemplateDeployment: enableVaultForTemplateDeployment
enabledForDiskEncryption: enableVaultForDiskEncryption
enableSoftDelete: enableSoftDelete
softDeleteRetentionInDays: softDeleteRetentionInDays
enableRbacAuthorization: enableRbacAuthorization
createMode: createMode
enablePurgeProtection: ((!enablePurgeProtection) ? json('null') : enablePurgeProtection)
tenantId: subscription().tenantId
accessPolicies: accessPolicies
sku: {
name: vaultSku
family: 'A'
}
networkAcls: (empty(networkAcls) ? json('null') : networkAcls_var)
}
}

resource keyVault_lock 'Microsoft.Authorization/locks@2016-09-01' = if (lockForDeletion) {
name: '${keyVaultName_var}-keyVaultDoNotDelete'
properties: {
level: 'CanNotDelete'
}
scope: keyVault
}

resource keyVault_diagnosticSettings 'Microsoft.Insights/diagnosticsettings@2017-05-01-preview' = if ((!empty(diagnosticStorageAccountId)) || (!empty(workspaceId)) || (!empty(eventHubAuthorizationRuleId)) || (!empty(eventHubName))) {
name: '${keyVaultName_var}-${diagnosticSettingName}'
properties: {
storageAccountId: (empty(diagnosticStorageAccountId) ? json('null') : diagnosticStorageAccountId)
workspaceId: (empty(workspaceId) ? json('null') : workspaceId)
eventHubAuthorizationRuleId: (empty(eventHubAuthorizationRuleId) ? json('null') : eventHubAuthorizationRuleId)
eventHubName: (empty(eventHubName) ? json('null') : eventHubName)
metrics: ((empty(diagnosticStorageAccountId) && empty(workspaceId) && empty(eventHubAuthorizationRuleId) && empty(eventHubName)) ? json('null') : diagnosticsMetrics)
logs: ((empty(diagnosticStorageAccountId) && empty(workspaceId) && empty(eventHubAuthorizationRuleId) && empty(eventHubName)) ? json('null') : diagnosticsLogs)
}
scope: keyVault
}

resource keyVault_secrets 'Microsoft.KeyVault/vaults/secrets@2019-09-01' = [for secret in secretsObject.secrets: if (!empty(secretsObject.secrets)) {
name: (empty(secretsObject.secrets) ? '${keyVaultName_var}/secretEntity' : '${keyVaultName_var}/${secret.secretName}')
properties: {
value: secret.secretValue
}
dependsOn: [
keyVault
]
}]

resource keyVault_keys 'Microsoft.KeyVault/vaults/keys@2019-09-01' = [for key in keysObject.keys: if (!empty(keysObject.keys)) {
name: (empty(keysObject.keys) ? '${keyVaultName_var}/keyEntity' : '${keyVaultName_var}/${key.keyName}')
properties: {
kty: key.keyType
keyOps: key.keyOps
keySize: key.keySize
curveName: key.curveName
}
dependsOn: [
keyVault
]
}]

module keyVault_privateEndpoints './.bicep/nested_privateEndpoint.bicep' = [for (item, i) in privateEndpoints: {
name: '${uniqueString(deployment().name, location)}-KeyVault-PrivateEndpoints-${i}'
params: {
privateEndpointResourceId: keyVault.id
privateEndpointVnetLocation: (empty(privateEndpoints) ? 'dummy' : reference(split(item.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location)
privateEndpointDef: item
tags: tags
}
dependsOn: [
keyVault
]
}]

module keyVault_rbac './.bicep/nested_rbac.bicep' = [for (item, i) in roleAssignments: {
name: 'rbac-${deployment().name}${i}'
params: {
roleAssignment: item
builtInRoleNames: builtInRoleNames
keyVaultName: keyVaultName_var
}
dependsOn: [
keyVault
]
}]

output keyVaultResourceId string = keyVault.id
output keyVaultResourceGroup string = resourceGroup().name
output keyVaultName string = keyVaultName_var
output keyVaultUrl string = reference(keyVault.id, '2016-10-01').vaultUri
Loading