fix: Add key vault to cognitive service - avm/res/cognitive-services/account (#3222)
## Description Follow-up to: #1932 cc: @Agazoth | Pipeline | | -------- | [![avm.res.cognitive-services.account](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.cognitive-services.account.yml/badge.svg?branch=users%2Falsehr%2FAgazoth%2FAddKVToCognitiveService&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.cognitive-services.account.yml) ## Type of Change <!-- Use the check-boxes [x] on the options that are relevant. --> - [ ] Update to CI Environment or utlities (Non-module effecting changes) - [x] Azure Verified Module updates: - [x] Bugfix containing backwards compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [ ] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation ## Checklist - [x] I'm sure there are no other open Pull Requests for the same update/change - [x] I have run `Set-AVMModule` locally to generate the supporting module files. - [x] My corresponding pipelines / checks run clean and green without any errors or warnings <!-- Please keep up to day with the contribution guide at https://aka.ms/avm/contribute/bicep --> --------- Co-authored-by: Axel B. Andersen <axel.boeg.andersen@atea.dk> Co-authored-by: Javier Cevallos <javier.cevallos@microsoft.com>
This commit is contained in:
Родитель
f21032a311
Коммит
7876f362de
|
@ -20,6 +20,7 @@ This module deploys a Cognitive Service.
|
|||
| `Microsoft.CognitiveServices/accounts` | [2023-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.CognitiveServices/2023-05-01/accounts) |
|
||||
| `Microsoft.CognitiveServices/accounts/deployments` | [2023-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.CognitiveServices/2023-05-01/accounts/deployments) |
|
||||
| `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) |
|
||||
| `Microsoft.KeyVault/vaults/secrets` | [2023-07-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.KeyVault/2023-07-01/vaults/secrets) |
|
||||
| `Microsoft.Network/privateEndpoints` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/privateEndpoints) |
|
||||
| `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/privateEndpoints/privateDnsZoneGroups) |
|
||||
|
||||
|
@ -33,13 +34,14 @@ The following section provides usage examples for the module, which were used to
|
|||
|
||||
- [Using `AIServices` with `deployments` in parameter set and private endpoints](#example-1-using-aiservices-with-deployments-in-parameter-set-and-private-endpoints)
|
||||
- [Using `AIServices` with `deployments` in parameter set](#example-2-using-aiservices-with-deployments-in-parameter-set)
|
||||
- [Using only defaults](#example-3-using-only-defaults)
|
||||
- [Using large parameter set](#example-4-using-large-parameter-set)
|
||||
- [Using `OpenAI` and `deployments` in parameter set with private endpoint](#example-5-using-openai-and-deployments-in-parameter-set-with-private-endpoint)
|
||||
- [As Speech Service](#example-6-as-speech-service)
|
||||
- [Using Customer-Managed-Keys with System-Assigned identity](#example-7-using-customer-managed-keys-with-system-assigned-identity)
|
||||
- [Using Customer-Managed-Keys with User-Assigned identity](#example-8-using-customer-managed-keys-with-user-assigned-identity)
|
||||
- [WAF-aligned](#example-9-waf-aligned)
|
||||
- [Storing keys of service in key vault](#example-3-storing-keys-of-service-in-key-vault)
|
||||
- [Using only defaults](#example-4-using-only-defaults)
|
||||
- [Using large parameter set](#example-5-using-large-parameter-set)
|
||||
- [Using `OpenAI` and `deployments` in parameter set with private endpoint](#example-6-using-openai-and-deployments-in-parameter-set-with-private-endpoint)
|
||||
- [As Speech Service](#example-7-as-speech-service)
|
||||
- [Using Customer-Managed-Keys with System-Assigned identity](#example-8-using-customer-managed-keys-with-system-assigned-identity)
|
||||
- [Using Customer-Managed-Keys with User-Assigned identity](#example-9-using-customer-managed-keys-with-user-assigned-identity)
|
||||
- [WAF-aligned](#example-10-waf-aligned)
|
||||
|
||||
### Example 1: _Using `AIServices` with `deployments` in parameter set and private endpoints_
|
||||
|
||||
|
@ -237,7 +239,71 @@ module account 'br/public:avm/res/cognitive-services/account:<version>' = {
|
|||
</details>
|
||||
<p>
|
||||
|
||||
### Example 3: _Using only defaults_
|
||||
### Example 3: _Storing keys of service in key vault_
|
||||
|
||||
This instance deploys the module and stores its keys in a key vault.
|
||||
|
||||
|
||||
<details>
|
||||
|
||||
<summary>via Bicep module</summary>
|
||||
|
||||
```bicep
|
||||
module account 'br/public:avm/res/cognitive-services/account:<version>' = {
|
||||
name: 'accountDeployment'
|
||||
params: {
|
||||
// Required parameters
|
||||
kind: 'SpeechServices'
|
||||
name: 'csakv001'
|
||||
// Non-required parameters
|
||||
location: '<location>'
|
||||
secretsExportConfiguration: {
|
||||
accessKey1Name: 'csakv001-accessKey1'
|
||||
accessKey2Name: 'csakv001-accessKey2'
|
||||
keyVaultResourceId: '<keyVaultResourceId>'
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</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
|
||||
"kind": {
|
||||
"value": "SpeechServices"
|
||||
},
|
||||
"name": {
|
||||
"value": "csakv001"
|
||||
},
|
||||
// Non-required parameters
|
||||
"location": {
|
||||
"value": "<location>"
|
||||
},
|
||||
"secretsExportConfiguration": {
|
||||
"value": {
|
||||
"accessKey1Name": "csakv001-accessKey1",
|
||||
"accessKey2Name": "csakv001-accessKey2",
|
||||
"keyVaultResourceId": "<keyVaultResourceId>"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
<p>
|
||||
|
||||
### Example 4: _Using only defaults_
|
||||
|
||||
This instance deploys the module with the minimum set of required parameters.
|
||||
|
||||
|
@ -289,7 +355,7 @@ module account 'br/public:avm/res/cognitive-services/account:<version>' = {
|
|||
</details>
|
||||
<p>
|
||||
|
||||
### Example 4: _Using large parameter set_
|
||||
### Example 5: _Using large parameter set_
|
||||
|
||||
This instance deploys the module with most of its features enabled.
|
||||
|
||||
|
@ -581,7 +647,7 @@ module account 'br/public:avm/res/cognitive-services/account:<version>' = {
|
|||
</details>
|
||||
<p>
|
||||
|
||||
### Example 5: _Using `OpenAI` and `deployments` in parameter set with private endpoint_
|
||||
### Example 6: _Using `OpenAI` and `deployments` in parameter set with private endpoint_
|
||||
|
||||
This instance deploys the module with the AI model deployment feature and private endpoint.
|
||||
|
||||
|
@ -689,7 +755,7 @@ module account 'br/public:avm/res/cognitive-services/account:<version>' = {
|
|||
</details>
|
||||
<p>
|
||||
|
||||
### Example 6: _As Speech Service_
|
||||
### Example 7: _As Speech Service_
|
||||
|
||||
This instance deploys the module as a Speech Service.
|
||||
|
||||
|
@ -803,7 +869,7 @@ module account 'br/public:avm/res/cognitive-services/account:<version>' = {
|
|||
</details>
|
||||
<p>
|
||||
|
||||
### Example 7: _Using Customer-Managed-Keys with System-Assigned identity_
|
||||
### Example 8: _Using Customer-Managed-Keys with System-Assigned identity_
|
||||
|
||||
This instance deploys the module using Customer-Managed-Keys using a System-Assigned Identity. This required the service to be deployed twice, once as a pre-requisite to create the System-Assigned Identity, and once to use it for accessing the Customer-Managed-Key secret.
|
||||
|
||||
|
@ -885,7 +951,7 @@ module account 'br/public:avm/res/cognitive-services/account:<version>' = {
|
|||
</details>
|
||||
<p>
|
||||
|
||||
### Example 8: _Using Customer-Managed-Keys with User-Assigned identity_
|
||||
### Example 9: _Using Customer-Managed-Keys with User-Assigned identity_
|
||||
|
||||
This instance deploys the module using Customer-Managed-Keys using a User-Assigned Identity to access the Customer-Managed-Key secret.
|
||||
|
||||
|
@ -973,7 +1039,7 @@ module account 'br/public:avm/res/cognitive-services/account:<version>' = {
|
|||
</details>
|
||||
<p>
|
||||
|
||||
### Example 9: _WAF-aligned_
|
||||
### Example 10: _WAF-aligned_
|
||||
|
||||
This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework.
|
||||
|
||||
|
@ -1146,6 +1212,7 @@ module account 'br/public:avm/res/cognitive-services/account:<version>' = {
|
|||
| [`restore`](#parameter-restore) | bool | Restore a soft-deleted cognitive service at deployment time. Will fail if no such soft-deleted resource exists. |
|
||||
| [`restrictOutboundNetworkAccess`](#parameter-restrictoutboundnetworkaccess) | bool | Restrict outbound network access. |
|
||||
| [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. |
|
||||
| [`secretsExportConfiguration`](#parameter-secretsexportconfiguration) | object | Key vault reference and secret settings for the module's secrets export. |
|
||||
| [`sku`](#parameter-sku) | string | SKU of the Cognitive Services resource. Use 'Get-AzCognitiveServicesAccountSku' to determine a valid combinations of 'kind' and 'SKU' for your Azure region. |
|
||||
| [`tags`](#parameter-tags) | object | Tags of the resource. |
|
||||
| [`userOwnedStorage`](#parameter-userownedstorage) | array | The storage accounts for this resource. |
|
||||
|
@ -2142,6 +2209,47 @@ The principal type of the assigned principal ID.
|
|||
]
|
||||
```
|
||||
|
||||
### Parameter: `secretsExportConfiguration`
|
||||
|
||||
Key vault reference and secret settings for the module's secrets export.
|
||||
|
||||
- Required: No
|
||||
- Type: object
|
||||
|
||||
**Required parameters**
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :-- | :-- | :-- |
|
||||
| [`keyVaultResourceId`](#parameter-secretsexportconfigurationkeyvaultresourceid) | string | The key vault name where to store the keys and connection strings generated by the modules. |
|
||||
|
||||
**Optional parameters**
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :-- | :-- | :-- |
|
||||
| [`accessKey1Name`](#parameter-secretsexportconfigurationaccesskey1name) | string | The name for the accessKey1 secret to create. |
|
||||
| [`accessKey2Name`](#parameter-secretsexportconfigurationaccesskey2name) | string | The name for the accessKey2 secret to create. |
|
||||
|
||||
### Parameter: `secretsExportConfiguration.keyVaultResourceId`
|
||||
|
||||
The key vault name where to store the keys and connection strings generated by the modules.
|
||||
|
||||
- Required: Yes
|
||||
- Type: string
|
||||
|
||||
### Parameter: `secretsExportConfiguration.accessKey1Name`
|
||||
|
||||
The name for the accessKey1 secret to create.
|
||||
|
||||
- Required: No
|
||||
- Type: string
|
||||
|
||||
### Parameter: `secretsExportConfiguration.accessKey2Name`
|
||||
|
||||
The name for the accessKey2 secret to create.
|
||||
|
||||
- Required: No
|
||||
- Type: string
|
||||
|
||||
### Parameter: `sku`
|
||||
|
||||
SKU of the Cognitive Services resource. Use 'Get-AzCognitiveServicesAccountSku' to determine a valid combinations of 'kind' and 'SKU' for your Azure region.
|
||||
|
@ -2192,6 +2300,7 @@ The storage accounts for this resource.
|
|||
| :-- | :-- | :-- |
|
||||
| `endpoint` | string | The service endpoint of the cognitive services account. |
|
||||
| `endpoints` | | All endpoints available for the cognitive services account, types depends on the cognitive service kind. |
|
||||
| `exportedSecrets` | | A hashtable of references to the secrets exported to the provided Key Vault. The key of each reference is each secret's name. |
|
||||
| `location` | string | The location the resource was deployed into. |
|
||||
| `name` | string | The name of the cognitive services account. |
|
||||
| `resourceGroupName` | string | The resource group the cognitive services account was deployed into. |
|
||||
|
|
|
@ -123,6 +123,9 @@ param enableTelemetry bool = true
|
|||
@description('Optional. Array of deployments about cognitive service accounts to create.')
|
||||
param deployments deploymentsType
|
||||
|
||||
@description('Optional. Key vault reference and secret settings for the module\'s secrets export.')
|
||||
param secretsExportConfiguration secretsExportConfigurationType?
|
||||
|
||||
var formattedUserAssignedIdentities = reduce(
|
||||
map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }),
|
||||
{},
|
||||
|
@ -468,6 +471,36 @@ resource cognitiveService_roleAssignments 'Microsoft.Authorization/roleAssignmen
|
|||
}
|
||||
]
|
||||
|
||||
module secretsExport 'modules/keyVaultExport.bicep' = if (secretsExportConfiguration != null) {
|
||||
name: '${uniqueString(deployment().name, location)}-secrets-kv'
|
||||
scope: resourceGroup(
|
||||
split((secretsExportConfiguration.?keyVaultResourceId ?? '//'), '/')[2],
|
||||
split((secretsExportConfiguration.?keyVaultResourceId ?? '////'), '/')[4]
|
||||
)
|
||||
params: {
|
||||
keyVaultName: last(split(secretsExportConfiguration.?keyVaultResourceId ?? '//', '/'))
|
||||
secretsToSet: union(
|
||||
[],
|
||||
contains(secretsExportConfiguration!, 'accessKey1Name')
|
||||
? [
|
||||
{
|
||||
name: secretsExportConfiguration!.accessKey1Name
|
||||
value: cognitiveService.listKeys().key1
|
||||
}
|
||||
]
|
||||
: [],
|
||||
contains(secretsExportConfiguration!, 'accessKey2Name')
|
||||
? [
|
||||
{
|
||||
name: secretsExportConfiguration!.accessKey2Name
|
||||
value: cognitiveService.listKeys().key2
|
||||
}
|
||||
]
|
||||
: []
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@description('The name of the cognitive services account.')
|
||||
output name string = cognitiveService.name
|
||||
|
||||
|
@ -489,6 +522,11 @@ output systemAssignedMIPrincipalId string = cognitiveService.?identity.?principa
|
|||
@description('The location the resource was deployed into.')
|
||||
output location string = cognitiveService.location
|
||||
|
||||
@description('A hashtable of references to the secrets exported to the provided Key Vault. The key of each reference is each secret\'s name.')
|
||||
output exportedSecrets secretsOutputType = (secretsExportConfiguration != null)
|
||||
? toObject(secretsExport.outputs.secretsSet, secret => last(split(secret.secretResourceId, '/')), secret => secret)
|
||||
: {}
|
||||
|
||||
// ================ //
|
||||
// Definitions //
|
||||
// ================ //
|
||||
|
@ -706,3 +744,20 @@ type endpointsType = {
|
|||
@description('The endpoint URI.')
|
||||
endpoint: string?
|
||||
}?
|
||||
|
||||
type secretsExportConfigurationType = {
|
||||
@description('Required. The key vault name where to store the keys and connection strings generated by the modules.')
|
||||
keyVaultResourceId: string
|
||||
|
||||
@description('Optional. The name for the accessKey1 secret to create.')
|
||||
accessKey1Name: string?
|
||||
|
||||
@description('Optional. The name for the accessKey2 secret to create.')
|
||||
accessKey2Name: string?
|
||||
}
|
||||
|
||||
import { secretSetType } from 'modules/keyVaultExport.bicep'
|
||||
type secretsOutputType = {
|
||||
@description('An exported secret\'s references.')
|
||||
*: secretSetType
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"_generator": {
|
||||
"name": "bicep",
|
||||
"version": "0.29.47.4906",
|
||||
"templateHash": "14735378599748380229"
|
||||
"templateHash": "259342811715055071"
|
||||
},
|
||||
"name": "Cognitive Services",
|
||||
"description": "This module deploys a Cognitive Service.",
|
||||
|
@ -573,6 +573,63 @@
|
|||
}
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"secretsExportConfigurationType": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"keyVaultResourceId": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Required. The key vault name where to store the keys and connection strings generated by the modules."
|
||||
}
|
||||
},
|
||||
"accessKey1Name": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"metadata": {
|
||||
"description": "Optional. The name for the accessKey1 secret to create."
|
||||
}
|
||||
},
|
||||
"accessKey2Name": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"metadata": {
|
||||
"description": "Optional. The name for the accessKey2 secret to create."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"secretsOutputType": {
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/secretSetType",
|
||||
"metadata": {
|
||||
"description": "An exported secret's references."
|
||||
}
|
||||
}
|
||||
},
|
||||
"secretSetType": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"secretResourceId": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The resourceId of the exported secret."
|
||||
}
|
||||
},
|
||||
"secretUri": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The secret URI of the exported secret."
|
||||
}
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"__bicep_imported_from!": {
|
||||
"sourceTemplate": "modules/keyVaultExport.bicep"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": {
|
||||
|
@ -783,6 +840,13 @@
|
|||
"metadata": {
|
||||
"description": "Optional. Array of deployments about cognitive service accounts to create."
|
||||
}
|
||||
},
|
||||
"secretsExportConfiguration": {
|
||||
"$ref": "#/definitions/secretsExportConfigurationType",
|
||||
"nullable": true,
|
||||
"metadata": {
|
||||
"description": "Optional. Key vault reference and secret settings for the module's secrets export."
|
||||
}
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
|
@ -1692,6 +1756,140 @@
|
|||
"dependsOn": [
|
||||
"cognitiveService"
|
||||
]
|
||||
},
|
||||
"secretsExport": {
|
||||
"condition": "[not(equals(parameters('secretsExportConfiguration'), null()))]",
|
||||
"type": "Microsoft.Resources/deployments",
|
||||
"apiVersion": "2022-09-01",
|
||||
"name": "[format('{0}-secrets-kv', uniqueString(deployment().name, parameters('location')))]",
|
||||
"subscriptionId": "[split(coalesce(tryGet(parameters('secretsExportConfiguration'), 'keyVaultResourceId'), '//'), '/')[2]]",
|
||||
"resourceGroup": "[split(coalesce(tryGet(parameters('secretsExportConfiguration'), 'keyVaultResourceId'), '////'), '/')[4]]",
|
||||
"properties": {
|
||||
"expressionEvaluationOptions": {
|
||||
"scope": "inner"
|
||||
},
|
||||
"mode": "Incremental",
|
||||
"parameters": {
|
||||
"keyVaultName": {
|
||||
"value": "[last(split(coalesce(tryGet(parameters('secretsExportConfiguration'), 'keyVaultResourceId'), '//'), '/'))]"
|
||||
},
|
||||
"secretsToSet": {
|
||||
"value": "[union(createArray(), if(contains(parameters('secretsExportConfiguration'), 'accessKey1Name'), createArray(createObject('name', parameters('secretsExportConfiguration').accessKey1Name, 'value', listKeys(resourceId('Microsoft.CognitiveServices/accounts', parameters('name')), '2023-05-01').key1)), createArray()), if(contains(parameters('secretsExportConfiguration'), 'accessKey2Name'), createArray(createObject('name', parameters('secretsExportConfiguration').accessKey2Name, 'value', listKeys(resourceId('Microsoft.CognitiveServices/accounts', parameters('name')), '2023-05-01').key2)), createArray()))]"
|
||||
}
|
||||
},
|
||||
"template": {
|
||||
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
|
||||
"languageVersion": "2.0",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"metadata": {
|
||||
"_generator": {
|
||||
"name": "bicep",
|
||||
"version": "0.29.47.4906",
|
||||
"templateHash": "986606208324987345"
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"secretSetType": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"secretResourceId": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The resourceId of the exported secret."
|
||||
}
|
||||
},
|
||||
"secretUri": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The secret URI of the exported secret."
|
||||
}
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"__bicep_export!": true
|
||||
}
|
||||
},
|
||||
"secretToSetType": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Required. The name of the secret to set."
|
||||
}
|
||||
},
|
||||
"value": {
|
||||
"type": "securestring",
|
||||
"metadata": {
|
||||
"description": "Required. The value of the secret to set."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": {
|
||||
"keyVaultName": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Required. The name of the Key Vault to set the ecrets in."
|
||||
}
|
||||
},
|
||||
"secretsToSet": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/secretToSetType"
|
||||
},
|
||||
"metadata": {
|
||||
"description": "Required. The secrets to set in the Key Vault."
|
||||
}
|
||||
}
|
||||
},
|
||||
"resources": {
|
||||
"keyVault": {
|
||||
"existing": true,
|
||||
"type": "Microsoft.KeyVault/vaults",
|
||||
"apiVersion": "2022-07-01",
|
||||
"name": "[parameters('keyVaultName')]"
|
||||
},
|
||||
"secrets": {
|
||||
"copy": {
|
||||
"name": "secrets",
|
||||
"count": "[length(parameters('secretsToSet'))]"
|
||||
},
|
||||
"type": "Microsoft.KeyVault/vaults/secrets",
|
||||
"apiVersion": "2023-07-01",
|
||||
"name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('secretsToSet')[copyIndex()].name)]",
|
||||
"properties": {
|
||||
"value": "[parameters('secretsToSet')[copyIndex()].value]"
|
||||
},
|
||||
"dependsOn": [
|
||||
"keyVault"
|
||||
]
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"secretsSet": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/secretSetType"
|
||||
},
|
||||
"metadata": {
|
||||
"description": "The references to the secrets exported to the provided Key Vault."
|
||||
},
|
||||
"copy": {
|
||||
"count": "[length(range(0, length(coalesce(parameters('secretsToSet'), createArray()))))]",
|
||||
"input": {
|
||||
"secretResourceId": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('secretsToSet')[range(0, length(coalesce(parameters('secretsToSet'), createArray())))[copyIndex()]].name)]",
|
||||
"secretUri": "[reference(format('secrets[{0}]', range(0, length(coalesce(parameters('secretsToSet'), createArray())))[copyIndex()])).secretUri]"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependsOn": [
|
||||
"cognitiveService"
|
||||
]
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
@ -1743,6 +1941,13 @@
|
|||
"description": "The location the resource was deployed into."
|
||||
},
|
||||
"value": "[reference('cognitiveService', '2023-05-01', 'full').location]"
|
||||
},
|
||||
"exportedSecrets": {
|
||||
"$ref": "#/definitions/secretsOutputType",
|
||||
"metadata": {
|
||||
"description": "A hashtable of references to the secrets exported to the provided Key Vault. The key of each reference is each secret's name."
|
||||
},
|
||||
"value": "[if(not(equals(parameters('secretsExportConfiguration'), null())), toObject(reference('secretsExport').outputs.secretsSet.value, lambda('secret', last(split(lambdaVariables('secret').secretResourceId, '/'))), lambda('secret', lambdaVariables('secret'))), createObject())]"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
// ============== //
|
||||
// Parameters //
|
||||
// ============== //
|
||||
|
||||
@description('Required. The name of the Key Vault to set the ecrets in.')
|
||||
param keyVaultName string
|
||||
|
||||
@description('Required. The secrets to set in the Key Vault.')
|
||||
param secretsToSet secretToSetType[]
|
||||
|
||||
// ============= //
|
||||
// Resources //
|
||||
// ============= //
|
||||
|
||||
resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' existing = {
|
||||
name: keyVaultName
|
||||
}
|
||||
|
||||
resource secrets 'Microsoft.KeyVault/vaults/secrets@2023-07-01' = [
|
||||
for secret in secretsToSet: {
|
||||
name: secret.name
|
||||
parent: keyVault
|
||||
properties: {
|
||||
value: secret.value
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
// =========== //
|
||||
// Outputs //
|
||||
// =========== //
|
||||
|
||||
@description('The references to the secrets exported to the provided Key Vault.')
|
||||
output secretsSet secretSetType[] = [
|
||||
#disable-next-line outputs-should-not-contain-secrets // Only returning the references, not a secret value
|
||||
for index in range(0, length(secretsToSet ?? [])): {
|
||||
secretResourceId: secrets[index].id
|
||||
secretUri: secrets[index].properties.secretUri
|
||||
}
|
||||
]
|
||||
|
||||
// =============== //
|
||||
// Definitions //
|
||||
// =============== //
|
||||
|
||||
@export()
|
||||
type secretSetType = {
|
||||
@description('The resourceId of the exported secret.')
|
||||
secretResourceId: string
|
||||
|
||||
@description('The secret URI of the exported secret.')
|
||||
secretUri: string
|
||||
}
|
||||
|
||||
type secretToSetType = {
|
||||
@description('Required. The name of the secret to set.')
|
||||
name: string
|
||||
|
||||
@description('Required. The value of the secret to set.')
|
||||
@secure()
|
||||
value: string
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
@description('Optional. The location to deploy to.')
|
||||
param location string = resourceGroup().location
|
||||
|
||||
@description('Required. The name of the Managed Identity to create.')
|
||||
param keyVaultName string
|
||||
|
||||
resource keyVault 'Microsoft.KeyVault/vaults@2021-06-01-preview' = {
|
||||
name: keyVaultName
|
||||
location: location
|
||||
properties: {
|
||||
sku: {
|
||||
family: 'A'
|
||||
name: 'standard'
|
||||
}
|
||||
enableRbacAuthorization: true
|
||||
tenantId: subscription().tenantId
|
||||
}
|
||||
}
|
||||
|
||||
@description('The name of the Key Vault created.')
|
||||
output keyVaultResourceId string = keyVault.id
|
|
@ -0,0 +1,63 @@
|
|||
targetScope = 'subscription'
|
||||
|
||||
metadata name = 'Storing keys of service in key vault'
|
||||
metadata description = 'This instance deploys the module and stores its keys in a key vault.'
|
||||
|
||||
// ========== //
|
||||
// Parameters //
|
||||
// ========== //
|
||||
|
||||
@description('Optional. The name of the resource group to deploy for testing purposes.')
|
||||
@maxLength(90)
|
||||
param resourceGroupName string = 'dep-${namePrefix}-cognitiveservices.accounts-${serviceShort}-rg'
|
||||
|
||||
@description('Optional. The location to deploy resources to.')
|
||||
param resourceLocation 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 = 'csakv'
|
||||
|
||||
@description('Optional. A token to inject into the name of each resource. This value can be automatically injected by the CI.')
|
||||
param namePrefix string = '#_namePrefix_#'
|
||||
|
||||
// ============ //
|
||||
// Dependencies //
|
||||
// ============ //
|
||||
|
||||
module nestedDependencies 'dependencies.bicep' = {
|
||||
scope: resourceGroup
|
||||
name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies'
|
||||
params: {
|
||||
keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}'
|
||||
location: resourceLocation
|
||||
}
|
||||
}
|
||||
|
||||
// General resources
|
||||
// =================
|
||||
resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = {
|
||||
name: resourceGroupName
|
||||
location: resourceLocation
|
||||
}
|
||||
|
||||
// ============== //
|
||||
// Test Execution //
|
||||
// ============== //
|
||||
|
||||
@batchSize(1)
|
||||
module testDeployment '../../../main.bicep' = [
|
||||
for iteration in ['init', 'idem']: {
|
||||
scope: resourceGroup
|
||||
name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}'
|
||||
params: {
|
||||
name: '${namePrefix}${serviceShort}001'
|
||||
kind: 'SpeechServices'
|
||||
location: resourceLocation
|
||||
secretsExportConfiguration: {
|
||||
keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId
|
||||
accessKey1Name: '${namePrefix}${serviceShort}001-accessKey1'
|
||||
accessKey2Name: '${namePrefix}${serviceShort}001-accessKey2'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
Загрузка…
Ссылка в новой задаче