From 073f92ef123d80ed04e359d03ff175582ffa9047 Mon Sep 17 00:00:00 2001 From: Nate Arnold Date: Thu, 22 Aug 2024 01:53:57 -0600 Subject: [PATCH] fix: `avm/res/db for postgre sql/flexible server` (#3080) ## Description Added "highAvailability: 'ZoneRedundant'" to default test to fix broken pipeline. Added updated role assignment logic to conform with new AVM specification. Fixes #2388 Closes #2388 ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.db-for-postgre-sql.flexible-server](https://github.com/arnoldna/bicep-registry-modules/actions/workflows/avm.res.db-for-postgre-sql.flexible-server.yml/badge.svg?branch=avm%2Fres%2Fdb-for-postgre-sql%2Fflexible-server)](https://github.com/arnoldna/bicep-registry-modules/actions/workflows/avm.res.db-for-postgre-sql.flexible-server.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting 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`. - [X] 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 --- .../flexible-server/README.md | 70 +++++-- .../flexible-server/administrator/main.json | 4 +- .../flexible-server/configuration/main.json | 4 +- .../flexible-server/database/main.json | 4 +- .../flexible-server/firewall-rule/main.json | 4 +- .../flexible-server/main.bicep | 41 ++-- .../flexible-server/main.json | 79 +++++--- .../tests/e2e/defaults/dependencies.bicep | 16 ++ .../tests/e2e/defaults/main.test.bicep | 44 +++-- .../tests/e2e/public/main.test.bicep | 187 +++++++++--------- .../tests/e2e/waf-aligned/main.test.bicep | 119 +++++------ 11 files changed, 350 insertions(+), 222 deletions(-) create mode 100644 avm/res/db-for-postgre-sql/flexible-server/tests/e2e/defaults/dependencies.bicep diff --git a/avm/res/db-for-postgre-sql/flexible-server/README.md b/avm/res/db-for-postgre-sql/flexible-server/README.md index 6986b8fee6..6603dd7d6c 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/README.md +++ b/avm/res/db-for-postgre-sql/flexible-server/README.md @@ -53,12 +53,18 @@ module flexibleServer 'br/public:avm/res/db-for-postgre-sql/flexible-server:' + administrators: [ + { + objectId: '' + principalName: '' + principalType: 'ServicePrincipal' + } + ] geoRedundantBackup: 'Enabled' + highAvailability: 'ZoneRedundant' location: '' } } @@ -81,21 +87,27 @@ module flexibleServer 'br/public:avm/res/db-for-postgre-sql/flexible-server:" + "administrators": { + "value": [ + { + "objectId": "", + "principalName": "", + "principalType": "ServicePrincipal" + } + ] }, "geoRedundantBackup": { "value": "Enabled" }, + "highAvailability": { + "value": "ZoneRedundant" + }, "location": { "value": "" } @@ -697,7 +709,14 @@ module flexibleServer 'br/public:avm/res/db-for-postgre-sql/flexible-server:' + maintenanceWindow: { + customWindow: 'Enabled' + dayOfWeek: 0 + startHour: 1 + startMinute: 0 + } privateDnsZoneArmResourceId: '' tags: { Environment: 'Non-Prod' @@ -782,9 +801,20 @@ module flexibleServer 'br/public:avm/res/db-for-postgre-sql/flexible-server:" }, + "maintenanceWindow": { + "value": { + "customWindow": "Enabled", + "dayOfWeek": 0, + "startHour": 1, + "startMinute": 0 + } + }, "privateDnsZoneArmResourceId": { "value": "" }, @@ -1314,7 +1344,15 @@ Properties for the maintenence window. If provided, 'customWindow' property must - Required: No - Type: object -- Default: `{}` +- Default: + ```Bicep + { + customWindow: 'Enabled' + dayOfWeek: 0 + startHour: 1 + startMinute: 0 + } + ``` ### Parameter: `passwordAuth` @@ -1361,6 +1399,7 @@ Array of role assignments to create. | [`conditionVersion`](#parameter-roleassignmentsconditionversion) | string | Version of the condition. | | [`delegatedManagedIdentityResourceId`](#parameter-roleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | | [`description`](#parameter-roleassignmentsdescription) | string | The description of the role assignment. | +| [`name`](#parameter-roleassignmentsname) | string | The name (as GUID) of the role assignment. If not provided, a GUID will be generated. | | [`principalType`](#parameter-roleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | ### Parameter: `roleAssignments.principalId` @@ -1411,6 +1450,13 @@ The description of the role assignment. - Required: No - Type: string +### Parameter: `roleAssignments.name` + +The name (as GUID) of the role assignment. If not provided, a GUID will be generated. + +- Required: No +- Type: string + ### Parameter: `roleAssignments.principalType` The principal type of the assigned principal ID. diff --git a/avm/res/db-for-postgre-sql/flexible-server/administrator/main.json b/avm/res/db-for-postgre-sql/flexible-server/administrator/main.json index 69197e9646..b7337b4766 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/administrator/main.json +++ b/avm/res/db-for-postgre-sql/flexible-server/administrator/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "17302939650459446486" + "version": "0.29.47.4906", + "templateHash": "9786947819042824705" }, "name": "DBforPostgreSQL Flexible Server Administrators", "description": "This module deploys a DBforPostgreSQL Flexible Server Administrator.", diff --git a/avm/res/db-for-postgre-sql/flexible-server/configuration/main.json b/avm/res/db-for-postgre-sql/flexible-server/configuration/main.json index 82ff31c783..8903e9ef21 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/configuration/main.json +++ b/avm/res/db-for-postgre-sql/flexible-server/configuration/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "4808844582468160626" + "version": "0.29.47.4906", + "templateHash": "3802666632340288344" }, "name": "DBforPostgreSQL Flexible Server Configurations", "description": "This module deploys a DBforPostgreSQL Flexible Server Configuration.", diff --git a/avm/res/db-for-postgre-sql/flexible-server/database/main.json b/avm/res/db-for-postgre-sql/flexible-server/database/main.json index a628aabe2a..1b15b5c7a4 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/database/main.json +++ b/avm/res/db-for-postgre-sql/flexible-server/database/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "12256776332622303948" + "version": "0.29.47.4906", + "templateHash": "17501165975344742322" }, "name": "DBforPostgreSQL Flexible Server Databases", "description": "This module deploys a DBforPostgreSQL Flexible Server Database.", diff --git a/avm/res/db-for-postgre-sql/flexible-server/firewall-rule/main.json b/avm/res/db-for-postgre-sql/flexible-server/firewall-rule/main.json index b7c6ec5209..572f886bfe 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/firewall-rule/main.json +++ b/avm/res/db-for-postgre-sql/flexible-server/firewall-rule/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "12309357869547394167" + "version": "0.29.47.4906", + "templateHash": "5110779562094536429" }, "name": "DBforPostgreSQL Flexible Server Firewall Rules", "description": "This module deploys a DBforPostgreSQL Flexible Server Firewall Rule.", diff --git a/avm/res/db-for-postgre-sql/flexible-server/main.bicep b/avm/res/db-for-postgre-sql/flexible-server/main.bicep index 58f76dcdfe..f8e16c5582 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/main.bicep +++ b/avm/res/db-for-postgre-sql/flexible-server/main.bicep @@ -117,7 +117,12 @@ param managedIdentities managedIdentitiesType param customerManagedKey customerManagedKeyType @description('Optional. Properties for the maintenence window. If provided, \'customWindow\' property must exist and set to \'Enabled\'.') -param maintenanceWindow object = {} +param maintenanceWindow object = { + customWindow: 'Enabled' + dayOfWeek: 0 + startHour: 1 + startMinute: 0 +} @description('Conditional. Required if \'createMode\' is set to \'PointInTimeRestore\'.') param pointInTimeUTC string = '' @@ -182,6 +187,17 @@ var builtInRoleNames = { ) } +var formattedRoleAssignments = [ + for (roleAssignment, index) in (roleAssignments ?? []): union(roleAssignment, { + roleDefinitionId: builtInRoleNames[?roleAssignment.roleDefinitionIdOrName] ?? (contains( + roleAssignment.roleDefinitionIdOrName, + '/providers/Microsoft.Authorization/roleDefinitions/' + ) + ? roleAssignment.roleDefinitionIdOrName + : subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleAssignment.roleDefinitionIdOrName)) + }) +] + #disable-next-line no-deployments-resources resource avmTelemetry 'Microsoft.Resources/deployments@2024-03-01' = if (enableTelemetry) { name: '46d3xbcp.res.dbforpostgresql-flexibleserver.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}' @@ -292,14 +308,10 @@ resource flexibleServer_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!e } resource flexibleServer_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ - for (roleAssignment, index) in (roleAssignments ?? []): { - name: guid(flexibleServer.id, roleAssignment.principalId, roleAssignment.roleDefinitionIdOrName) + for (roleAssignment, index) in (formattedRoleAssignments ?? []): { + name: roleAssignment.?name ?? guid(flexibleServer.id, roleAssignment.principalId, roleAssignment.roleDefinitionId) properties: { - roleDefinitionId: contains(builtInRoleNames, roleAssignment.roleDefinitionIdOrName) - ? builtInRoleNames[roleAssignment.roleDefinitionIdOrName] - : contains(roleAssignment.roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/') - ? roleAssignment.roleDefinitionIdOrName - : subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleAssignment.roleDefinitionIdOrName) + roleDefinitionId: roleAssignment.roleDefinitionId principalId: roleAssignment.principalId description: roleAssignment.?description principalType: roleAssignment.?principalType @@ -317,8 +329,8 @@ module flexibleServer_databases 'database/main.bicep' = [ params: { name: database.name flexibleServerName: flexibleServer.name - collation: contains(database, 'collation') ? database.collation : '' - charset: contains(database, 'charset') ? database.charset : '' + collation: database.?collation ?? '' + charset: database.?charset ?? '' } } ] @@ -345,8 +357,8 @@ module flexibleServer_configurations 'configuration/main.bicep' = [ params: { name: configuration.name flexibleServerName: flexibleServer.name - source: contains(configuration, 'source') ? configuration.source : '' - value: contains(configuration, 'value') ? configuration.value : '' + source: configuration.?source ?? '' + value: configuration.?value ?? '' } dependsOn: [ flexibleServer_firewallRules @@ -362,7 +374,7 @@ module flexibleServer_administrators 'administrator/main.bicep' = [ objectId: administrator.objectId principalName: administrator.principalName principalType: administrator.principalType - tenantId: contains(administrator, 'tenantId') ? administrator.tenantId : tenant().tenantId + tenantId: administrator.?tenantId ?? tenant().tenantId } } ] @@ -429,6 +441,9 @@ type lockType = { }? type roleAssignmentType = { + @description('Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated.') + name: string? + @description('Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') roleDefinitionIdOrName: string diff --git a/avm/res/db-for-postgre-sql/flexible-server/main.json b/avm/res/db-for-postgre-sql/flexible-server/main.json index f89dcb945d..38e387fbae 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/main.json +++ b/avm/res/db-for-postgre-sql/flexible-server/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "6917599378543885817" + "version": "0.29.47.4906", + "templateHash": "11155893103946575130" }, "name": "DBforPostgreSQL Flexible Servers", "description": "This module deploys a DBforPostgreSQL Flexible Server.", @@ -58,6 +58,13 @@ "items": { "type": "object", "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, "roleDefinitionIdOrName": { "type": "string", "metadata": { @@ -457,7 +464,12 @@ }, "maintenanceWindow": { "type": "object", - "defaultValue": {}, + "defaultValue": { + "customWindow": "Enabled", + "dayOfWeek": 0, + "startHour": 1, + "startMinute": 0 + }, "metadata": { "description": "Optional. Properties for the maintenence window. If provided, 'customWindow' property must exist and set to 'Enabled'." } @@ -545,6 +557,13 @@ } }, "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]", "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'UserAssigned', 'None'), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]", "builtInRoleNames": { @@ -667,20 +686,20 @@ "flexibleServer_roleAssignments": { "copy": { "name": "flexibleServer_roleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" }, "type": "Microsoft.Authorization/roleAssignments", "apiVersion": "2022-04-01", "scope": "[format('Microsoft.DBforPostgreSQL/flexibleServers/{0}', parameters('name'))]", - "name": "[guid(resourceId('Microsoft.DBforPostgreSQL/flexibleServers', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.DBforPostgreSQL/flexibleServers', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", "properties": { - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", - "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", - "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", - "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", - "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", - "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", - "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" }, "dependsOn": [ "flexibleServer" @@ -747,8 +766,12 @@ "flexibleServerName": { "value": "[parameters('name')]" }, - "collation": "[if(contains(parameters('databases')[copyIndex()], 'collation'), createObject('value', parameters('databases')[copyIndex()].collation), createObject('value', ''))]", - "charset": "[if(contains(parameters('databases')[copyIndex()], 'charset'), createObject('value', parameters('databases')[copyIndex()].charset), createObject('value', ''))]" + "collation": { + "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'collation'), '')]" + }, + "charset": { + "value": "[coalesce(tryGet(parameters('databases')[copyIndex()], 'charset'), '')]" + } }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", @@ -756,8 +779,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "6060199938382421423" + "version": "0.29.47.4906", + "templateHash": "17501165975344742322" }, "name": "DBforPostgreSQL Flexible Server Databases", "description": "This module deploys a DBforPostgreSQL Flexible Server Database.", @@ -864,8 +887,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "18047073594923038356" + "version": "0.29.47.4906", + "templateHash": "5110779562094536429" }, "name": "DBforPostgreSQL Flexible Server Firewall Rules", "description": "This module deploys a DBforPostgreSQL Flexible Server Firewall Rule.", @@ -960,8 +983,12 @@ "flexibleServerName": { "value": "[parameters('name')]" }, - "source": "[if(contains(parameters('configurations')[copyIndex()], 'source'), createObject('value', parameters('configurations')[copyIndex()].source), createObject('value', ''))]", - "value": "[if(contains(parameters('configurations')[copyIndex()], 'value'), createObject('value', parameters('configurations')[copyIndex()].value), createObject('value', ''))]" + "source": { + "value": "[coalesce(tryGet(parameters('configurations')[copyIndex()], 'source'), '')]" + }, + "value": { + "value": "[coalesce(tryGet(parameters('configurations')[copyIndex()], 'value'), '')]" + } }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", @@ -969,8 +996,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "1739518705583408324" + "version": "0.29.47.4906", + "templateHash": "3802666632340288344" }, "name": "DBforPostgreSQL Flexible Server Configurations", "description": "This module deploys a DBforPostgreSQL Flexible Server Configuration.", @@ -1071,7 +1098,9 @@ "principalType": { "value": "[parameters('administrators')[copyIndex()].principalType]" }, - "tenantId": "[if(contains(parameters('administrators')[copyIndex()], 'tenantId'), createObject('value', parameters('administrators')[copyIndex()].tenantId), createObject('value', tenant().tenantId))]" + "tenantId": { + "value": "[coalesce(tryGet(parameters('administrators')[copyIndex()], 'tenantId'), tenant().tenantId)]" + } }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", @@ -1079,8 +1108,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "18164580138640455419" + "version": "0.29.47.4906", + "templateHash": "9786947819042824705" }, "name": "DBforPostgreSQL Flexible Server Administrators", "description": "This module deploys a DBforPostgreSQL Flexible Server Administrator.", diff --git a/avm/res/db-for-postgre-sql/flexible-server/tests/e2e/defaults/dependencies.bicep b/avm/res/db-for-postgre-sql/flexible-server/tests/e2e/defaults/dependencies.bicep new file mode 100644 index 0000000000..7ddc0bfb00 --- /dev/null +++ b/avm/res/db-for-postgre-sql/flexible-server/tests/e2e/defaults/dependencies.bicep @@ -0,0 +1,16 @@ +@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 + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { + name: managedIdentityName + location: location +} + +@description('The client ID of the created Managed Identity.') +output managedIdentityClientId string = managedIdentity.properties.clientId + +@description('The name of the created Managed Identity.') +output managedIdentityName string = managedIdentity.name diff --git a/avm/res/db-for-postgre-sql/flexible-server/tests/e2e/defaults/main.test.bicep b/avm/res/db-for-postgre-sql/flexible-server/tests/e2e/defaults/main.test.bicep index f7848f4b41..6c56f5b441 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/tests/e2e/defaults/main.test.bicep +++ b/avm/res/db-for-postgre-sql/flexible-server/tests/e2e/defaults/main.test.bicep @@ -17,10 +17,6 @@ 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 = 'dfpsfsmin' -@description('Optional. The password to leverage for the login.') -@secure() -param password string = newGuid() - @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' @@ -35,21 +31,37 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2023-07-01' = { location: resourceLocation } +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + 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' - location: resourceLocation - administratorLogin: 'adminUserName' - administratorLoginPassword: password - skuName: 'Standard_B2s' - tier: 'Burstable' - geoRedundantBackup: 'Enabled' +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + administrators: [ + { + objectId: nestedDependencies.outputs.managedIdentityClientId + principalName: nestedDependencies.outputs.managedIdentityName + principalType: 'ServicePrincipal' + } + ] + skuName: 'Standard_D2s_v3' + tier: 'GeneralPurpose' + geoRedundantBackup: 'Enabled' + highAvailability: 'ZoneRedundant' + } } -}] +] diff --git a/avm/res/db-for-postgre-sql/flexible-server/tests/e2e/public/main.test.bicep b/avm/res/db-for-postgre-sql/flexible-server/tests/e2e/public/main.test.bicep index 834c02cbb9..01b6ee55cc 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/tests/e2e/public/main.test.bicep +++ b/avm/res/db-for-postgre-sql/flexible-server/tests/e2e/public/main.test.bicep @@ -59,99 +59,100 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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' - administrators: [ - { - objectId: nestedDependencies.outputs.managedIdentityClientId - principalName: nestedDependencies.outputs.managedIdentityName - principalType: 'ServicePrincipal' - } - ] - skuName: 'Standard_D2s_v3' - tier: 'GeneralPurpose' - backupRetentionDays: 20 - configurations: [ - { - name: 'log_min_messages' - source: 'user-override' - value: 'INFO' - } - ] - databases: [ - { - charset: 'UTF8' - collation: 'en_US.utf8' - name: 'testdb1' - } - { - name: 'testdb2' - } - ] - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + administrators: [ + { + objectId: nestedDependencies.outputs.managedIdentityClientId + principalName: nestedDependencies.outputs.managedIdentityName + principalType: 'ServicePrincipal' + } + ] + skuName: 'Standard_D2s_v3' + tier: 'GeneralPurpose' + backupRetentionDays: 20 + configurations: [ + { + name: 'log_min_messages' + source: 'user-override' + value: 'INFO' + } + ] + databases: [ + { + charset: 'UTF8' + collation: 'en_US.utf8' + name: 'testdb1' + } + { + name: 'testdb2' + } + ] + roleAssignments: [ + { + roleDefinitionIdOrName: 'Owner' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'acdd72a7-3385-48ef-bd42-f606fba81ae7' + ) + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + firewallRules: [ + { + endIpAddress: '0.0.0.0' + name: 'AllowAllWindowsAzureIps' + startIpAddress: '0.0.0.0' + } + { + endIpAddress: '10.10.10.10' + name: 'test-rule1' + startIpAddress: '10.10.10.1' + } + { + endIpAddress: '100.100.100.10' + name: 'test-rule2' + startIpAddress: '100.100.100.1' + } + ] + geoRedundantBackup: 'Disabled' + highAvailability: 'SameZone' + location: resourceLocation + storageSizeGB: 1024 + version: '14' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - ] - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - firewallRules: [ - { - endIpAddress: '0.0.0.0' - name: 'AllowAllWindowsAzureIps' - startIpAddress: '0.0.0.0' - } - { - endIpAddress: '10.10.10.10' - name: 'test-rule1' - startIpAddress: '10.10.10.1' - } - { - endIpAddress: '100.100.100.10' - name: 'test-rule2' - startIpAddress: '100.100.100.1' - } - ] - geoRedundantBackup: 'Disabled' - highAvailability: 'SameZone' - location: resourceLocation - storageSizeGB: 1024 - version: '14' - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' } } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +] diff --git a/avm/res/db-for-postgre-sql/flexible-server/tests/e2e/waf-aligned/main.test.bicep b/avm/res/db-for-postgre-sql/flexible-server/tests/e2e/waf-aligned/main.test.bicep index 395890f8fb..f33e849678 100644 --- a/avm/res/db-for-postgre-sql/flexible-server/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/db-for-postgre-sql/flexible-server/tests/e2e/waf-aligned/main.test.bicep @@ -62,62 +62,71 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // ============== // @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' - location: resourceLocation - administrators: [ - { - objectId: nestedDependencies.outputs.managedIdentityClientId - principalName: nestedDependencies.outputs.managedIdentityName - principalType: 'ServicePrincipal' - } - ] - skuName: 'Standard_D2s_v3' - tier: 'GeneralPurpose' - configurations: [ - { - name: 'log_min_messages' - source: 'user-override' - value: 'INFO' - } - { - name: 'autovacuum_naptime' - source: 'user-override' - value: '80' +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + administrators: [ + { + objectId: nestedDependencies.outputs.managedIdentityClientId + principalName: nestedDependencies.outputs.managedIdentityName + principalType: 'ServicePrincipal' + } + ] + skuName: 'Standard_D2s_v3' + tier: 'GeneralPurpose' + configurations: [ + { + name: 'log_min_messages' + source: 'user-override' + value: 'INFO' + } + { + name: 'autovacuum_naptime' + source: 'user-override' + value: '80' + } + ] + databases: [ + { + charset: 'UTF8' + collation: 'en_US.utf8' + name: 'testdb1' + } + { + name: 'testdb2' + } + ] + delegatedSubnetResourceId: nestedDependencies.outputs.subnetResourceId + diagnosticSettings: [ + { + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + geoRedundantBackup: 'Enabled' + privateDnsZoneArmResourceId: nestedDependencies.outputs.privateDNSZoneResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' } - ] - databases: [ - { - charset: 'UTF8' - collation: 'en_US.utf8' - name: 'testdb1' - } - { - name: 'testdb2' - } - ] - delegatedSubnetResourceId: nestedDependencies.outputs.subnetResourceId - diagnosticSettings: [ - { - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + maintenanceWindow: { + customWindow: 'Enabled' + dayOfWeek: 0 + startHour: 1 + startMinute: 0 } - ] - geoRedundantBackup: 'Enabled' - privateDnsZoneArmResourceId: nestedDependencies.outputs.privateDNSZoneResourceId - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' + highAvailability: 'ZoneRedundant' } + dependsOn: [ + nestedDependencies + diagnosticDependencies + ] } - dependsOn: [ - nestedDependencies - diagnosticDependencies - ] -}] +]