From 6f6a4f45bd57625304f0173881594aa119038335 Mon Sep 17 00:00:00 2001 From: ReneHezser <rene@hezser.de> Date: Thu, 13 Jun 2024 19:45:58 +0200 Subject: [PATCH 1/8] documentation updates and Service Bus test --- avm/res/web/connection/README.md | 185 ++++++++++++++++- avm/res/web/connection/main.bicep | 158 +++++++++++--- avm/res/web/connection/main.json | 193 ++++++++++++++++-- .../tests/e2e/servicebus/dependencies.bicep | 102 +++++++++ .../tests/e2e/servicebus/main.test.bicep | 75 +++++++ 5 files changed, 655 insertions(+), 58 deletions(-) create mode 100644 avm/res/web/connection/tests/e2e/servicebus/dependencies.bicep create mode 100644 avm/res/web/connection/tests/e2e/servicebus/main.test.bicep diff --git a/avm/res/web/connection/README.md b/avm/res/web/connection/README.md index 3215e264f7..65a69163d2 100644 --- a/avm/res/web/connection/README.md +++ b/avm/res/web/connection/README.md @@ -34,7 +34,8 @@ The following section provides usage examples for the module, which were used to - [Using only defaults](#example-1-using-only-defaults) - [Using large parameter set](#example-2-using-large-parameter-set) -- [WAF-aligned](#example-3-waf-aligned) +- [Using large parameter set](#example-3-using-large-parameter-set) +- [WAF-aligned](#example-4-waf-aligned) ### Example 1: _Using only defaults_ @@ -214,7 +215,97 @@ module connection 'br/public:avm/res/web/connection:<version>' = { </details> <p> -### Example 3: _WAF-aligned_ +### Example 3: _Using large parameter set_ + +This instance deploys the module with most of its features enabled. + + +<details> + +<summary>via Bicep module</summary> + +```bicep +module connection 'br/public:avm/res/web/connection:<version>' = { + name: 'connectionDeployment' + params: { + // Required parameters + displayName: 'Service Bus' + name: 'servicebus' + // Non-required parameters + api: { + id: '<id>' + } + location: '<location>' + parameterValueSet: { + name: 'managedIdentityAuth' + values: { + namespaceEndpoint: { + value: '<value>' + } + } + } + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +</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 + "displayName": { + "value": "Service Bus" + }, + "name": { + "value": "servicebus" + }, + // Non-required parameters + "api": { + "value": { + "id": "<id>" + } + }, + "location": { + "value": "<location>" + }, + "parameterValueSet": { + "value": { + "name": "managedIdentityAuth", + "values": { + "namespaceEndpoint": { + "value": "<value>" + } + } + } + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +</details> +<p> + +### Example 4: _WAF-aligned_ This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework. @@ -293,8 +384,8 @@ module connection 'br/public:avm/res/web/connection:<version>' = { | Parameter | Type | Description | | :-- | :-- | :-- | -| [`displayName`](#parameter-displayname) | string | Display name connection. Example: 'blobconnection' when using blobs. It can change depending on the resource. | -| [`name`](#parameter-name) | string | Connection name for connection. Example: 'azureblob' when using blobs. It can change depending on the resource. | +| [`displayName`](#parameter-displayname) | string | Display name connection. Example: `blobconnection` when using blobs. It can change depending on the resource. | +| [`name`](#parameter-name) | string | Connection name for connection. It can change depending on the resource. | **Optional parameters** @@ -307,6 +398,7 @@ module connection 'br/public:avm/res/web/connection:<version>' = { | [`lock`](#parameter-lock) | object | The lock settings of the service. | | [`nonSecretParameterValues`](#parameter-nonsecretparametervalues) | object | Dictionary of nonsecret parameter values. | | [`parameterValues`](#parameter-parametervalues) | secureObject | Connection strings or access keys for connection. Example: 'accountName' and 'accessKey' when using blobs. It can change depending on the resource. | +| [`parameterValueSet`](#parameter-parametervalueset) | object | Additional parameter Value Set. | | [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | | [`statuses`](#parameter-statuses) | array | Status of the connection. | | [`tags`](#parameter-tags) | object | Tags of the resource. | @@ -314,14 +406,14 @@ module connection 'br/public:avm/res/web/connection:<version>' = { ### Parameter: `displayName` -Display name connection. Example: 'blobconnection' when using blobs. It can change depending on the resource. +Display name connection. Example: `blobconnection` when using blobs. It can change depending on the resource. - Required: Yes - Type: string ### Parameter: `name` -Connection name for connection. Example: 'azureblob' when using blobs. It can change depending on the resource. +Connection name for connection. It can change depending on the resource. - Required: Yes - Type: string @@ -333,6 +425,80 @@ Specific values for some API connections. - Required: No - Type: object +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`id`](#parameter-apiid) | string | The ID of the API connection. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`brandColor`](#parameter-apibrandcolor) | string | The Brand color. | +| [`description`](#parameter-apidescription) | string | The custom API description. | +| [`displayName`](#parameter-apidisplayname) | string | The display name of the API connection. | +| [`iconUri`](#parameter-apiiconuri) | string | The icon URI. | +| [`name`](#parameter-apiname) | string | The name of the API connection. | +| [`swagger`](#parameter-apiswagger) | string | The swagger URL. For Bicep, you can use the any() function. | +| [`type`](#parameter-apitype) | string | The resource reference type. | + +### Parameter: `api.id` + +The ID of the API connection. + +- Required: Yes +- Type: string + +### Parameter: `api.brandColor` + +The Brand color. + +- Required: No +- Type: string + +### Parameter: `api.description` + +The custom API description. + +- Required: No +- Type: string + +### Parameter: `api.displayName` + +The display name of the API connection. + +- Required: No +- Type: string + +### Parameter: `api.iconUri` + +The icon URI. + +- Required: No +- Type: string + +### Parameter: `api.name` + +The name of the API connection. + +- Required: No +- Type: string + +### Parameter: `api.swagger` + +The swagger URL. For Bicep, you can use the any() function. + +- Required: No +- Type: string + +### Parameter: `api.type` + +The resource reference type. + +- Required: No +- Type: string + ### Parameter: `customParameterValues` Dictionary of custom parameter values for specific connections. @@ -406,6 +572,13 @@ Connection strings or access keys for connection. Example: 'accountName' and 'ac - Required: No - Type: secureObject +### Parameter: `parameterValueSet` + +Additional parameter Value Set. + +- Required: No +- Type: object + ### Parameter: `roleAssignments` Array of role assignments to create. diff --git a/avm/res/web/connection/main.bicep b/avm/res/web/connection/main.bicep index 6a4bea2123..17a42aa334 100644 --- a/avm/res/web/connection/main.bicep +++ b/avm/res/web/connection/main.bicep @@ -2,46 +2,66 @@ metadata name = 'API Connections' metadata description = 'This module deploys an Azure API Connection.' metadata owner = 'Azure/module-maintainers' -@description('Optional. Specific values for some API connections.') -param api object? - -@description('Required. Connection name for connection. Example: \'azureblob\' when using blobs. It can change depending on the resource.') +@description('Required. Connection name for connection. It can change depending on the resource.') param name string +@description('Optional. Location of the deployment.') +param location string = resourceGroup().location + @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true +// ============ // +// Parameters // +// ============ // + +@description('Optional. Specific values for some API connections.') +param api apiReferenceType? + @description('Optional. Dictionary of custom parameter values for specific connections.') param customParameterValues object? -@description('Required. Display name connection. Example: \'blobconnection\' when using blobs. It can change depending on the resource.') +@description('Required. Display name connection. Example: `blobconnection` when using blobs. It can change depending on the resource.') param displayName string -@description('Optional. Location of the deployment.') -param location string = resourceGroup().location - @description('Optional. Dictionary of nonsecret parameter values.') #disable-next-line secure-secrets-in-params // Not a secret param nonSecretParameterValues object? @description('Optional. Connection strings or access keys for connection. Example: \'accountName\' and \'accessKey\' when using blobs. It can change depending on the resource.') @secure() +@metadata({ + example: ''' + connectionString: 'listKeys('/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/Microsoft.ServiceBus/namespaces/AuthorizationRules/<serviceBusName>/RootManagedSharedAccessKey', '2023-01-01').primaryConnectionString' + ''' +}) param parameterValues object? +@description('Optional. Additional parameter Value Set.') +param parameterValueSet object? + @description('Optional. Array of role assignments to create.') param roleAssignments roleAssignmentType @description('Optional. Status of the connection.') -param statuses array? +param statuses statusType[]? @description('Optional. The lock settings of the service.') param lock lockType +@metadata({ + example: ''' + { + key1: 'value1' + key2: 'value2' + } + ''' +}) @description('Optional. Tags of the resource.') param tags object? @description('Optional. Links to test the API connection.') -param testLinks array? +param testLinks testLinkType[]? var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') @@ -57,24 +77,27 @@ var builtInRoleNames = { ) } -resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = - if (enableTelemetry) { - name: '46d3xbcp.res.web-connection.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}' - properties: { - mode: 'Incremental' - template: { - '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' - contentVersion: '1.0.0.0' - resources: [] - outputs: { - telemetry: { - type: 'String' - value: 'For more information, see https://aka.ms/avm/TelemetryInfo' - } +// ============== // +// Resources // +// ============== // + +resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { + name: '46d3xbcp.res.web-connection.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + outputs: { + telemetry: { + type: 'String' + value: 'For more information, see https://aka.ms/avm/TelemetryInfo' } } } } +} resource connection 'Microsoft.Web/connections@2016-06-01' = { name: name @@ -88,20 +111,21 @@ resource connection 'Microsoft.Web/connections@2016-06-01' = { nonSecretParameterValues: nonSecretParameterValues testLinks: testLinks statuses: statuses + #disable-next-line BCP037 + parameterValueSet: parameterValueSet } } -resource connection_lock 'Microsoft.Authorization/locks@2020-05-01' = - if (!empty(lock ?? {}) && lock.?kind != 'None') { - name: lock.?name ?? 'lock-${name}' - properties: { - level: lock.?kind ?? '' - notes: lock.?kind == 'CanNotDelete' - ? 'Cannot delete resource or child resources.' - : 'Cannot delete or modify the resource or child resources.' - } - scope: connection +resource connection_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') { + name: lock.?name ?? 'lock-${name}' + properties: { + level: lock.?kind ?? '' + notes: lock.?kind == 'CanNotDelete' + ? 'Cannot delete resource or child resources.' + : 'Cannot delete or modify the resource or child resources.' } + scope: connection +} resource connection_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ for (roleAssignment, index) in (roleAssignments ?? []): { @@ -123,6 +147,10 @@ resource connection_roleAssignments 'Microsoft.Authorization/roleAssignments@202 } ] +// ============ // +// Outputs // +// ============ // + @description('The resource ID of the connection.') output resourceId string = connection.id @@ -169,3 +197,65 @@ type roleAssignmentType = { @description('Optional. The Resource Id of the delegated managed identity resource.') delegatedManagedIdentityResourceId: string? }[]? + +type apiReferenceType = { + @description('Optional. The Brand color.') + brandColor: string? + + @description('Optional. The custom API description.') + description: string? + + @description('Optional. The display name of the API connection.') + displayName: string? + + @description('Optional. The icon URI.') + iconUri: string? + + @description('Required. The ID of the API connection.') + id: string + + @description('Optional. The name of the API connection.') + name: string? + + @description('Optional. The swagger URL. For Bicep, you can use the any() function.') + swagger: string? + + @description('Optional. The resource reference type.') + 'type': string? +} + +type statusType = { + @description('Optional. The error of the connection.') + error: { + @description('Optional. The etag of the error.') + etag: string + + @description('Optional. The location of the resource.') + location: string + + @description('Optional. Connection Error Properties.') + properties: { + @description('Optional. Code of the status.') + code: string + + @description('Optional. Description of the status.') + message: string + } + + @description('Optional. The tags of the error.') + tags: object + } + @description('Optional. The status of the connection.') + status: string + + @description('Optional. The target of the error.') + target: string +} + +type testLinkType = { + @description('Optional. The HTTP Method.') + method: string + + @description('Optional. Test link request URI.') + requestUri: string +} diff --git a/avm/res/web/connection/main.json b/avm/res/web/connection/main.json index b8ead16876..a2fa7ddde6 100644 --- a/avm/res/web/connection/main.json +++ b/avm/res/web/connection/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.54.24096", - "templateHash": "153462740137838298" + "version": "0.28.1.47646", + "templateHash": "2460380322221205337" }, "name": "API Connections", "description": "This module deploys an Azure API Connection.", @@ -103,20 +103,161 @@ } }, "nullable": true + }, + "apiReferenceType": { + "type": "object", + "properties": { + "brandColor": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Brand color." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom API description." + } + }, + "displayName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The display name of the API connection." + } + }, + "iconUri": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The icon URI." + } + }, + "id": { + "type": "string", + "metadata": { + "description": "Required. The ID of the API connection." + } + }, + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the API connection." + } + }, + "swagger": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The swagger URL. For Bicep, you can use the any() function." + } + }, + "type": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource reference type." + } + } + } + }, + "statusType": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "etag": { + "type": "string", + "metadata": { + "description": "Optional. The etag of the error." + } + }, + "location": { + "type": "string", + "metadata": { + "description": "Optional. The location of the resource." + } + }, + "properties": { + "type": "object", + "properties": { + "code": { + "type": "string", + "metadata": { + "description": "Optional. Code of the status." + } + }, + "message": { + "type": "string", + "metadata": { + "description": "Optional. Description of the status." + } + } + }, + "metadata": { + "description": "Optional. Connection Error Properties." + } + }, + "tags": { + "type": "object", + "metadata": { + "description": "Optional. The tags of the error." + } + } + }, + "metadata": { + "description": "Optional. The error of the connection." + } + }, + "status": { + "type": "string", + "metadata": { + "description": "Optional. The status of the connection." + } + }, + "target": { + "type": "string", + "metadata": { + "description": "Optional. The target of the error." + } + } + } + }, + "testLinkType": { + "type": "object", + "properties": { + "method": { + "type": "string", + "metadata": { + "description": "Optional. The HTTP Method." + } + }, + "requestUri": { + "type": "string", + "metadata": { + "description": "Optional. Test link request URI." + } + } + } } }, "parameters": { - "api": { - "type": "object", - "nullable": true, + "name": { + "type": "string", "metadata": { - "description": "Optional. Specific values for some API connections." + "example": "azureblob", + "description": "Required. Connection name for connection. It can change depending on the resource." } }, - "name": { + "location": { "type": "string", + "defaultValue": "[resourceGroup().location]", "metadata": { - "description": "Required. Connection name for connection. Example: 'azureblob' when using blobs. It can change depending on the resource." + "description": "Optional. Location of the deployment." } }, "enableTelemetry": { @@ -126,6 +267,13 @@ "description": "Optional. Enable/Disable usage telemetry for module." } }, + "api": { + "$ref": "#/definitions/apiReferenceType", + "nullable": true, + "metadata": { + "description": "Optional. Specific values for some API connections." + } + }, "customParameterValues": { "type": "object", "nullable": true, @@ -136,14 +284,7 @@ "displayName": { "type": "string", "metadata": { - "description": "Required. Display name connection. Example: 'blobconnection' when using blobs. It can change depending on the resource." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. Location of the deployment." + "description": "Required. Display name connection. Example: `blobconnection` when using blobs. It can change depending on the resource." } }, "nonSecretParameterValues": { @@ -157,9 +298,17 @@ "type": "secureObject", "nullable": true, "metadata": { + "example": " {\r\n //connectionString: '[listKeys(resourceId(parameters('servicebus_resourceGroup'),'Microsoft.ServiceBus/namespaces/AuthorizationRules', parameters('serviceBusName'), 'RootManageSharedAccessKey'),'2015-08-01').primaryConnectionString]'\r\n connectionString: 'list'\r\n }\r\n ", "description": "Optional. Connection strings or access keys for connection. Example: 'accountName' and 'accessKey' when using blobs. It can change depending on the resource." } }, + "parameterValueSet": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Additional parameter Value Set." + } + }, "roleAssignments": { "$ref": "#/definitions/roleAssignmentType", "metadata": { @@ -168,6 +317,9 @@ }, "statuses": { "type": "array", + "items": { + "$ref": "#/definitions/statusType" + }, "nullable": true, "metadata": { "description": "Optional. Status of the connection." @@ -183,11 +335,15 @@ "type": "object", "nullable": true, "metadata": { + "example": " {\r\n key1: 'value1'\r\n key2: 'value2'\r\n }\r\n ", "description": "Optional. Tags of the resource." } }, "testLinks": { "type": "array", + "items": { + "$ref": "#/definitions/testLinkType" + }, "nullable": true, "metadata": { "description": "Optional. Links to test the API connection." @@ -237,7 +393,8 @@ "parameterValues": "[parameters('parameterValues')]", "nonSecretParameterValues": "[parameters('nonSecretParameterValues')]", "testLinks": "[parameters('testLinks')]", - "statuses": "[parameters('statuses')]" + "statuses": "[parameters('statuses')]", + "parameterValueSet": "[parameters('parameterValueSet')]" } }, "connection_lock": { @@ -307,4 +464,4 @@ "value": "[reference('connection', '2016-06-01', 'full').location]" } } -} \ No newline at end of file +} diff --git a/avm/res/web/connection/tests/e2e/servicebus/dependencies.bicep b/avm/res/web/connection/tests/e2e/servicebus/dependencies.bicep new file mode 100644 index 0000000000..43c0ee1585 --- /dev/null +++ b/avm/res/web/connection/tests/e2e/servicebus/dependencies.bicep @@ -0,0 +1,102 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + +param serviceBusNamespaceName string + +var messageRoutingTopic = 'topic1' + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +resource serviceBusNamespace 'Microsoft.ServiceBus/namespaces@2021-11-01' = { + name: serviceBusNamespaceName + location: location + sku: { + name: 'Standard' + capacity: 1 + tier: 'Standard' + } + properties: {} + // identity: { + // type: 'UserAssigned' + // userAssignedIdentities: { + // '${managedIdentity.id}': {} + // } + // } + + resource authorizationRule 'authorizationRules@2021-11-01' = { + name: 'RootManageSharedAccessKey' + properties: { + rights: [ + 'Listen' + 'Send' + 'Manage' + ] + } + } + + resource topics 'topics@2021-11-01' = { + name: messageRoutingTopic + properties: { + requiresDuplicateDetection: false + enableBatchedOperations: true + status: 'Active' + supportOrdering: false + enablePartitioning: true + enableExpress: false + } + + resource ubscription 'subscriptions@2021-11-01' = { + name: 'subscription1' + properties: { + lockDuration: 'PT5M' + requiresSession: false + deadLetteringOnMessageExpiration: false + deadLetteringOnFilterEvaluationExceptions: true + defaultMessageTimeToLive: 'P10675199DT2H48M5.4775807S' + autoDeleteOnIdle: 'P10675199DT2H48M5.4775807S' + enableBatchedOperations: true + status: 'Active' + } + } + } +} + +resource sbPermissionsReader 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid('msi-${managedIdentity.name}-ServiceBus-DataReceiver-RoleAssignment') + scope: serviceBusNamespace + properties: { + principalId: managedIdentity.properties.principalId + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '4f6d3b9b-027b-4f4c-9142-0e5a2a2247e0' + ) // Azure Service Bus Data Receiver + principalType: 'ServicePrincipal' + } +} + +resource sbPermissionsSender 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid('msi-${managedIdentity.name}-ServiceBus-DataSender-RoleAssignment') + scope: serviceBusNamespace + properties: { + principalId: managedIdentity.properties.principalId + roleDefinitionId: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '69a216fc-b8fb-44d8-bc22-1f3c2cd27a39' + ) // Azure Service Bus Data Sender + principalType: 'ServicePrincipal' + } +} +@description('The principal ID of the created Managed Identity.') +output managedIdentityPrincipalId string = managedIdentity.properties.principalId + +output serviceBusResourceId string = serviceBusNamespace.id + +output serviceBusName string = serviceBusNamespace.name + +output serviceBusEndpoint string = serviceBusNamespace.properties.serviceBusEndpoint diff --git a/avm/res/web/connection/tests/e2e/servicebus/main.test.bicep b/avm/res/web/connection/tests/e2e/servicebus/main.test.bicep new file mode 100644 index 0000000000..f8ed2aab15 --- /dev/null +++ b/avm/res/web/connection/tests/e2e/servicebus/main.test.bicep @@ -0,0 +1,75 @@ +targetScope = 'subscription' + +metadata name = 'Using a Service Bus connection' +metadata description = 'This instance deploys the module with a connection to Service Bus.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-web.connections-${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 = 'wcsb' + +@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: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + location: resourceLocation + serviceBusNamespaceName: 'dep-${namePrefix}-sb-${serviceShort}' + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + displayName: 'Service Bus' + name: 'servicebus' + location: resourceLocation + api: { + id: subscriptionResourceId('Microsoft.Web/locations/managedApis', '${resourceLocation}', 'servicebus') + } + parameterValueSet: { + name: 'managedIdentityAuth' + values: { + namespaceEndpoint: { + value: 'sb://${nestedDependencies.outputs.serviceBusEndpoint}' + } + } + } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + } +] From 18e1241328d2d75428472c5a0390246ac436adf0 Mon Sep 17 00:00:00 2001 From: ReneHezser <rene@hezser.de> Date: Fri, 14 Jun 2024 17:39:52 +0200 Subject: [PATCH 2/8] parameter updates --- avm/res/web/connection/main.bicep | 33 ++++++++++++++++--- .../tests/e2e/servicebus/main.test.bicep | 1 + 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/avm/res/web/connection/main.bicep b/avm/res/web/connection/main.bicep index 17a42aa334..61c3d04b8d 100644 --- a/avm/res/web/connection/main.bicep +++ b/avm/res/web/connection/main.bicep @@ -18,6 +18,10 @@ param enableTelemetry bool = true @description('Optional. Specific values for some API connections.') param api apiReferenceType? +@description('Optional. The kind of the connection. `V1` for StandardLogicApp.') +@allowed(['V1', 'V2']) +param kind string + @description('Optional. Dictionary of custom parameter values for specific connections.') param customParameterValues object? @@ -32,12 +36,29 @@ param nonSecretParameterValues object? @secure() @metadata({ example: ''' + { connectionString: 'listKeys('/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/Microsoft.ServiceBus/namespaces/AuthorizationRules/<serviceBusName>/RootManagedSharedAccessKey', '2023-01-01').primaryConnectionString' + } + { + rootfolder: fileshareConnection.rootfolder + authType: fileshareConnection.authType + // to add an object, use the any() function + gateway: any({ + name: fileshareConnection.odgw.name + id: resourceId(fileshareConnection.odgw.resourceGroup, 'Microsoft.Web/connectionGateways', fileshareConnection.odgw.name) + type: 'Microsoft.Web/connectionGateways' + }) + username: username + password: password + } ''' }) param parameterValues object? -@description('Optional. Additional parameter Value Set.') +@allowed(['', 'Alternative']) +param alternativeParameterValues string? + +@description('Optional. Additional parameter Value Set used for authentication settings.') param parameterValueSet object? @description('Optional. Array of role assignments to create.') @@ -102,15 +123,17 @@ resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableT resource connection 'Microsoft.Web/connections@2016-06-01' = { name: name location: location + #disable-next-line BCP187 + kind: kind tags: tags properties: { displayName: displayName customParameterValues: customParameterValues api: api - parameterValues: parameterValues - nonSecretParameterValues: nonSecretParameterValues - testLinks: testLinks - statuses: statuses + parameterValues: !empty(parameterValues) ? parameterValues : null + nonSecretParameterValues: !empty(nonSecretParameterValues) ? nonSecretParameterValues : null + testLinks: !empty(testLinks) ? testLinks : null + statuses: !empty(statuses) ? statuses : null #disable-next-line BCP037 parameterValueSet: parameterValueSet } diff --git a/avm/res/web/connection/tests/e2e/servicebus/main.test.bicep b/avm/res/web/connection/tests/e2e/servicebus/main.test.bicep index f8ed2aab15..fe204fe995 100644 --- a/avm/res/web/connection/tests/e2e/servicebus/main.test.bicep +++ b/avm/res/web/connection/tests/e2e/servicebus/main.test.bicep @@ -55,6 +55,7 @@ module testDeployment '../../../main.bicep' = [ name: 'servicebus' location: resourceLocation api: { + type: 'Microsoft.Web/locations/managedApis' id: subscriptionResourceId('Microsoft.Web/locations/managedApis', '${resourceLocation}', 'servicebus') } parameterValueSet: { From 1131d5838fad24aac058699498ef3d6d165c69fd Mon Sep 17 00:00:00 2001 From: ReneHezser <rene@hezser.de> Date: Tue, 18 Jun 2024 07:24:19 +0000 Subject: [PATCH 3/8] removed user defined type --- avm/res/web/connection/README.md | 177 +----------------- avm/res/web/connection/main.bicep | 107 +++-------- avm/res/web/connection/main.json | 167 ++--------------- .../tests/e2e/servicebus/dependencies.bicep | 102 ---------- .../tests/e2e/servicebus/main.test.bicep | 76 -------- 5 files changed, 49 insertions(+), 580 deletions(-) delete mode 100644 avm/res/web/connection/tests/e2e/servicebus/dependencies.bicep delete mode 100644 avm/res/web/connection/tests/e2e/servicebus/main.test.bicep diff --git a/avm/res/web/connection/README.md b/avm/res/web/connection/README.md index 65a69163d2..6fbc5a62c3 100644 --- a/avm/res/web/connection/README.md +++ b/avm/res/web/connection/README.md @@ -34,8 +34,7 @@ The following section provides usage examples for the module, which were used to - [Using only defaults](#example-1-using-only-defaults) - [Using large parameter set](#example-2-using-large-parameter-set) -- [Using large parameter set](#example-3-using-large-parameter-set) -- [WAF-aligned](#example-4-waf-aligned) +- [WAF-aligned](#example-3-waf-aligned) ### Example 1: _Using only defaults_ @@ -215,97 +214,7 @@ module connection 'br/public:avm/res/web/connection:<version>' = { </details> <p> -### Example 3: _Using large parameter set_ - -This instance deploys the module with most of its features enabled. - - -<details> - -<summary>via Bicep module</summary> - -```bicep -module connection 'br/public:avm/res/web/connection:<version>' = { - name: 'connectionDeployment' - params: { - // Required parameters - displayName: 'Service Bus' - name: 'servicebus' - // Non-required parameters - api: { - id: '<id>' - } - location: '<location>' - parameterValueSet: { - name: 'managedIdentityAuth' - values: { - namespaceEndpoint: { - value: '<value>' - } - } - } - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } -} -``` - -</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 - "displayName": { - "value": "Service Bus" - }, - "name": { - "value": "servicebus" - }, - // Non-required parameters - "api": { - "value": { - "id": "<id>" - } - }, - "location": { - "value": "<location>" - }, - "parameterValueSet": { - "value": { - "name": "managedIdentityAuth", - "values": { - "namespaceEndpoint": { - "value": "<value>" - } - } - } - }, - "tags": { - "value": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - } -} -``` - -</details> -<p> - -### Example 4: _WAF-aligned_ +### Example 3: _WAF-aligned_ This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework. @@ -397,8 +306,8 @@ module connection 'br/public:avm/res/web/connection:<version>' = { | [`location`](#parameter-location) | string | Location of the deployment. | | [`lock`](#parameter-lock) | object | The lock settings of the service. | | [`nonSecretParameterValues`](#parameter-nonsecretparametervalues) | object | Dictionary of nonsecret parameter values. | -| [`parameterValues`](#parameter-parametervalues) | secureObject | Connection strings or access keys for connection. Example: 'accountName' and 'accessKey' when using blobs. It can change depending on the resource. | -| [`parameterValueSet`](#parameter-parametervalueset) | object | Additional parameter Value Set. | +| [`parameterValues`](#parameter-parametervalues) | secureObject | Connection strings or access keys for connection. Example: `accountName` and `accessKey` when using blobs. It can change depending on the resource. | +| [`parameterValueSet`](#parameter-parametervalueset) | object | Additional parameter Value Set used for authentication settings. | | [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | | [`statuses`](#parameter-statuses) | array | Status of the connection. | | [`tags`](#parameter-tags) | object | Tags of the resource. | @@ -425,80 +334,6 @@ Specific values for some API connections. - Required: No - Type: object -**Required parameters** - -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`id`](#parameter-apiid) | string | The ID of the API connection. | - -**Optional parameters** - -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`brandColor`](#parameter-apibrandcolor) | string | The Brand color. | -| [`description`](#parameter-apidescription) | string | The custom API description. | -| [`displayName`](#parameter-apidisplayname) | string | The display name of the API connection. | -| [`iconUri`](#parameter-apiiconuri) | string | The icon URI. | -| [`name`](#parameter-apiname) | string | The name of the API connection. | -| [`swagger`](#parameter-apiswagger) | string | The swagger URL. For Bicep, you can use the any() function. | -| [`type`](#parameter-apitype) | string | The resource reference type. | - -### Parameter: `api.id` - -The ID of the API connection. - -- Required: Yes -- Type: string - -### Parameter: `api.brandColor` - -The Brand color. - -- Required: No -- Type: string - -### Parameter: `api.description` - -The custom API description. - -- Required: No -- Type: string - -### Parameter: `api.displayName` - -The display name of the API connection. - -- Required: No -- Type: string - -### Parameter: `api.iconUri` - -The icon URI. - -- Required: No -- Type: string - -### Parameter: `api.name` - -The name of the API connection. - -- Required: No -- Type: string - -### Parameter: `api.swagger` - -The swagger URL. For Bicep, you can use the any() function. - -- Required: No -- Type: string - -### Parameter: `api.type` - -The resource reference type. - -- Required: No -- Type: string - ### Parameter: `customParameterValues` Dictionary of custom parameter values for specific connections. @@ -567,14 +402,14 @@ Dictionary of nonsecret parameter values. ### Parameter: `parameterValues` -Connection strings or access keys for connection. Example: 'accountName' and 'accessKey' when using blobs. It can change depending on the resource. +Connection strings or access keys for connection. Example: `accountName` and `accessKey` when using blobs. It can change depending on the resource. - Required: No - Type: secureObject ### Parameter: `parameterValueSet` -Additional parameter Value Set. +Additional parameter Value Set used for authentication settings. - Required: No - Type: object diff --git a/avm/res/web/connection/main.bicep b/avm/res/web/connection/main.bicep index 61c3d04b8d..2124c5e0cd 100644 --- a/avm/res/web/connection/main.bicep +++ b/avm/res/web/connection/main.bicep @@ -16,11 +16,16 @@ param enableTelemetry bool = true // ============ // @description('Optional. Specific values for some API connections.') -param api apiReferenceType? - -@description('Optional. The kind of the connection. `V1` for StandardLogicApp.') -@allowed(['V1', 'V2']) -param kind string +@metadata({ + example: ''' + // for a Service Bus connection + { + type: 'Microsoft.Web/locations/managedApis' + id: subscriptionResourceId('Microsoft.Web/locations/managedApis', '${resourceLocation}', 'servicebus') + } +''' +}) +param api object? @description('Optional. Dictionary of custom parameter values for specific connections.') param customParameterValues object? @@ -32,7 +37,7 @@ param displayName string #disable-next-line secure-secrets-in-params // Not a secret param nonSecretParameterValues object? -@description('Optional. Connection strings or access keys for connection. Example: \'accountName\' and \'accessKey\' when using blobs. It can change depending on the resource.') +@description('Optional. Connection strings or access keys for connection. Example: `accountName` and `accessKey` when using blobs. It can change depending on the resource.') @secure() @metadata({ example: ''' @@ -55,17 +60,27 @@ param nonSecretParameterValues object? }) param parameterValues object? -@allowed(['', 'Alternative']) -param alternativeParameterValues string? - @description('Optional. Additional parameter Value Set used for authentication settings.') +@metadata({ + example: ''' + // for a Service Bus connection + { + name: 'managedIdentityAuth' + values: { + namespaceEndpoint: { + value: 'sb://${dependency.outputs.serviceBusEndpoint}' + } + } + } +''' +}) param parameterValueSet object? @description('Optional. Array of role assignments to create.') param roleAssignments roleAssignmentType @description('Optional. Status of the connection.') -param statuses statusType[]? +param statuses array[]? @description('Optional. The lock settings of the service.') param lock lockType @@ -82,7 +97,7 @@ param lock lockType param tags object? @description('Optional. Links to test the API connection.') -param testLinks testLinkType[]? +param testLinks array[]? var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') @@ -103,7 +118,7 @@ var builtInRoleNames = { // ============== // resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { - name: '46d3xbcp.res.web-connection.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}' + name: take('46d3xbcp.res.web-connection.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}', 4) properties: { mode: 'Incremental' template: { @@ -123,8 +138,6 @@ resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableT resource connection 'Microsoft.Web/connections@2016-06-01' = { name: name location: location - #disable-next-line BCP187 - kind: kind tags: tags properties: { displayName: displayName @@ -132,8 +145,8 @@ resource connection 'Microsoft.Web/connections@2016-06-01' = { api: api parameterValues: !empty(parameterValues) ? parameterValues : null nonSecretParameterValues: !empty(nonSecretParameterValues) ? nonSecretParameterValues : null - testLinks: !empty(testLinks) ? testLinks : null - statuses: !empty(statuses) ? statuses : null + testLinks: testLinks + statuses: statuses #disable-next-line BCP037 parameterValueSet: parameterValueSet } @@ -220,65 +233,3 @@ type roleAssignmentType = { @description('Optional. The Resource Id of the delegated managed identity resource.') delegatedManagedIdentityResourceId: string? }[]? - -type apiReferenceType = { - @description('Optional. The Brand color.') - brandColor: string? - - @description('Optional. The custom API description.') - description: string? - - @description('Optional. The display name of the API connection.') - displayName: string? - - @description('Optional. The icon URI.') - iconUri: string? - - @description('Required. The ID of the API connection.') - id: string - - @description('Optional. The name of the API connection.') - name: string? - - @description('Optional. The swagger URL. For Bicep, you can use the any() function.') - swagger: string? - - @description('Optional. The resource reference type.') - 'type': string? -} - -type statusType = { - @description('Optional. The error of the connection.') - error: { - @description('Optional. The etag of the error.') - etag: string - - @description('Optional. The location of the resource.') - location: string - - @description('Optional. Connection Error Properties.') - properties: { - @description('Optional. Code of the status.') - code: string - - @description('Optional. Description of the status.') - message: string - } - - @description('Optional. The tags of the error.') - tags: object - } - @description('Optional. The status of the connection.') - status: string - - @description('Optional. The target of the error.') - target: string -} - -type testLinkType = { - @description('Optional. The HTTP Method.') - method: string - - @description('Optional. Test link request URI.') - requestUri: string -} diff --git a/avm/res/web/connection/main.json b/avm/res/web/connection/main.json index a2fa7ddde6..bb710ea916 100644 --- a/avm/res/web/connection/main.json +++ b/avm/res/web/connection/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.28.1.47646", - "templateHash": "2460380322221205337" + "templateHash": "9402688204918471482" }, "name": "API Connections", "description": "This module deploys an Azure API Connection.", @@ -103,153 +103,12 @@ } }, "nullable": true - }, - "apiReferenceType": { - "type": "object", - "properties": { - "brandColor": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Brand color." - } - }, - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The custom API description." - } - }, - "displayName": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The display name of the API connection." - } - }, - "iconUri": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The icon URI." - } - }, - "id": { - "type": "string", - "metadata": { - "description": "Required. The ID of the API connection." - } - }, - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name of the API connection." - } - }, - "swagger": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The swagger URL. For Bicep, you can use the any() function." - } - }, - "type": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The resource reference type." - } - } - } - }, - "statusType": { - "type": "object", - "properties": { - "error": { - "type": "object", - "properties": { - "etag": { - "type": "string", - "metadata": { - "description": "Optional. The etag of the error." - } - }, - "location": { - "type": "string", - "metadata": { - "description": "Optional. The location of the resource." - } - }, - "properties": { - "type": "object", - "properties": { - "code": { - "type": "string", - "metadata": { - "description": "Optional. Code of the status." - } - }, - "message": { - "type": "string", - "metadata": { - "description": "Optional. Description of the status." - } - } - }, - "metadata": { - "description": "Optional. Connection Error Properties." - } - }, - "tags": { - "type": "object", - "metadata": { - "description": "Optional. The tags of the error." - } - } - }, - "metadata": { - "description": "Optional. The error of the connection." - } - }, - "status": { - "type": "string", - "metadata": { - "description": "Optional. The status of the connection." - } - }, - "target": { - "type": "string", - "metadata": { - "description": "Optional. The target of the error." - } - } - } - }, - "testLinkType": { - "type": "object", - "properties": { - "method": { - "type": "string", - "metadata": { - "description": "Optional. The HTTP Method." - } - }, - "requestUri": { - "type": "string", - "metadata": { - "description": "Optional. Test link request URI." - } - } - } } }, "parameters": { "name": { "type": "string", "metadata": { - "example": "azureblob", "description": "Required. Connection name for connection. It can change depending on the resource." } }, @@ -268,9 +127,10 @@ } }, "api": { - "$ref": "#/definitions/apiReferenceType", + "type": "object", "nullable": true, "metadata": { + "example": " // for a Service Bus connection\n {\n type: 'Microsoft.Web/locations/managedApis'\n id: subscriptionResourceId('Microsoft.Web/locations/managedApis', '${resourceLocation}', 'servicebus')\n }\n", "description": "Optional. Specific values for some API connections." } }, @@ -298,15 +158,16 @@ "type": "secureObject", "nullable": true, "metadata": { - "example": " {\r\n //connectionString: '[listKeys(resourceId(parameters('servicebus_resourceGroup'),'Microsoft.ServiceBus/namespaces/AuthorizationRules', parameters('serviceBusName'), 'RootManageSharedAccessKey'),'2015-08-01').primaryConnectionString]'\r\n connectionString: 'list'\r\n }\r\n ", - "description": "Optional. Connection strings or access keys for connection. Example: 'accountName' and 'accessKey' when using blobs. It can change depending on the resource." + "example": " {\n connectionString: 'listKeys('/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/Microsoft.ServiceBus/namespaces/AuthorizationRules/<serviceBusName>/RootManagedSharedAccessKey', '2023-01-01').primaryConnectionString'\n }\n {\n rootfolder: fileshareConnection.rootfolder\n authType: fileshareConnection.authType\n // to add an object, use the any() function\n gateway: any({\n name: fileshareConnection.odgw.name\n id: resourceId(fileshareConnection.odgw.resourceGroup, 'Microsoft.Web/connectionGateways', fileshareConnection.odgw.name)\n type: 'Microsoft.Web/connectionGateways'\n })\n username: username\n password: password\n }\n ", + "description": "Optional. Connection strings or access keys for connection. Example: `accountName` and `accessKey` when using blobs. It can change depending on the resource." } }, "parameterValueSet": { "type": "object", "nullable": true, "metadata": { - "description": "Optional. Additional parameter Value Set." + "example": " // for a Service Bus connection\n {\n name: 'managedIdentityAuth'\n values: {\n namespaceEndpoint: {\n value: 'sb://${dependency.outputs.serviceBusEndpoint}'\n }\n }\n }\n", + "description": "Optional. Additional parameter Value Set used for authentication settings." } }, "roleAssignments": { @@ -318,7 +179,7 @@ "statuses": { "type": "array", "items": { - "$ref": "#/definitions/statusType" + "type": "array" }, "nullable": true, "metadata": { @@ -335,14 +196,14 @@ "type": "object", "nullable": true, "metadata": { - "example": " {\r\n key1: 'value1'\r\n key2: 'value2'\r\n }\r\n ", + "example": " {\n key1: 'value1'\n key2: 'value2'\n }\n ", "description": "Optional. Tags of the resource." } }, "testLinks": { "type": "array", "items": { - "$ref": "#/definitions/testLinkType" + "type": "array" }, "nullable": true, "metadata": { @@ -364,7 +225,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2023-07-01", - "name": "[format('46d3xbcp.res.web-connection.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[take(format('46d3xbcp.res.web-connection.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4)), 4)]", "properties": { "mode": "Incremental", "template": { @@ -390,8 +251,8 @@ "displayName": "[parameters('displayName')]", "customParameterValues": "[parameters('customParameterValues')]", "api": "[parameters('api')]", - "parameterValues": "[parameters('parameterValues')]", - "nonSecretParameterValues": "[parameters('nonSecretParameterValues')]", + "parameterValues": "[if(not(empty(parameters('parameterValues'))), parameters('parameterValues'), null())]", + "nonSecretParameterValues": "[if(not(empty(parameters('nonSecretParameterValues'))), parameters('nonSecretParameterValues'), null())]", "testLinks": "[parameters('testLinks')]", "statuses": "[parameters('statuses')]", "parameterValueSet": "[parameters('parameterValueSet')]" @@ -464,4 +325,4 @@ "value": "[reference('connection', '2016-06-01', 'full').location]" } } -} +} \ No newline at end of file diff --git a/avm/res/web/connection/tests/e2e/servicebus/dependencies.bicep b/avm/res/web/connection/tests/e2e/servicebus/dependencies.bicep deleted file mode 100644 index 43c0ee1585..0000000000 --- a/avm/res/web/connection/tests/e2e/servicebus/dependencies.bicep +++ /dev/null @@ -1,102 +0,0 @@ -@description('Optional. The location to deploy to.') -param location string = resourceGroup().location - -@description('Required. The name of the Managed Identity to create.') -param managedIdentityName string - -param serviceBusNamespaceName string - -var messageRoutingTopic = 'topic1' - -resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location -} - -resource serviceBusNamespace 'Microsoft.ServiceBus/namespaces@2021-11-01' = { - name: serviceBusNamespaceName - location: location - sku: { - name: 'Standard' - capacity: 1 - tier: 'Standard' - } - properties: {} - // identity: { - // type: 'UserAssigned' - // userAssignedIdentities: { - // '${managedIdentity.id}': {} - // } - // } - - resource authorizationRule 'authorizationRules@2021-11-01' = { - name: 'RootManageSharedAccessKey' - properties: { - rights: [ - 'Listen' - 'Send' - 'Manage' - ] - } - } - - resource topics 'topics@2021-11-01' = { - name: messageRoutingTopic - properties: { - requiresDuplicateDetection: false - enableBatchedOperations: true - status: 'Active' - supportOrdering: false - enablePartitioning: true - enableExpress: false - } - - resource ubscription 'subscriptions@2021-11-01' = { - name: 'subscription1' - properties: { - lockDuration: 'PT5M' - requiresSession: false - deadLetteringOnMessageExpiration: false - deadLetteringOnFilterEvaluationExceptions: true - defaultMessageTimeToLive: 'P10675199DT2H48M5.4775807S' - autoDeleteOnIdle: 'P10675199DT2H48M5.4775807S' - enableBatchedOperations: true - status: 'Active' - } - } - } -} - -resource sbPermissionsReader 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid('msi-${managedIdentity.name}-ServiceBus-DataReceiver-RoleAssignment') - scope: serviceBusNamespace - properties: { - principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId( - 'Microsoft.Authorization/roleDefinitions', - '4f6d3b9b-027b-4f4c-9142-0e5a2a2247e0' - ) // Azure Service Bus Data Receiver - principalType: 'ServicePrincipal' - } -} - -resource sbPermissionsSender 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid('msi-${managedIdentity.name}-ServiceBus-DataSender-RoleAssignment') - scope: serviceBusNamespace - properties: { - principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId( - 'Microsoft.Authorization/roleDefinitions', - '69a216fc-b8fb-44d8-bc22-1f3c2cd27a39' - ) // Azure Service Bus Data Sender - principalType: 'ServicePrincipal' - } -} -@description('The principal ID of the created Managed Identity.') -output managedIdentityPrincipalId string = managedIdentity.properties.principalId - -output serviceBusResourceId string = serviceBusNamespace.id - -output serviceBusName string = serviceBusNamespace.name - -output serviceBusEndpoint string = serviceBusNamespace.properties.serviceBusEndpoint diff --git a/avm/res/web/connection/tests/e2e/servicebus/main.test.bicep b/avm/res/web/connection/tests/e2e/servicebus/main.test.bicep deleted file mode 100644 index fe204fe995..0000000000 --- a/avm/res/web/connection/tests/e2e/servicebus/main.test.bicep +++ /dev/null @@ -1,76 +0,0 @@ -targetScope = 'subscription' - -metadata name = 'Using a Service Bus connection' -metadata description = 'This instance deploys the module with a connection to Service Bus.' - -// ========== // -// Parameters // -// ========== // - -@description('Optional. The name of the resource group to deploy for testing purposes.') -@maxLength(90) -param resourceGroupName string = 'dep-${namePrefix}-web.connections-${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 = 'wcsb' - -@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: resourceLocation -} - -module nestedDependencies 'dependencies.bicep' = { - scope: resourceGroup - name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' - params: { - managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' - location: resourceLocation - serviceBusNamespaceName: 'dep-${namePrefix}-sb-${serviceShort}' - } -} - -// ============== // -// Test Execution // -// ============== // - -@batchSize(1) -module testDeployment '../../../main.bicep' = [ - for iteration in ['init', 'idem']: { - scope: resourceGroup - name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' - params: { - displayName: 'Service Bus' - name: 'servicebus' - location: resourceLocation - api: { - type: 'Microsoft.Web/locations/managedApis' - id: subscriptionResourceId('Microsoft.Web/locations/managedApis', '${resourceLocation}', 'servicebus') - } - parameterValueSet: { - name: 'managedIdentityAuth' - values: { - namespaceEndpoint: { - value: 'sb://${nestedDependencies.outputs.serviceBusEndpoint}' - } - } - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - } - } -] From 7759910e2d25ffe22de87c9b8092ae34998c59a2 Mon Sep 17 00:00:00 2001 From: ReneHezser <rene@hezser.de> Date: Tue, 18 Jun 2024 10:40:57 +0200 Subject: [PATCH 4/8] chore: Update version.json to 0.2 --- avm/res/web/connection/version.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/res/web/connection/version.json b/avm/res/web/connection/version.json index 83083db694..1c035df49f 100644 --- a/avm/res/web/connection/version.json +++ b/avm/res/web/connection/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.1", + "version": "0.2", "pathFilters": [ "./main.json" ] From a161ce16adebefc396bfc173469853c73c55d485 Mon Sep 17 00:00:00 2001 From: ReneHezser <rene@hezser.de> Date: Wed, 19 Jun 2024 08:20:42 +0200 Subject: [PATCH 5/8] small changes --- avm/res/web/connection/main.bicep | 10 +++++----- avm/res/web/connection/main.json | 12 +++--------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/avm/res/web/connection/main.bicep b/avm/res/web/connection/main.bicep index 2124c5e0cd..d0e871f0ce 100644 --- a/avm/res/web/connection/main.bicep +++ b/avm/res/web/connection/main.bicep @@ -80,7 +80,7 @@ param parameterValueSet object? param roleAssignments roleAssignmentType @description('Optional. Status of the connection.') -param statuses array[]? +param statuses array? @description('Optional. The lock settings of the service.') param lock lockType @@ -97,7 +97,7 @@ param lock lockType param tags object? @description('Optional. Links to test the API connection.') -param testLinks array[]? +param testLinks array? var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') @@ -143,11 +143,11 @@ resource connection 'Microsoft.Web/connections@2016-06-01' = { displayName: displayName customParameterValues: customParameterValues api: api - parameterValues: !empty(parameterValues) ? parameterValues : null - nonSecretParameterValues: !empty(nonSecretParameterValues) ? nonSecretParameterValues : null + parameterValues: parameterValues + nonSecretParameterValues: nonSecretParameterValues testLinks: testLinks statuses: statuses - #disable-next-line BCP037 + #disable-next-line BCP037 // the parameterValueSet is not yet made available in the resource provider, which generates warnings. Disable the warning for now. parameterValueSet: parameterValueSet } } diff --git a/avm/res/web/connection/main.json b/avm/res/web/connection/main.json index bb710ea916..178eb7af63 100644 --- a/avm/res/web/connection/main.json +++ b/avm/res/web/connection/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.28.1.47646", - "templateHash": "9402688204918471482" + "templateHash": "14422693215555410586" }, "name": "API Connections", "description": "This module deploys an Azure API Connection.", @@ -178,9 +178,6 @@ }, "statuses": { "type": "array", - "items": { - "type": "array" - }, "nullable": true, "metadata": { "description": "Optional. Status of the connection." @@ -202,9 +199,6 @@ }, "testLinks": { "type": "array", - "items": { - "type": "array" - }, "nullable": true, "metadata": { "description": "Optional. Links to test the API connection." @@ -251,8 +245,8 @@ "displayName": "[parameters('displayName')]", "customParameterValues": "[parameters('customParameterValues')]", "api": "[parameters('api')]", - "parameterValues": "[if(not(empty(parameters('parameterValues'))), parameters('parameterValues'), null())]", - "nonSecretParameterValues": "[if(not(empty(parameters('nonSecretParameterValues'))), parameters('nonSecretParameterValues'), null())]", + "parameterValues": "[parameters('parameterValues')]", + "nonSecretParameterValues": "[parameters('nonSecretParameterValues')]", "testLinks": "[parameters('testLinks')]", "statuses": "[parameters('statuses')]", "parameterValueSet": "[parameters('parameterValueSet')]" From 3fc8a9db003cc126288552edd16f57cc173e050d Mon Sep 17 00:00:00 2001 From: ReneHezser <rene@hezser.de> Date: Wed, 19 Jun 2024 09:38:30 +0200 Subject: [PATCH 6/8] parameter changes --- avm/res/web/connection/main.bicep | 4 ++-- avm/res/web/connection/main.json | 18 ++++++++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/avm/res/web/connection/main.bicep b/avm/res/web/connection/main.bicep index d0e871f0ce..b0a0150d0b 100644 --- a/avm/res/web/connection/main.bicep +++ b/avm/res/web/connection/main.bicep @@ -80,7 +80,7 @@ param parameterValueSet object? param roleAssignments roleAssignmentType @description('Optional. Status of the connection.') -param statuses array? +param statuses object[]? @description('Optional. The lock settings of the service.') param lock lockType @@ -97,7 +97,7 @@ param lock lockType param tags object? @description('Optional. Links to test the API connection.') -param testLinks array? +param testLinks object[]? var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') diff --git a/avm/res/web/connection/main.json b/avm/res/web/connection/main.json index 178eb7af63..487e508338 100644 --- a/avm/res/web/connection/main.json +++ b/avm/res/web/connection/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.28.1.47646", - "templateHash": "14422693215555410586" + "templateHash": "17780492072403055036" }, "name": "API Connections", "description": "This module deploys an Azure API Connection.", @@ -130,7 +130,7 @@ "type": "object", "nullable": true, "metadata": { - "example": " // for a Service Bus connection\n {\n type: 'Microsoft.Web/locations/managedApis'\n id: subscriptionResourceId('Microsoft.Web/locations/managedApis', '${resourceLocation}', 'servicebus')\n }\n", + "example": " // for a Service Bus connection\r\n {\r\n type: 'Microsoft.Web/locations/managedApis'\r\n id: subscriptionResourceId('Microsoft.Web/locations/managedApis', '${resourceLocation}', 'servicebus')\r\n }\r\n", "description": "Optional. Specific values for some API connections." } }, @@ -158,7 +158,7 @@ "type": "secureObject", "nullable": true, "metadata": { - "example": " {\n connectionString: 'listKeys('/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/Microsoft.ServiceBus/namespaces/AuthorizationRules/<serviceBusName>/RootManagedSharedAccessKey', '2023-01-01').primaryConnectionString'\n }\n {\n rootfolder: fileshareConnection.rootfolder\n authType: fileshareConnection.authType\n // to add an object, use the any() function\n gateway: any({\n name: fileshareConnection.odgw.name\n id: resourceId(fileshareConnection.odgw.resourceGroup, 'Microsoft.Web/connectionGateways', fileshareConnection.odgw.name)\n type: 'Microsoft.Web/connectionGateways'\n })\n username: username\n password: password\n }\n ", + "example": " {\r\n connectionString: 'listKeys('/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/Microsoft.ServiceBus/namespaces/AuthorizationRules/<serviceBusName>/RootManagedSharedAccessKey', '2023-01-01').primaryConnectionString'\r\n }\r\n {\r\n rootfolder: fileshareConnection.rootfolder\r\n authType: fileshareConnection.authType\r\n // to add an object, use the any() function\r\n gateway: any({\r\n name: fileshareConnection.odgw.name\r\n id: resourceId(fileshareConnection.odgw.resourceGroup, 'Microsoft.Web/connectionGateways', fileshareConnection.odgw.name)\r\n type: 'Microsoft.Web/connectionGateways'\r\n })\r\n username: username\r\n password: password\r\n }\r\n ", "description": "Optional. Connection strings or access keys for connection. Example: `accountName` and `accessKey` when using blobs. It can change depending on the resource." } }, @@ -166,7 +166,7 @@ "type": "object", "nullable": true, "metadata": { - "example": " // for a Service Bus connection\n {\n name: 'managedIdentityAuth'\n values: {\n namespaceEndpoint: {\n value: 'sb://${dependency.outputs.serviceBusEndpoint}'\n }\n }\n }\n", + "example": " // for a Service Bus connection\r\n {\r\n name: 'managedIdentityAuth'\r\n values: {\r\n namespaceEndpoint: {\r\n value: 'sb://${dependency.outputs.serviceBusEndpoint}'\r\n }\r\n }\r\n }\r\n", "description": "Optional. Additional parameter Value Set used for authentication settings." } }, @@ -178,6 +178,9 @@ }, "statuses": { "type": "array", + "items": { + "type": "object" + }, "nullable": true, "metadata": { "description": "Optional. Status of the connection." @@ -193,12 +196,15 @@ "type": "object", "nullable": true, "metadata": { - "example": " {\n key1: 'value1'\n key2: 'value2'\n }\n ", + "example": " {\r\n key1: 'value1'\r\n key2: 'value2'\r\n }\r\n ", "description": "Optional. Tags of the resource." } }, "testLinks": { "type": "array", + "items": { + "type": "object" + }, "nullable": true, "metadata": { "description": "Optional. Links to test the API connection." @@ -319,4 +325,4 @@ "value": "[reference('connection', '2016-06-01', 'full').location]" } } -} \ No newline at end of file +} From 88199b1b723241cb7594dbe151873905b28c7bfc Mon Sep 17 00:00:00 2001 From: ReneHezser <rene@hezser.de> Date: Wed, 19 Jun 2024 09:56:35 +0200 Subject: [PATCH 7/8] annoying line breaks --- avm/res/web/connection/README.md | 4 ++-- avm/res/web/connection/main.bicep | 2 +- avm/res/web/connection/main.json | 14 +++++++------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/avm/res/web/connection/README.md b/avm/res/web/connection/README.md index 6fbc5a62c3..e64e979609 100644 --- a/avm/res/web/connection/README.md +++ b/avm/res/web/connection/README.md @@ -309,7 +309,7 @@ module connection 'br/public:avm/res/web/connection:<version>' = { | [`parameterValues`](#parameter-parametervalues) | secureObject | Connection strings or access keys for connection. Example: `accountName` and `accessKey` when using blobs. It can change depending on the resource. | | [`parameterValueSet`](#parameter-parametervalueset) | object | Additional parameter Value Set used for authentication settings. | | [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | -| [`statuses`](#parameter-statuses) | array | Status of the connection. | +| [`statuses`](#parameter-statuses) | array | The status of the connection. | | [`tags`](#parameter-tags) | object | Tags of the resource. | | [`testLinks`](#parameter-testlinks) | array | Links to test the API connection. | @@ -505,7 +505,7 @@ The principal type of the assigned principal ID. ### Parameter: `statuses` -Status of the connection. +The status of the connection. - Required: No - Type: array diff --git a/avm/res/web/connection/main.bicep b/avm/res/web/connection/main.bicep index b0a0150d0b..e068b3b69c 100644 --- a/avm/res/web/connection/main.bicep +++ b/avm/res/web/connection/main.bicep @@ -79,7 +79,7 @@ param parameterValueSet object? @description('Optional. Array of role assignments to create.') param roleAssignments roleAssignmentType -@description('Optional. Status of the connection.') +@description('Optional. The status of the connection.') param statuses object[]? @description('Optional. The lock settings of the service.') diff --git a/avm/res/web/connection/main.json b/avm/res/web/connection/main.json index 487e508338..54b41c63f1 100644 --- a/avm/res/web/connection/main.json +++ b/avm/res/web/connection/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.28.1.47646", - "templateHash": "17780492072403055036" + "templateHash": "8299633375832706187" }, "name": "API Connections", "description": "This module deploys an Azure API Connection.", @@ -130,7 +130,7 @@ "type": "object", "nullable": true, "metadata": { - "example": " // for a Service Bus connection\r\n {\r\n type: 'Microsoft.Web/locations/managedApis'\r\n id: subscriptionResourceId('Microsoft.Web/locations/managedApis', '${resourceLocation}', 'servicebus')\r\n }\r\n", + "example": " // for a Service Bus connection\n {\n type: 'Microsoft.Web/locations/managedApis'\n id: subscriptionResourceId('Microsoft.Web/locations/managedApis', '${resourceLocation}', 'servicebus')\n }\n", "description": "Optional. Specific values for some API connections." } }, @@ -158,7 +158,7 @@ "type": "secureObject", "nullable": true, "metadata": { - "example": " {\r\n connectionString: 'listKeys('/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/Microsoft.ServiceBus/namespaces/AuthorizationRules/<serviceBusName>/RootManagedSharedAccessKey', '2023-01-01').primaryConnectionString'\r\n }\r\n {\r\n rootfolder: fileshareConnection.rootfolder\r\n authType: fileshareConnection.authType\r\n // to add an object, use the any() function\r\n gateway: any({\r\n name: fileshareConnection.odgw.name\r\n id: resourceId(fileshareConnection.odgw.resourceGroup, 'Microsoft.Web/connectionGateways', fileshareConnection.odgw.name)\r\n type: 'Microsoft.Web/connectionGateways'\r\n })\r\n username: username\r\n password: password\r\n }\r\n ", + "example": " {\n connectionString: 'listKeys('/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/Microsoft.ServiceBus/namespaces/AuthorizationRules/<serviceBusName>/RootManagedSharedAccessKey', '2023-01-01').primaryConnectionString'\n }\n {\n rootfolder: fileshareConnection.rootfolder\n authType: fileshareConnection.authType\n // to add an object, use the any() function\n gateway: any({\n name: fileshareConnection.odgw.name\n id: resourceId(fileshareConnection.odgw.resourceGroup, 'Microsoft.Web/connectionGateways', fileshareConnection.odgw.name)\n type: 'Microsoft.Web/connectionGateways'\n })\n username: username\n password: password\n }\n ", "description": "Optional. Connection strings or access keys for connection. Example: `accountName` and `accessKey` when using blobs. It can change depending on the resource." } }, @@ -166,7 +166,7 @@ "type": "object", "nullable": true, "metadata": { - "example": " // for a Service Bus connection\r\n {\r\n name: 'managedIdentityAuth'\r\n values: {\r\n namespaceEndpoint: {\r\n value: 'sb://${dependency.outputs.serviceBusEndpoint}'\r\n }\r\n }\r\n }\r\n", + "example": " // for a Service Bus connection\n {\n name: 'managedIdentityAuth'\n values: {\n namespaceEndpoint: {\n value: 'sb://${dependency.outputs.serviceBusEndpoint}'\n }\n }\n }\n", "description": "Optional. Additional parameter Value Set used for authentication settings." } }, @@ -183,7 +183,7 @@ }, "nullable": true, "metadata": { - "description": "Optional. Status of the connection." + "description": "Optional. The status of the connection." } }, "lock": { @@ -196,7 +196,7 @@ "type": "object", "nullable": true, "metadata": { - "example": " {\r\n key1: 'value1'\r\n key2: 'value2'\r\n }\r\n ", + "example": " {\n key1: 'value1'\n key2: 'value2'\n }\n ", "description": "Optional. Tags of the resource." } }, @@ -325,4 +325,4 @@ "value": "[reference('connection', '2016-06-01', 'full').location]" } } -} +} \ No newline at end of file From 082cb210862252b2f970f21a17609c850f406966 Mon Sep 17 00:00:00 2001 From: ReneHezser <rene@hezser.de> Date: Fri, 21 Jun 2024 14:24:09 +0200 Subject: [PATCH 8/8] updates json after merge --- avm/res/web/connection/main.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/res/web/connection/main.json b/avm/res/web/connection/main.json index 64fe101b67..dad6241d48 100644 --- a/avm/res/web/connection/main.json +++ b/avm/res/web/connection/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.28.1.47646", - "templateHash": "16876360500243904943" + "templateHash": "4760344619510029018" }, "name": "API Connections", "description": "This module deploys an Azure API Connection.",