Skip to content

Commit 9ed03f9

Browse files
committed
Allow passing in an existing Key Vault instance
1 parent 4950908 commit 9ed03f9

File tree

8 files changed

+103
-41
lines changed

8 files changed

+103
-41
lines changed

Diff for: docs/changelog.md

+3
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ Legend:
6161
> 5. Remote hubs – Ingest cost data from other tenants.
6262
> 6. Retention – Configure how long you want to keep Cost Management exports and normalized data in storage.
6363
> 7. Analytics engine – Ingest cost data into an Azure Data Explorer cluster.
64+
> 8. Allow specifying an existing Key Vault instance.
65+
> - If using template deployment, set the `existingKeyVaultId` parameter to the fully-qualified resource ID.
66+
> - If using the `Deploy-FinOpsHub` PowerShell command, set the `-ExistingKeyVaultId` parameter to the fully-qualified resource ID.
6467
>
6568
> ✏️ Changed:
6669
>

Diff for: docs/finops-hub/template.md

+8-7
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,14 @@ Please ensure the following prerequisites are met before deploying this template
7272

7373
## 📥 Parameters
7474

75-
| Parameter | Type | Description | Default value |
76-
| ---------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- |
77-
| **hubName** | String | Optional. Name of the hub. Used to ensure unique resource names. | `"finops-hub"` |
78-
| **location** | String | Optional. Azure location where all resources should be created. See https://aka.ms/azureregions. | (resource group location) |
79-
| **storageSku** | String | Optional. Storage SKU to use. LRS = Lowest cost, ZRS = High availability. Note Standard SKUs are not available for Data Lake gen2 storage. Allowed: `Premium_LRS`, `Premium_ZRS`. | `Premium_LRS` |
80-
| **tags** | Object | Optional. Tags to apply to all resources. We will also add the `cm-resource-parent` tag for improved cost roll-ups in Cost Management. |
81-
| **exportScopes** | Array | Optional. List of scope IDs to create exports for. |
75+
| Parameter | Type | Description | Default value |
76+
| ---------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- |
77+
| **hubName** | String | Optional. Name of the hub. Used to ensure unique resource names. | `"finops-hub"` |
78+
| **location** | String | Optional. Azure location where all resources should be created. See https://aka.ms/azureregions. | (resource group location) |
79+
| **storageSku** | String | Optional. Storage SKU to use. LRS = Lowest cost, ZRS = High availability. Note Standard SKUs are not available for Data Lake gen2 storage. Allowed: `Premium_LRS`, `Premium_ZRS`. | `Premium_LRS` |
80+
| **existingKeyVaultId** | String | Optional. Resource ID of the existing Key Vault resource to use. If not specified, a new Key Vault instance will be created. | |
81+
| **tags** | Object | Optional. Tags to apply to all resources. We will also add the `cm-resource-parent` tag for improved cost roll-ups in Cost Management. | |
82+
| **exportScopes** | Array | Optional. List of scope IDs to create exports for. | |
8283

8384
<br>
8485

Diff for: docs/powershell/hubs/Deploy-FinOpsHub.md

+15-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ Deploy-FinOpsHub `
4040
-Name <string> `
4141
-ResourceGroup <string> `
4242
-Location <string> `
43+
[-KeyVaultId <string>] `
4344
[-Version <string>] `
4445
[-Preview] `
4546
[-StorageSku <string>] `
@@ -57,6 +58,7 @@ Deploy-FinOpsHub `
5758
| `‑ResourceGroup` | Required. Name of the resource group to deploy to. Will be created if it doesn't exist. |
5859
| `‑Location` | Required. Azure location to execute the deployment from. |
5960
| `‑Version` | Optional. Version of the FinOps hub template to use. Default = "latest". |
61+
| `‑KeyVaultId` | Optional. Resource ID of the existing Key Vault instance to use. If not specified, one will be created. |
6062
| `‑Preview` | Optional. Indicates that preview releases should also be included. Default = false. |
6163
| `‑StorageSku` | Optional. Storage account SKU. Premium_LRS = Lowest cost, Premium_ZRS = High availability. Note Standard SKUs are not available for Data Lake gen2 storage. Default = "Premium_LRS". |
6264
| `‑Tags` | Optional. Tags for all resources. |
@@ -88,12 +90,24 @@ Deploy-FinOpsHub `
8890

8991
Deploys a new FinOps hub instance named MyHub to a new resource group named MyNewResourceGroup using version {% include version.txt %} of the template.
9092

93+
### Use existing Key Vault instance
94+
95+
```powershell
96+
Deploy-FinOpsHub `
97+
-Name MyHub `
98+
-ResourceGroupName MyExistingResourceGroup `
99+
-Location westus `
100+
-KeyVaultId "/subscriptions/###/resourceGroups/###/providers/Microsoft.KeyVault/vaults/foo"
101+
```
102+
103+
Deploys a new FinOps hub instance named MyHub using an existing Key Vault instance.
104+
91105
<br>
92106

93107
---
94108

95109
## 🧰 Related tools
96110

97-
{% include tools.md hubs="1" %}
111+
{% include tools.md hubs="1" pbi="1" %}
98112

99113
<br>

Diff for: src/powershell/Public/Deploy-FinOpsHub.ps1

+15-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
.PARAMETER Location
2020
Required. Azure location to execute the deployment from.
2121
22+
.PARAMETER KeyVaultId
23+
Optional. Resource ID of the existing Key Vault instance to use. If not specified, one will be created.
24+
2225
.PARAMETER Version
2326
Optional. Version of the FinOps hub template to use. Default = "latest".
2427
@@ -35,12 +38,17 @@
3538
Deploy-FinOpsHub -Name MyHub -ResourceGroupName MyExistingResourceGroup -Location westus
3639
3740
Deploys a new FinOps hub instance named MyHub to an existing resource group named MyExistingResourceGroup.
38-
41+
3942
.EXAMPLE
4043
Deploy-FinOpsHub -Name MyHub -Location westus -Version 0.1
41-
44+
4245
Deploys a new FinOps hub instance named MyHub using version 0.1 of the template.
4346
47+
.EXAMPLE
48+
Deploy-FinOpsHub -Name MyHub -ResourceGroupName MyExistingResourceGroup -Location westus -KeyVaultId "/subscriptions/###/resourceGroups/###/providers/Microsoft.KeyVault/vaults/foo"
49+
50+
Deploys a new FinOps hub instance named MyHub using an existing Key Vault instance.
51+
4452
.LINK
4553
https://aka.ms/ftk/Deploy-FinOpsHub
4654
#>
@@ -62,6 +70,10 @@ function Deploy-FinOpsHub
6270
[string]
6371
$Location,
6472

73+
[Parameter(Mandatory = $false)]
74+
[string]
75+
$KeyVaultId = '',
76+
6577
[Parameter()]
6678
[string]
6779
$Version = 'latest',
@@ -112,6 +124,7 @@ function Deploy-FinOpsHub
112124
TemplateParameterObject = @{
113125
hubName = $Name
114126
storageSku = $StorageSku
127+
existingKeyVaultId = $KeyVaultId
115128
}
116129
}
117130

Diff for: src/templates/finops-hub/main.bicep

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ param location string = resourceGroup().location
2020
@description('Optional. Storage SKU to use. LRS = Lowest cost, ZRS = High availability. Note Standard SKUs are not available for Data Lake gen2 storage. Allowed: Premium_LRS, Premium_ZRS. Default: Premium_LRS.')
2121
param storageSku string = 'Premium_LRS'
2222

23+
@description('Optional. Resource ID of the existing Key Vault resource to use. If not specified, a new Key Vault instance will be created.')
24+
param existingKeyVaultId string = ''
25+
2326
@description('Optional. Tags to apply to all resources. We will also add the cm-resource-parent tag for improved cost roll-ups in Cost Management.')
2427
param tags object = {}
2528

@@ -39,6 +42,7 @@ module hub 'modules/hub.bicep' = {
3942
hubName: hubName
4043
location: location
4144
storageSku: storageSku
45+
existingKeyVaultId: existingKeyVaultId
4246
tags: tags
4347
tagsByResource: tagsByResource
4448
exportScopes: exportScopes

Diff for: src/templates/finops-hub/modules/dataFactory.bicep

+5-4
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
// Parameters
66
//==============================================================================
77

8-
@description('Optional. Name of the hub. Used to ensure unique resource names. Default: "finops-hub".')
8+
@description('Required. Name of the hub. Used to ensure unique resource names.')
99
param dataFactoryName string
1010

11-
@description('Required. The name of the Azure Key Vault instance.')
12-
param keyVaultName string
11+
@description('Optional. The resource ID of the Azure Key Vault instance.')
12+
param keyVaultId string
1313

1414
@description('Required. The name of the Azure storage account instance.')
1515
param storageAccountName string
@@ -293,7 +293,8 @@ resource stopHubTriggers 'Microsoft.Resources/deploymentScripts@2020-10-01' = {
293293
//------------------------------------------------------------------------------
294294

295295
resource keyVault 'Microsoft.KeyVault/vaults@2022-11-01' existing = {
296-
name: keyVaultName
296+
name: last(split(keyVaultId, '/'))
297+
scope: resourceGroup(split(keyVaultId, '/')[2], split(keyVaultId, '/')[4])
297298
}
298299

299300
resource linkedService_keyVault 'Microsoft.DataFactory/factories/linkedservices@2018-06-01' = {

Diff for: src/templates/finops-hub/modules/hub.bicep

+6-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ param location string = resourceGroup().location
1818
@description('Optional. Storage SKU to use. LRS = Lowest cost, ZRS = High availability. Note Standard SKUs are not available for Data Lake gen2 storage. Allowed: Premium_LRS, Premium_ZRS. Default: Premium_LRS.')
1919
param storageSku string = 'Premium_LRS'
2020

21+
@description('Optional. Resource ID of the existing Key Vault resource to use. If not specified, a new Key Vault instance will be created.')
22+
param existingKeyVaultId string = ''
23+
2124
@description('Optional. Tags to apply to all resources. We will also add the cm-resource-parent tag for improved cost roll-ups in Cost Management.')
2225
param tags object = {}
2326

@@ -122,7 +125,7 @@ module dataFactoryResources 'dataFactory.bicep' = {
122125
params: {
123126
dataFactoryName: dataFactoryName
124127
convertToParquet: convertToParquet
125-
keyVaultName: keyVault.outputs.name
128+
keyVaultId: keyVault.outputs.resourceId
126129
storageAccountName: storage.outputs.name
127130
exportContainerName: storage.outputs.exportContainer
128131
ingestionContainerName: storage.outputs.ingestionContainer
@@ -138,8 +141,10 @@ module dataFactoryResources 'dataFactory.bicep' = {
138141

139142
module keyVault 'keyVault.bicep' = {
140143
name: 'keyVault'
144+
scope: empty(existingKeyVaultId) ? resourceGroup() : resourceGroup(split(existingKeyVaultId, '/')[2], split(existingKeyVaultId, '/')[4])
141145
params: {
142146
hubName: hubName
147+
existingKeyVaultName: last(split(existingKeyVaultId, '/'))
143148
uniqueSuffix: uniqueSuffix
144149
location: location
145150
tags: resourceTags

Diff for: src/templates/finops-hub/modules/keyVault.bicep

+47-26
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ param hubName string
1111
@description('Required. Suffix to add to the KeyVault instance name to ensure uniqueness.')
1212
param uniqueSuffix string
1313

14+
@description('Optional. Resource ID of the existing Key Vault resource to use. If not specified, a new Key Vault instance will be created.')
15+
param existingKeyVaultName string
16+
1417
@description('Optional. Location for all resources.')
1518
param location string = resourceGroup().location
1619

@@ -49,11 +52,42 @@ var formattedAccessPolicies = [for accessPolicy in accessPolicies: {
4952
tenantId: contains(accessPolicy, 'tenantId') ? accessPolicy.tenantId : tenant().tenantId
5053
}]
5154

55+
var storageSecretProperties = {
56+
attributes: {
57+
enabled: true
58+
exp: 1702648632
59+
nbf: 10000
60+
}
61+
value: storageRef.listKeys().keys[0].value
62+
}
63+
5264
//==============================================================================
5365
// Resources
5466
//==============================================================================
5567

56-
resource keyVault 'Microsoft.KeyVault/vaults@2022-11-01' = {
68+
resource storageRef 'Microsoft.Storage/storageAccounts@2022-09-01' existing = {
69+
name: storageAccountName
70+
}
71+
72+
// Get existing key vault, if existingKeyVaultName is set
73+
resource existingKeyVault 'Microsoft.KeyVault/vaults@2023-07-01' existing = if (!empty(existingKeyVaultName)) {
74+
name: empty(existingKeyVaultName) ? 'placeholder' : existingKeyVaultName
75+
76+
resource existingKeyVault_accessPolicies 'accessPolicies@2023-07-01' = if (!empty(accessPolicies)) {
77+
name: 'add'
78+
properties: {
79+
accessPolicies: formattedAccessPolicies
80+
}
81+
}
82+
83+
resource existingKeyVault_secrets 'secrets@2023-07-01' = {
84+
name: storageRef.name
85+
properties: storageSecretProperties
86+
}
87+
}
88+
89+
// Create new key vault, if existingKeyVaultName is not set
90+
resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' = if (empty(existingKeyVaultName)) {
5791
name: keyVaultName
5892
location: location
5993
tags: union(tags, contains(tagsByResource, 'Microsoft.KeyVault/vaults') ? tagsByResource['Microsoft.KeyVault/vaults'] : {})
@@ -73,30 +107,17 @@ resource keyVault 'Microsoft.KeyVault/vaults@2022-11-01' = {
73107
family: 'A'
74108
}
75109
}
76-
}
77-
78-
resource keyVault_accessPolicies 'Microsoft.KeyVault/vaults/accessPolicies@2022-11-01' = if (!empty(accessPolicies)) {
79-
name: 'add'
80-
parent: keyVault
81-
properties: {
82-
accessPolicies: formattedAccessPolicies
83-
}
84-
}
85110

86-
resource storageRef 'Microsoft.Storage/storageAccounts@2022-09-01' existing = {
87-
name: storageAccountName
88-
}
89-
90-
resource keyVault_secrets 'Microsoft.KeyVault/vaults/secrets@2022-11-01' = {
91-
name: storageRef.name
92-
parent: keyVault
93-
properties: {
94-
attributes: {
95-
enabled: true
96-
exp: 1702648632
97-
nbf: 10000
111+
resource keyVault_accessPolicies 'accessPolicies@2023-07-01' = if (!empty(accessPolicies)) {
112+
name: 'add'
113+
properties: {
114+
accessPolicies: formattedAccessPolicies
98115
}
99-
value: storageRef.listKeys().keys[0].value
116+
}
117+
118+
resource keyVault_secrets 'secrets@2023-07-01' = {
119+
name: storageRef.name
120+
properties: storageSecretProperties
100121
}
101122
}
102123

@@ -105,10 +126,10 @@ resource keyVault_secrets 'Microsoft.KeyVault/vaults/secrets@2022-11-01' = {
105126
//==============================================================================
106127

107128
@description('The resource ID of the key vault.')
108-
output resourceId string = keyVault.id
129+
output resourceId string = empty(existingKeyVaultName) ? keyVault.id : existingKeyVault.id
109130

110131
@description('The name of the key vault.')
111-
output name string = keyVault.name
132+
output name string = empty(existingKeyVaultName) ? keyVault.name : existingKeyVault.name
112133

113134
@description('The URI of the key vault.')
114-
output uri string = keyVault.properties.vaultUri
135+
output uri string = empty(existingKeyVaultName) ? keyVault.properties.vaultUri : existingKeyVault.properties.vaultUri

0 commit comments

Comments
 (0)