From 187ae4169f3cd4f968d9c3ea93527a9cb98d9a9e Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Wed, 13 Sep 2023 15:54:05 +1200 Subject: [PATCH 01/17] test --- .../.bicep/nested_roleAssignments.bicep | 69 ++ .../.test/common/dependencies.bicep | 49 + .../.test/common/main.test.bicep | 97 ++ .../.test/min/main.test.bicep | 45 + modules/cache/redis-enterprise/README.md | 563 +++++++++ modules/cache/redis-enterprise/main.bicep | 215 ++++ modules/cache/redis-enterprise/main.json | 1016 +++++++++++++++++ modules/cache/redis-enterprise/version.json | 7 + 8 files changed, 2061 insertions(+) create mode 100644 modules/cache/redis-enterprise/.bicep/nested_roleAssignments.bicep create mode 100644 modules/cache/redis-enterprise/.test/common/dependencies.bicep create mode 100644 modules/cache/redis-enterprise/.test/common/main.test.bicep create mode 100644 modules/cache/redis-enterprise/.test/min/main.test.bicep create mode 100644 modules/cache/redis-enterprise/README.md create mode 100644 modules/cache/redis-enterprise/main.bicep create mode 100644 modules/cache/redis-enterprise/main.json create mode 100644 modules/cache/redis-enterprise/version.json diff --git a/modules/cache/redis-enterprise/.bicep/nested_roleAssignments.bicep b/modules/cache/redis-enterprise/.bicep/nested_roleAssignments.bicep new file mode 100644 index 0000000000..f888e4ca02 --- /dev/null +++ b/modules/cache/redis-enterprise/.bicep/nested_roleAssignments.bicep @@ -0,0 +1,69 @@ +@sys.description('Required. The IDs of the principals to assign the role to.') +param principalIds array + +@sys.description('Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead.') +param roleDefinitionIdOrName string + +@sys.description('Required. The resource ID of the resource to apply the role assignment to.') +param resourceId string + +@sys.description('Optional. The principal type of the assigned principal ID.') +@allowed([ + 'ServicePrincipal' + 'Group' + 'User' + 'ForeignGroup' + 'Device' + '' +]) +param principalType string = '' + +@sys.description('Optional. The description of the role assignment.') +param description string = '' + +@sys.description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container".') +param condition string = '' + +@sys.description('Optional. Version of the condition.') +@allowed([ + '2.0' +]) +param conditionVersion string = '2.0' + +@sys.description('Optional. Id of the delegated managed identity resource.') +param delegatedManagedIdentityResourceId string = '' + +var builtInRoleNames = { + Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') + 'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293') + 'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893') + 'Managed Application Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e') + 'Managed Application Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae') + 'Managed Applications Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44') + 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa') + 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05') + Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') + Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + 'Redis Cache Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e0f68234-74aa-48ed-b826-c38b57376e17') + 'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608') + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168') + 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') +} + +resource redisCacheEnterprise 'Microsoft.Cache/redisEnterprise@2022-01-01' existing = { + name: last(split(resourceId, '/'))! +} + +resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for principalId in principalIds: { + name: guid(redisCacheEnterprise.id, principalId, roleDefinitionIdOrName) + properties: { + description: description + roleDefinitionId: contains(builtInRoleNames, roleDefinitionIdOrName) ? builtInRoleNames[roleDefinitionIdOrName] : roleDefinitionIdOrName + principalId: principalId + principalType: !empty(principalType) ? any(principalType) : null + condition: !empty(condition) ? condition : null + conditionVersion: !empty(conditionVersion) && !empty(condition) ? conditionVersion : null + delegatedManagedIdentityResourceId: !empty(delegatedManagedIdentityResourceId) ? delegatedManagedIdentityResourceId : null + } + scope: redisCacheEnterprise +}] diff --git a/modules/cache/redis-enterprise/.test/common/dependencies.bicep b/modules/cache/redis-enterprise/.test/common/dependencies.bicep new file mode 100644 index 0000000000..6e785bcc07 --- /dev/null +++ b/modules/cache/redis-enterprise/.test/common/dependencies.bicep @@ -0,0 +1,49 @@ +@description('Optional. The location to deploy resources to.') +param location string = resourceGroup().location + +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +var addressPrefix = '10.0.0.0/16' + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + } + } + ] + } +} + +resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { + name: 'privatelink.azuresynapse.net' + location: 'global' + + resource virtualNetworkLinks 'virtualNetworkLinks@2020-06-01' = { + name: '${virtualNetwork.name}-vnetlink' + location: 'global' + properties: { + virtualNetwork: { + id: virtualNetwork.id + } + registrationEnabled: false + } + } +} + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id + +@description('The resource ID of the created Private DNS Zone.') +output privateDNSResourceId string = privateDNSZone.id diff --git a/modules/cache/redis-enterprise/.test/common/main.test.bicep b/modules/cache/redis-enterprise/.test/common/main.test.bicep new file mode 100644 index 0000000000..7a2bd4069f --- /dev/null +++ b/modules/cache/redis-enterprise/.test/common/main.test.bicep @@ -0,0 +1,97 @@ +targetScope = 'subscription' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'ms.cache.redisenterprise-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param location 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 = 'crecom' + +@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +param enableDefaultTelemetry bool = true + +@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: location +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-nestedDependencies' + params: { + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + } +} + +// Diagnostics +// =========== +module diagnosticDependencies '../../../../.shared/.templates/diagnostic.dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-diagnosticDependencies' + params: { + storageAccountName: 'dep${namePrefix}diasa${serviceShort}01' + logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' + eventHubNamespaceEventHubName: 'dep-${namePrefix}-evh-${serviceShort}' + eventHubNamespaceName: 'dep-${namePrefix}-evhns-${serviceShort}' + location: location + } +} + +// ============== // +// Test Execution // +// ============== // + +module testDeployment '../../main.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}' + params: { + enableDefaultTelemetry: enableDefaultTelemetry + name: '${namePrefix}${serviceShort}001' + capacity: 2 + diagnosticStorageAccountId: diagnosticDependencies.outputs.storageAccountResourceId + diagnosticWorkspaceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + diagnosticEventHubAuthorizationRuleId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + diagnosticEventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + diagnosticSettingsName: 'redisdiagnostics' + lock: 'CanNotDelete' + minimumTlsVersion: '1.2' + zoneRedundant: true + zones: [ 1, 2 ] + privateEndpoints: [ + { + privateDnsZoneGroup: { + privateDNSResourceIds: [ + nestedDependencies.outputs.privateDNSResourceId + ] + } + service: 'redisCache' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + resourceType: 'Redis Cache' + } + } +} diff --git a/modules/cache/redis-enterprise/.test/min/main.test.bicep b/modules/cache/redis-enterprise/.test/min/main.test.bicep new file mode 100644 index 0000000000..dfe3f24c13 --- /dev/null +++ b/modules/cache/redis-enterprise/.test/min/main.test.bicep @@ -0,0 +1,45 @@ +targetScope = 'subscription' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'ms.cache.redisenterprise-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param location 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 = 'cremin' + +@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +param enableDefaultTelemetry bool = true + +@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: location +} + +// ============== // +// Test Execution // +// ============== // + +module testDeployment '../../main.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}' + params: { + enableDefaultTelemetry: enableDefaultTelemetry + name: '${namePrefix}${serviceShort}001' + } +} diff --git a/modules/cache/redis-enterprise/README.md b/modules/cache/redis-enterprise/README.md new file mode 100644 index 0000000000..713fbd99f7 --- /dev/null +++ b/modules/cache/redis-enterprise/README.md @@ -0,0 +1,563 @@ +# Redis Cache `[Microsoft.Cache/Redis]` + +This module deploys a Redis Cache. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Deployment examples](#Deployment-examples) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | +| `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | +| `Microsoft.Cache/redis` | [2021-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Cache/2021-06-01/redis) | +| `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | +| `Microsoft.Network/privateEndpoints` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints) | +| `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints/privateDnsZoneGroups) | + +## Parameters + +**Required parameters** + +| Parameter Name | Type | Description | +| :-- | :-- | :-- | +| `name` | string | The name of the Redis cache resource. | + +**Optional parameters** + +| Parameter Name | Type | Default Value | Allowed Values | Description | +| :-- | :-- | :-- | :-- | :-- | +| `capacity` | int | `1` | `[0, 1, 2, 3, 4, 5, 6]` | The size of the Redis cache to deploy. Valid values: for C (Basic/Standard) family (0, 1, 2, 3, 4, 5, 6), for P (Premium) family (1, 2, 3, 4). | +| `diagnosticEventHubAuthorizationRuleId` | string | `''` | | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | +| `diagnosticEventHubName` | string | `''` | | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | +| `diagnosticLogCategoriesToEnable` | array | `[allLogs]` | `['', allLogs, ConnectedClientList]` | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| `diagnosticMetricsToEnable` | array | `[AllMetrics]` | `[AllMetrics]` | The name of metrics that will be streamed. | +| `diagnosticSettingsName` | string | `''` | | The name of the diagnostic setting, if deployed. If left empty, it defaults to "-diagnosticSettings". | +| `diagnosticStorageAccountId` | string | `''` | | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | +| `diagnosticWorkspaceId` | string | `''` | | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | +| `enableDefaultTelemetry` | bool | `True` | | Enable telemetry via a Globally Unique Identifier (GUID). | +| `enableNonSslPort` | bool | `False` | | Specifies whether the non-ssl Redis server port (6379) is enabled. | +| `location` | string | `[resourceGroup().location]` | | The location to deploy the Redis cache service. | +| `lock` | string | `''` | `['', CanNotDelete, ReadOnly]` | Specify the type of lock. | +| `minimumTlsVersion` | string | `'1.2'` | `[1.0, 1.1, 1.2]` | Requires clients to use a specified TLS version (or higher) to connect. | +| `privateEndpoints` | array | `[]` | | Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible. | +| `publicNetworkAccess` | string | `''` | `['', Disabled, Enabled]` | Whether or not public network access is allowed for this resource. For security reasons it should be disabled. If not specified, it will be disabled by default if private endpoints are set. | +| `redisConfiguration` | object | `{object}` | | All Redis Settings. Few possible keys: rdb-backup-enabled,rdb-storage-connection-string,rdb-backup-frequency,maxmemory-delta,maxmemory-policy,notify-keyspace-events,maxmemory-samples,slowlog-log-slower-than,slowlog-max-len,list-max-ziplist-entries,list-max-ziplist-value,hash-max-ziplist-entries,hash-max-ziplist-value,set-max-intset-entries,zset-max-ziplist-entries,zset-max-ziplist-value etc. | +| `redisVersion` | string | `'6'` | `[4, 6]` | Redis version. Only major version will be used in PUT/PATCH request with current valid values: (4, 6). | +| `replicasPerMaster` | int | `1` | | The number of replicas to be created per primary. | +| `replicasPerPrimary` | int | `1` | | The number of replicas to be created per primary. | +| `roleAssignments` | array | `[]` | | Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | +| `shardCount` | int | `1` | | The number of shards to be created on a Premium Cluster Cache. | +| `skuName` | string | `'Basic'` | `[Basic, Premium, Standard]` | The type of Redis cache to deploy. | +| `staticIP` | string | `''` | | Static IP address. Optionally, may be specified when deploying a Redis cache inside an existing Azure Virtual Network; auto assigned by default. | +| `subnetId` | string | `''` | | The full resource ID of a subnet in a virtual network to deploy the Redis cache in. Example format: /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/Microsoft.{Network|ClassicNetwork}/VirtualNetworks/vnet1/subnets/subnet1. | +| `systemAssignedIdentity` | bool | `False` | | Enables system assigned managed identity on the resource. | +| `tags` | object | `{object}` | | Tags of the resource. | +| `tenantSettings` | object | `{object}` | | A dictionary of tenant settings. | +| `userAssignedIdentities` | object | `{object}` | | The ID(s) to assign to the resource. | +| `zoneRedundant` | bool | `True` | | When true, replicas will be provisioned in availability zones specified in the zones parameter. | +| `zones` | array | `[]` | | If the zoneRedundant parameter is true, replicas will be provisioned in the availability zones specified here. Otherwise, the service will choose where replicas are deployed. | + + +### Parameter Usage: `roleAssignments` + +Create a role assignment for the given resource. If you want to assign a service principal / managed identity that is created in the same deployment, make sure to also specify the `'principalType'` parameter and set it to `'ServicePrincipal'`. This will ensure the role assignment waits for the principal's propagation in Azure. + +
+ +Parameter JSON format + +```json +"roleAssignments": { + "value": [ + { + "roleDefinitionIdOrName": "Reader", + "description": "Reader Role Assignment", + "principalIds": [ + "12345678-1234-1234-1234-123456789012", // object 1 + "78945612-1234-1234-1234-123456789012" // object 2 + ] + }, + { + "roleDefinitionIdOrName": "/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11", + "principalIds": [ + "12345678-1234-1234-1234-123456789012" // object 1 + ], + "principalType": "ServicePrincipal" + } + ] +} +``` + +
+ +
+ +Bicep format + +```bicep +roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + description: 'Reader Role Assignment' + principalIds: [ + '12345678-1234-1234-1234-123456789012' // object 1 + '78945612-1234-1234-1234-123456789012' // object 2 + ] + } + { + roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11' + principalIds: [ + '12345678-1234-1234-1234-123456789012' // object 1 + ] + principalType: 'ServicePrincipal' + } +] +``` + +
+

+ +### Parameter Usage: `tags` + +Tag names and tag values can be provided as needed. A tag can be left without a value. + +

+ +Parameter JSON format + +```json +"tags": { + "value": { + "Environment": "Non-Prod", + "Contact": "test.user@testcompany.com", + "PurchaseOrder": "1234", + "CostCenter": "7890", + "ServiceName": "DeploymentValidation", + "Role": "DeploymentValidation" + } +} +``` + +
+ +
+ +Bicep format + +```bicep +tags: { + Environment: 'Non-Prod' + Contact: 'test.user@testcompany.com' + PurchaseOrder: '1234' + CostCenter: '7890' + ServiceName: 'DeploymentValidation' + Role: 'DeploymentValidation' +} +``` + +
+

+ +### Parameter Usage: `userAssignedIdentities` + +You can specify multiple user assigned identities to a resource by providing additional resource IDs using the following format: + +

+ +Parameter JSON format + +```json +"userAssignedIdentities": { + "value": { + "/subscriptions/[[subscriptionId]]/resourcegroups/validation-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/adp-sxx-az-msi-x-001": {}, + "/subscriptions/[[subscriptionId]]/resourcegroups/validation-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/adp-sxx-az-msi-x-002": {} + } +} +``` + +
+ +
+ +Bicep format + +```bicep +userAssignedIdentities: { + '/subscriptions/[[subscriptionId]]/resourcegroups/validation-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/adp-sxx-az-msi-x-001': {} + '/subscriptions/[[subscriptionId]]/resourcegroups/validation-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/adp-sxx-az-msi-x-002': {} +} +``` + +
+

+ +### Parameter Usage: `redisConfiguration` + +All Redis Settings. Few possible keys: rdb-backup-enabled,rdb-storage-connection-string,rdb-backup-frequency,maxmemory-delta,maxmemory-policy,notify-keyspace-events,maxmemory-samples,slowlog-log-slower-than,slowlog-max-len,list-max-ziplist-entries,list-max-ziplist-value,hash-max-ziplist-entries,hash-max-ziplist-value,set-max-intset-entries,zset-max-ziplist-entries,zset-max-ziplist-value etc.. + +Name | Description | Value +---------|----------|--------- +aof-storage-connection-string-0 | First storage account connection string | string +aof-storage-connection-string-1 | Second storage account connection string | string +maxfragmentationmemory-reserved | Value in megabytes reserved for fragmentation per shard | string +maxmemory-delta | Value in megabytes reserved for non-cache usage per shard e.g. failover. | string +maxmemory-policy | The eviction strategy used when your data won't fit within its memory limit. | string +maxmemory-reserved | Value in megabytes reserved for non-cache usage per shard e.g. failover. | string +rdb-backup-enabled | Specifies whether the rdb backup is enabled | string +rdb-backup-frequency | Specifies the frequency for creating rdb backup | string +rdb-backup-max-snapshot-count | Specifies the maximum number of snapshots for rdb backup | string +rdb-storage-connection-string | The storage account connection string for storing rdb file | string + +For more details visit [Microsoft.Cache redis reference](https://learn.microsoft.com/en-us/azure/templates/microsoft.cache/redis?tabs=bicep) + +

+ +Bicep format + +```bicep +userAssignedIdentities: { + '/subscriptions/12345678-1234-1234-1234-123456789012/resourcegroups/validation-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/adp-sxx-az-msi-x-001': {} + '/subscriptions/12345678-1234-1234-1234-123456789012/resourcegroups/validation-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/adp-sxx-az-msi-x-002': {} +} +``` + +
+

+ +### Parameter Usage: `privateEndpoints` + +To use Private Endpoint the following dependencies must be deployed: + +- Destination subnet must be created with the following configuration option - `"privateEndpointNetworkPolicies": "Disabled"`. Setting this option acknowledges that NSG rules are not applied to Private Endpoints (this capability is coming soon). A full example is available in the Virtual Network Module. +- Although not strictly required, it is highly recommended to first create a private DNS Zone to host Private Endpoint DNS records. See [Azure Private Endpoint DNS configuration](https://learn.microsoft.com/en-us/azure/private-link/private-endpoint-dns) for more information. + +

+ +Parameter JSON format + +```json +"privateEndpoints": { + "value": [ + // Example showing all available fields + { + "name": "sxx-az-pe", // Optional: Name will be automatically generated if one is not provided here + "subnetResourceId": "/subscriptions/[[subscriptionId]]/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/sxx-az-vnet-x-001/subnets/sxx-az-subnet-x-001", + "service": "", // e.g. vault, registry, blob + "privateDnsZoneGroup": { + "privateDNSResourceIds": [ // Optional: No DNS record will be created if a private DNS zone Resource ID is not specified + "/subscriptions/[[subscriptionId]]/resourceGroups/validation-rg/providers/Microsoft.Network/privateDnsZones/" // e.g. privatelink.vaultcore.azure.net, privatelink.azurecr.io, privatelink.blob.core.windows.net + ] + }, + "ipConfigurations":[ + { + "name": "myIPconfigTest02", + "properties": { + "groupId": "blob", + "memberName": "blob", + "privateIPAddress": "10.0.0.30" + } + } + ], + "customDnsConfigs": [ + { + "fqdn": "customname.test.local", + "ipAddresses": [ + "10.10.10.10" + ] + } + ] + }, + // Example showing only mandatory fields + { + "subnetResourceId": "/subscriptions/[[subscriptionId]]/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/sxx-az-vnet-x-001/subnets/sxx-az-subnet-x-001", + "service": "" // e.g. vault, registry, blob + } + ] +} +``` + +
+ +
+ +Bicep format + +```bicep +privateEndpoints: [ + // Example showing all available fields + { + name: 'sxx-az-pe' // Optional: Name will be automatically generated if one is not provided here + subnetResourceId: '/subscriptions/[[subscriptionId]]/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/sxx-az-vnet-x-001/subnets/sxx-az-subnet-x-001' + service: '' // e.g. vault, registry, blob + privateDnsZoneGroup: { + privateDNSResourceIds: [ // Optional: No DNS record will be created if a private DNS zone Resource ID is not specified + '/subscriptions/[[subscriptionId]]/resourceGroups/validation-rg/providers/Microsoft.Network/privateDnsZones/' // e.g. privatelink.vaultcore.azure.net, privatelink.azurecr.io, privatelink.blob.core.windows.net + ] + } + customDnsConfigs: [ + { + fqdn: 'customname.test.local' + ipAddresses: [ + '10.10.10.10' + ] + } + ] + ipConfigurations:[ + { + name: 'myIPconfigTest02' + properties: { + groupId: 'blob' + memberName: 'blob' + privateIPAddress: '10.0.0.30' + } + } + ] + } + // Example showing only mandatory fields + { + subnetResourceId: '/subscriptions/[[subscriptionId]]/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/sxx-az-vnet-x-001/subnets/sxx-az-subnet-x-001' + service: '' // e.g. vault, registry, blob + } +] +``` + +
+

+ +## Outputs + +| Output Name | Type | Description | +| :-- | :-- | :-- | +| `hostName` | string | Redis hostname. | +| `location` | string | The location the resource was deployed into. | +| `name` | string | The resource name. | +| `resourceGroupName` | string | The name of the resource group the Redis cache was created in. | +| `resourceId` | string | The resource ID. | +| `sslPort` | int | Redis SSL port. | +| `subnetId` | string | The full resource ID of a subnet in a virtual network where the Redis cache was deployed in. | + +## Cross-referenced modules + +This section gives you an overview of all local-referenced module files (i.e., other CARML modules that are referenced in this module) and all remote-referenced files (i.e., Bicep modules that are referenced from a Bicep Registry or Template Specs). + +| Reference | Type | +| :-- | :-- | +| `network/private-endpoint` | Local reference | + +## Deployment examples + +The following module usage examples are retrieved from the content of the files hosted in the module's `.test` folder. + >**Note**: The name of each example is based on the name of the file from which it is taken. + + >**Note**: Each example lists all the required parameters first, followed by the rest - each in alphabetical order. + +

Example 1: Common

+ +
+ +via Bicep module + +```bicep +module redis './cache/redis/main.bicep' = { + name: '${uniqueString(deployment().name, location)}-test-crcom' + params: { + // Required parameters + name: 'crcom001' + // Non-required parameters + capacity: 2 + diagnosticEventHubAuthorizationRuleId: '' + diagnosticEventHubName: '' + diagnosticSettingsName: 'redisdiagnostics' + diagnosticStorageAccountId: '' + diagnosticWorkspaceId: '' + enableDefaultTelemetry: '' + enableNonSslPort: true + lock: 'CanNotDelete' + minimumTlsVersion: '1.2' + privateEndpoints: [ + { + privateDnsZoneGroup: { + privateDNSResourceIds: [ + '' + ] + } + service: 'redisCache' + subnetResourceId: '' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + ] + publicNetworkAccess: 'Enabled' + redisVersion: '6' + shardCount: 1 + skuName: 'Premium' + systemAssignedIdentity: true + tags: { + 'hidden-title': 'This is visible in the resource name' + resourceType: 'Redis Cache' + } + zoneRedundant: true + zones: [ + 1 + 2 + ] + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "crcom001" + }, + // Non-required parameters + "capacity": { + "value": 2 + }, + "diagnosticEventHubAuthorizationRuleId": { + "value": "" + }, + "diagnosticEventHubName": { + "value": "" + }, + "diagnosticSettingsName": { + "value": "redisdiagnostics" + }, + "diagnosticStorageAccountId": { + "value": "" + }, + "diagnosticWorkspaceId": { + "value": "" + }, + "enableDefaultTelemetry": { + "value": "" + }, + "enableNonSslPort": { + "value": true + }, + "lock": { + "value": "CanNotDelete" + }, + "minimumTlsVersion": { + "value": "1.2" + }, + "privateEndpoints": { + "value": [ + { + "privateDnsZoneGroup": { + "privateDNSResourceIds": [ + "" + ] + }, + "service": "redisCache", + "subnetResourceId": "", + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + ] + }, + "publicNetworkAccess": { + "value": "Enabled" + }, + "redisVersion": { + "value": "6" + }, + "shardCount": { + "value": 1 + }, + "skuName": { + "value": "Premium" + }, + "systemAssignedIdentity": { + "value": true + }, + "tags": { + "value": { + "hidden-title": "This is visible in the resource name", + "resourceType": "Redis Cache" + } + }, + "zoneRedundant": { + "value": true + }, + "zones": { + "value": [ + 1, + 2 + ] + } + } +} +``` + +
+

+ +

Example 2: Min

+ +
+ +via Bicep module + +```bicep +module redis './cache/redis/main.bicep' = { + name: '${uniqueString(deployment().name, location)}-test-crmin' + params: { + // Required parameters + name: 'crmin001' + // Non-required parameters + enableDefaultTelemetry: '' + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "crmin001" + }, + // Non-required parameters + "enableDefaultTelemetry": { + "value": "" + } + } +} +``` + +
+

diff --git a/modules/cache/redis-enterprise/main.bicep b/modules/cache/redis-enterprise/main.bicep new file mode 100644 index 0000000000..88eff95375 --- /dev/null +++ b/modules/cache/redis-enterprise/main.bicep @@ -0,0 +1,215 @@ +metadata name = 'Redis Cache Enterprise' +metadata description = 'This module deploys a Redis Cache Enterprise.' +metadata owner = 'Azure/module-maintainers' + +@description('Optional. The location to deploy the Redis cache service.') +param location string = resourceGroup().location + +@description('Required. The name of the Redis cache resource.') +param name string + +@allowed([ + '' + 'CanNotDelete' + 'ReadOnly' +]) +@description('Optional. Specify the type of lock.') +param lock string = '' + +@description('Optional. Array of role assignment objects that contain the \'roleDefinitionIdOrName\' and \'principalId\' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') +param roleAssignments array = [] + +@description('Optional. Tags of the resource.') +param tags object = {} + +@allowed([ + '1.0' + '1.1' + '1.2' +]) +@description('Optional. Requires clients to use a specified TLS version (or higher) to connect.') +param minimumTlsVersion string = '1.2' + +@description('Optional. The size of the RedisEnterprise cluster. Defaults to 2. Valid values are (2, 4, 6, ...) for Enterprise SKUs and (3, 9, 15, ...) for Flash SKUs.') +param capacity int = 2 + +@allowed([ + 'EnterpriseFlash_F1500' + 'EnterpriseFlash_F300' + 'EnterpriseFlash_F700' + 'Enterprise_E10' + 'Enterprise_E100' + 'Enterprise_E20' + 'Enterprise_E50' +]) +@description('Optional. The type of RedisEnterprise cluster to deploy.') +param skuName string = 'Enterprise_E10' + +@description('Optional. When true, replicas will be provisioned in availability zones specified in the zones parameter.') +param zoneRedundant bool = true + +@description('Optional. If the zoneRedundant parameter is true, replicas will be provisioned in the availability zones specified here. Otherwise, the service will choose where replicas are deployed.') +param zones array = [] + +@description('Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible.') +param privateEndpoints array = [] + +@description('Optional. The name of the diagnostic setting, if deployed. If left empty, it defaults to "-diagnosticSettings".') +param diagnosticSettingsName string = '' + +@description('Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') +param diagnosticStorageAccountId string = '' + +@description('Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') +param diagnosticWorkspaceId string = '' + +@description('Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to.') +param diagnosticEventHubAuthorizationRuleId string = '' + +@description('Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') +param diagnosticEventHubName string = '' + +@description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') +@allowed([ + '' + 'allLogs' + 'ConnectedClientList' +]) +param diagnosticLogCategoriesToEnable array = [ + 'allLogs' +] + +@description('Optional. The name of metrics that will be streamed.') +@allowed([ + 'AllMetrics' +]) +param diagnosticMetricsToEnable array = [ + 'AllMetrics' +] + +@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +param enableDefaultTelemetry bool = true + +var availabilityZones = zoneRedundant ? !empty(zones) ? zones : pickZones('Microsoft.Cache', 'redisEnterprise', location, 3) : [] + +var diagnosticsLogsSpecified = [for category in filter(diagnosticLogCategoriesToEnable, item => item != 'allLogs' && item != ''): { + category: category + enabled: true +}] + +var diagnosticsLogs = contains(diagnosticLogCategoriesToEnable, 'allLogs') ? [ + { + categoryGroup: 'allLogs' + enabled: true + } +] : contains(diagnosticLogCategoriesToEnable, '') ? [] : diagnosticsLogsSpecified + +var diagnosticsMetrics = [for metric in diagnosticMetricsToEnable: { + category: metric + timeGrain: null + enabled: true +}] + +var enableReferencedModulesTelemetry = false + +resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (enableDefaultTelemetry) { + name: 'pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-${uniqueString(deployment().name)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + } + } +} + +resource redisCacheEnterprise 'Microsoft.Cache/redisEnterprise@2023-07-01' = { + name: name + location: location + tags: tags + sku: { + capacity: capacity + name: skuName + } + properties: { + minimumTlsVersion: minimumTlsVersion + } + zones: availabilityZones +} + +resource redisCacheEnterprise_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock)) { + name: '${redisCacheEnterprise.name}-${lock}-lock' + properties: { + level: any(lock) + notes: lock == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot modify the resource or child resources.' + } + scope: redisCacheEnterprise +} + +resource redisCacheEnterprise_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if (!empty(diagnosticStorageAccountId) || !empty(diagnosticWorkspaceId) || !empty(diagnosticEventHubAuthorizationRuleId) || !empty(diagnosticEventHubName)) { + name: !empty(diagnosticSettingsName) ? diagnosticSettingsName : '${name}-diagnosticSettings' + properties: { + storageAccountId: empty(diagnosticStorageAccountId) ? null : diagnosticStorageAccountId + workspaceId: empty(diagnosticWorkspaceId) ? null : diagnosticWorkspaceId + eventHubAuthorizationRuleId: empty(diagnosticEventHubAuthorizationRuleId) ? null : diagnosticEventHubAuthorizationRuleId + eventHubName: empty(diagnosticEventHubName) ? null : diagnosticEventHubName + metrics: empty(diagnosticStorageAccountId) && empty(diagnosticWorkspaceId) && empty(diagnosticEventHubAuthorizationRuleId) && empty(diagnosticEventHubName) ? null : diagnosticsMetrics + logs: empty(diagnosticStorageAccountId) && empty(diagnosticWorkspaceId) && empty(diagnosticEventHubAuthorizationRuleId) && empty(diagnosticEventHubName) ? null : diagnosticsLogs + } + scope: redisCacheEnterprise +} + +module redisCacheEnterprise_rbac '.bicep/nested_roleAssignments.bicep' = [for (roleAssignment, index) in roleAssignments: { + name: '${uniqueString(deployment().name, location)}-redisCacheEnterprise-Rbac-${index}' + params: { + description: contains(roleAssignment, 'description') ? roleAssignment.description : '' + principalIds: roleAssignment.principalIds + principalType: contains(roleAssignment, 'principalType') ? roleAssignment.principalType : '' + roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName + condition: contains(roleAssignment, 'condition') ? roleAssignment.condition : '' + delegatedManagedIdentityResourceId: contains(roleAssignment, 'delegatedManagedIdentityResourceId') ? roleAssignment.delegatedManagedIdentityResourceId : '' + resourceId: redisCacheEnterprise.id + } +}] + +module redisCacheEnterprise_privateEndpoints '../../network/private-endpoint/main.bicep' = [for (privateEndpoint, index) in privateEndpoints: { + name: '${uniqueString(deployment().name, location)}-redisCacheEnterprise-PrivateEndpoint-${index}' + params: { + groupIds: [ + privateEndpoint.service + ] + name: contains(privateEndpoint, 'name') ? privateEndpoint.name : 'pe-${last(split(redisCacheEnterprise.id, '/'))}-${privateEndpoint.service}-${index}' + serviceResourceId: redisCacheEnterprise.id + subnetResourceId: privateEndpoint.subnetResourceId + enableDefaultTelemetry: enableReferencedModulesTelemetry + location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock + privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] + tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} + manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] + customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] + ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] + applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' + } +}] + +@description('The name of the redis cache enterprise.') +output name string = redisCacheEnterprise.name + +@description('The resource ID of the redis cache enterprise.') +output resourceId string = redisCacheEnterprise.id + +@description('The name of the resource group the redis cache enterprise was created in.') +output resourceGroupName string = resourceGroup().name + +@description('Redis hostname.') +output hostName string = redisCacheEnterprise.properties.hostName + +//@description('The full resource ID of a subnet in a virtual network where the Redis cache was deployed in.') +//output subnetId string = !empty(subnetId) ? redisCacheEnterprise.properties.subnetId : '' + +@description('The location the resource was deployed into.') +output location string = redisCacheEnterprise.location diff --git a/modules/cache/redis-enterprise/main.json b/modules/cache/redis-enterprise/main.json new file mode 100644 index 0000000000..d93c58f9ba --- /dev/null +++ b/modules/cache/redis-enterprise/main.json @@ -0,0 +1,1016 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.21.1.54444", + "templateHash": "1782588459974283676" + }, + "name": "Redis Cache Enterprise", + "description": "This module deploys a Redis Cache Enterprise.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. The location to deploy the Redis cache service." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the Redis cache resource." + } + }, + "lock": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "", + "CanNotDelete", + "ReadOnly" + ], + "metadata": { + "description": "Optional. Specify the type of lock." + } + }, + "roleAssignments": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "tags": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "minimumTlsVersion": { + "type": "string", + "defaultValue": "1.2", + "allowedValues": [ + "1.0", + "1.1", + "1.2" + ], + "metadata": { + "description": "Optional. Requires clients to use a specified TLS version (or higher) to connect." + } + }, + "capacity": { + "type": "int", + "defaultValue": 2, + "metadata": { + "description": "Optional. The size of the RedisEnterprise cluster. Defaults to 2. Valid values are (2, 4, 6, ...) for Enterprise SKUs and (3, 9, 15, ...) for Flash SKUs." + } + }, + "skuName": { + "type": "string", + "defaultValue": "Enterprise_E10", + "allowedValues": [ + "EnterpriseFlash_F1500", + "EnterpriseFlash_F300", + "EnterpriseFlash_F700", + "Enterprise_E10", + "Enterprise_E100", + "Enterprise_E20", + "Enterprise_E50" + ], + "metadata": { + "description": "Optional. The type of RedisEnterprise cluster to deploy." + } + }, + "zoneRedundant": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. When true, replicas will be provisioned in availability zones specified in the zones parameter." + } + }, + "zones": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. If the zoneRedundant parameter is true, replicas will be provisioned in the availability zones specified here. Otherwise, the service will choose where replicas are deployed." + } + }, + "privateEndpoints": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible." + } + }, + "diagnosticSettingsName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The name of the diagnostic setting, if deployed. If left empty, it defaults to \"-diagnosticSettings\"." + } + }, + "diagnosticStorageAccountId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "diagnosticWorkspaceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "diagnosticEventHubAuthorizationRuleId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." + } + }, + "diagnosticEventHubName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "diagnosticLogCategoriesToEnable": { + "type": "array", + "defaultValue": [ + "allLogs" + ], + "allowedValues": [ + "", + "allLogs", + "ConnectedClientList" + ], + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + } + }, + "diagnosticMetricsToEnable": { + "type": "array", + "defaultValue": [ + "AllMetrics" + ], + "allowedValues": [ + "AllMetrics" + ], + "metadata": { + "description": "Optional. The name of metrics that will be streamed." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + } + }, + "variables": { + "copy": [ + { + "name": "diagnosticsLogsSpecified", + "count": "[length(filter(parameters('diagnosticLogCategoriesToEnable'), lambda('item', and(not(equals(lambdaVariables('item'), 'allLogs')), not(equals(lambdaVariables('item'), ''))))))]", + "input": { + "category": "[filter(parameters('diagnosticLogCategoriesToEnable'), lambda('item', and(not(equals(lambdaVariables('item'), 'allLogs')), not(equals(lambdaVariables('item'), '')))))[copyIndex('diagnosticsLogsSpecified')]]", + "enabled": true + } + }, + { + "name": "diagnosticsMetrics", + "count": "[length(parameters('diagnosticMetricsToEnable'))]", + "input": { + "category": "[parameters('diagnosticMetricsToEnable')[copyIndex('diagnosticsMetrics')]]", + "timeGrain": null, + "enabled": true + } + } + ], + "availabilityZones": "[if(parameters('zoneRedundant'), if(not(empty(parameters('zones'))), parameters('zones'), pickZones('Microsoft.Cache', 'redisEnterprise', parameters('location'), 3)), createArray())]", + "diagnosticsLogs": "[if(contains(parameters('diagnosticLogCategoriesToEnable'), 'allLogs'), createArray(createObject('categoryGroup', 'allLogs', 'enabled', true())), if(contains(parameters('diagnosticLogCategoriesToEnable'), ''), createArray(), variables('diagnosticsLogsSpecified')))]", + "enableReferencedModulesTelemetry": false + }, + "resources": [ + { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + { + "type": "Microsoft.Cache/redisEnterprise", + "apiVersion": "2023-07-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "sku": { + "capacity": "[parameters('capacity')]", + "name": "[parameters('skuName')]" + }, + "properties": { + "minimumTlsVersion": "[parameters('minimumTlsVersion')]" + }, + "zones": "[variables('availabilityZones')]" + }, + { + "condition": "[not(empty(parameters('lock')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Cache/redisEnterprise/{0}', parameters('name'))]", + "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "properties": { + "level": "[parameters('lock')]", + "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + }, + "dependsOn": [ + "[resourceId('Microsoft.Cache/redisEnterprise', parameters('name'))]" + ] + }, + { + "condition": "[or(or(or(not(empty(parameters('diagnosticStorageAccountId'))), not(empty(parameters('diagnosticWorkspaceId')))), not(empty(parameters('diagnosticEventHubAuthorizationRuleId')))), not(empty(parameters('diagnosticEventHubName'))))]", + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.Cache/redisEnterprise/{0}', parameters('name'))]", + "name": "[if(not(empty(parameters('diagnosticSettingsName'))), parameters('diagnosticSettingsName'), format('{0}-diagnosticSettings', parameters('name')))]", + "properties": { + "storageAccountId": "[if(empty(parameters('diagnosticStorageAccountId')), null(), parameters('diagnosticStorageAccountId'))]", + "workspaceId": "[if(empty(parameters('diagnosticWorkspaceId')), null(), parameters('diagnosticWorkspaceId'))]", + "eventHubAuthorizationRuleId": "[if(empty(parameters('diagnosticEventHubAuthorizationRuleId')), null(), parameters('diagnosticEventHubAuthorizationRuleId'))]", + "eventHubName": "[if(empty(parameters('diagnosticEventHubName')), null(), parameters('diagnosticEventHubName'))]", + "metrics": "[if(and(and(and(empty(parameters('diagnosticStorageAccountId')), empty(parameters('diagnosticWorkspaceId'))), empty(parameters('diagnosticEventHubAuthorizationRuleId'))), empty(parameters('diagnosticEventHubName'))), null(), variables('diagnosticsMetrics'))]", + "logs": "[if(and(and(and(empty(parameters('diagnosticStorageAccountId')), empty(parameters('diagnosticWorkspaceId'))), empty(parameters('diagnosticEventHubAuthorizationRuleId'))), empty(parameters('diagnosticEventHubName'))), null(), variables('diagnosticsLogs'))]" + }, + "dependsOn": [ + "[resourceId('Microsoft.Cache/redisEnterprise', parameters('name'))]" + ] + }, + { + "copy": { + "name": "redisCacheEnterprise_rbac", + "count": "[length(parameters('roleAssignments'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-redisCacheEnterprise-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", + "principalIds": { + "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" + }, + "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", + "roleDefinitionIdOrName": { + "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" + }, + "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", + "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", + "resourceId": { + "value": "[resourceId('Microsoft.Cache/redisEnterprise', parameters('name'))]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.21.1.54444", + "templateHash": "2462654739530119148" + } + }, + "parameters": { + "principalIds": { + "type": "array", + "metadata": { + "description": "Required. The IDs of the principals to assign the role to." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of the resource to apply the role assignment to." + } + }, + "principalType": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "ServicePrincipal", + "Group", + "User", + "ForeignGroup", + "Device", + "" + ], + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "defaultValue": "2.0", + "allowedValues": [ + "2.0" + ], + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Id of the delegated managed identity resource." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", + "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", + "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", + "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", + "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", + "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", + "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Redis Cache Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e0f68234-74aa-48ed-b826-c38b57376e17')]", + "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": [ + { + "copy": { + "name": "roleAssignment", + "count": "[length(parameters('principalIds'))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Cache/redisEnterprise/{0}', last(split(parameters('resourceId'), '/')))]", + "name": "[guid(resourceId('Microsoft.Cache/redisEnterprise', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", + "properties": { + "description": "[parameters('description')]", + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", + "principalId": "[parameters('principalIds')[copyIndex()]]", + "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", + "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", + "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", + "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" + } + } + ] + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Cache/redisEnterprise', parameters('name'))]" + ] + }, + { + "copy": { + "name": "redisCacheEnterprise_privateEndpoints", + "count": "[length(parameters('privateEndpoints'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-redisCacheEnterprise-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "groupIds": { + "value": [ + "[parameters('privateEndpoints')[copyIndex()].service]" + ] + }, + "name": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'name'), createObject('value', parameters('privateEndpoints')[copyIndex()].name), createObject('value', format('pe-{0}-{1}-{2}', last(split(resourceId('Microsoft.Cache/redisEnterprise', parameters('name')), '/')), parameters('privateEndpoints')[copyIndex()].service, copyIndex())))]", + "serviceResourceId": { + "value": "[resourceId('Microsoft.Cache/redisEnterprise', parameters('name'))]" + }, + "subnetResourceId": { + "value": "[parameters('privateEndpoints')[copyIndex()].subnetResourceId]" + }, + "enableDefaultTelemetry": { + "value": "[variables('enableReferencedModulesTelemetry')]" + }, + "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", + "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", + "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", + "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", + "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", + "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", + "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.21.1.54444", + "templateHash": "17036874096652764314" + }, + "name": "Private Endpoints", + "description": "This module deploys a Private Endpoint.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the private endpoint resource to create." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "serviceResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the resource that needs to be connected to the network." + } + }, + "applicationSecurityGroups": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "ipConfigurations": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "groupIds": { + "type": "array", + "metadata": { + "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." + } + }, + "privateDnsZoneGroup": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "lock": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "", + "CanNotDelete", + "ReadOnly" + ], + "metadata": { + "description": "Optional. Specify the type of lock." + } + }, + "roleAssignments": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "tags": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "customDnsConfigs": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "manualPrivateLinkServiceConnections": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Manual PrivateLink Service Connections." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + } + }, + "variables": { + "enableReferencedModulesTelemetry": false + }, + "resources": [ + { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + { + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-04-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", + "customDnsConfigs": "[parameters('customDnsConfigs')]", + "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", + "ipConfigurations": "[parameters('ipConfigurations')]", + "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "privateLinkServiceConnections": [ + { + "name": "[parameters('name')]", + "properties": { + "privateLinkServiceId": "[parameters('serviceResourceId')]", + "groupIds": "[parameters('groupIds')]" + } + } + ], + "subnet": { + "id": "[parameters('subnetResourceId')]" + } + } + }, + { + "condition": "[not(empty(parameters('lock')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "properties": { + "level": "[parameters('lock')]", + "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + ] + }, + { + "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "privateDNSResourceIds": { + "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + }, + "privateEndpointName": { + "value": "[parameters('name')]" + }, + "enableDefaultTelemetry": { + "value": "[variables('enableReferencedModulesTelemetry')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.21.1.54444", + "templateHash": "2469208411936339153" + }, + "name": "Private Endpoint Private DNS Zone Groups", + "description": "This module deploys a Private Endpoint Private DNS Zone Group.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "privateEndpointName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." + } + }, + "privateDNSResourceIds": { + "type": "array", + "minLength": 1, + "maxLength": 5, + "metadata": { + "description": "Required. Array of private DNS zone resource IDs. A DNS zone group can support up to 5 DNS zones." + } + }, + "name": { + "type": "string", + "defaultValue": "default", + "metadata": { + "description": "Optional. The name of the private DNS zone group." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + } + }, + "variables": { + "copy": [ + { + "name": "privateDnsZoneConfigs", + "count": "[length(parameters('privateDNSResourceIds'))]", + "input": { + "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "properties": { + "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + } + } + } + ] + }, + "resources": [ + { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + { + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", + "properties": { + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint DNS zone group." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint DNS zone group." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', parameters('privateEndpointName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint DNS zone group was deployed into." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + ] + }, + { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(parameters('roleAssignments'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", + "principalIds": { + "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" + }, + "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", + "roleDefinitionIdOrName": { + "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" + }, + "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", + "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", + "resourceId": { + "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.21.1.54444", + "templateHash": "13032708393704093995" + } + }, + "parameters": { + "principalIds": { + "type": "array", + "metadata": { + "description": "Required. The IDs of the principals to assign the role to." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of the resource to apply the role assignment to." + } + }, + "principalType": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "ServicePrincipal", + "Group", + "User", + "ForeignGroup", + "Device", + "" + ], + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "defaultValue": "2.0", + "allowedValues": [ + "2.0" + ], + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Id of the delegated managed identity resource." + } + } + }, + "variables": { + "builtInRoleNames": { + "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", + "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", + "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", + "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", + "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", + "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", + "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", + "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", + "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", + "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", + "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", + "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", + "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", + "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", + "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", + "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", + "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", + "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", + "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", + "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", + "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", + "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", + "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", + "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", + "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", + "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" + } + }, + "resources": [ + { + "copy": { + "name": "roleAssignment", + "count": "[length(parameters('principalIds'))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", + "properties": { + "description": "[parameters('description')]", + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", + "principalId": "[parameters('principalIds')[copyIndex()]]", + "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", + "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", + "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", + "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" + } + } + ] + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + ] + } + ], + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint." + }, + "value": "[parameters('name')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Cache/redisEnterprise', parameters('name'))]" + ] + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the redis cache enterprise." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the redis cache enterprise." + }, + "value": "[resourceId('Microsoft.Cache/redisEnterprise', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the redis cache enterprise was created in." + }, + "value": "[resourceGroup().name]" + }, + "hostName": { + "type": "string", + "metadata": { + "description": "Redis hostname." + }, + "value": "[reference(resourceId('Microsoft.Cache/redisEnterprise', parameters('name')), '2023-07-01').hostName]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference(resourceId('Microsoft.Cache/redisEnterprise', parameters('name')), '2023-07-01', 'full').location]" + } + } +} \ No newline at end of file diff --git a/modules/cache/redis-enterprise/version.json b/modules/cache/redis-enterprise/version.json new file mode 100644 index 0000000000..04a0dd1a80 --- /dev/null +++ b/modules/cache/redis-enterprise/version.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.5", + "pathFilters": [ + "./main.json" + ] +} From 166427db1ce8636667b1b56e12f2956599c6666f Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Wed, 13 Sep 2023 21:58:40 +1200 Subject: [PATCH 02/17] generated docs --- .../ms.cache.redisenterprise.yml | 51 +++++++++++ .../workflows/ms.cache.redisenterprise.yml | 85 +++++++++++++++++++ modules/cache/redis-enterprise/README.md | 70 ++++----------- modules/cache/redis-enterprise/main.bicep | 2 +- modules/cache/redis-enterprise/main.json | 8 +- 5 files changed, 157 insertions(+), 59 deletions(-) create mode 100644 .azuredevops/modulePipelines/ms.cache.redisenterprise.yml create mode 100644 .github/workflows/ms.cache.redisenterprise.yml diff --git a/.azuredevops/modulePipelines/ms.cache.redisenterprise.yml b/.azuredevops/modulePipelines/ms.cache.redisenterprise.yml new file mode 100644 index 0000000000..1747ee91a9 --- /dev/null +++ b/.azuredevops/modulePipelines/ms.cache.redisenterprise.yml @@ -0,0 +1,51 @@ +name: 'Cache - Redis Enterprise' + +parameters: + - name: staticValidation + displayName: Execute static validation + type: boolean + default: true + - name: deploymentValidation + displayName: Execute deployment validation + type: boolean + default: true + - name: removeDeployment + displayName: Remove deployed module + type: boolean + default: true + - name: prerelease + displayName: Publish prerelease module + type: boolean + default: false + +pr: none + +trigger: + batch: true + branches: + include: + - main + paths: + include: + - '/modules/cache/redis-enterprise/*' + - '/modules/network/private-endpoint/*' + - '/.azuredevops/modulePipelines/ms.cache.redisenterprise.yml' + - '/.azuredevops/pipelineTemplates/*.yml' + - '/utilities/pipelines/*' + exclude: + - '/utilities/pipelines/deploymentRemoval/*' + - '/**/*.md' + +variables: + - template: '../../settings.yml' + - group: 'PLATFORM_VARIABLES' + - name: modulePath + value: '/modules/cache/redis' + +stages: + - template: /.azuredevops/pipelineTemplates/stages.module.yml + parameters: + staticValidation: '${{ parameters.staticValidation }}' + deploymentValidation: '${{ parameters.deploymentValidation }}' + removeDeployment: '${{ parameters.removeDeployment }}' + prerelease: '${{ parameters.prerelease }}' diff --git a/.github/workflows/ms.cache.redisenterprise.yml b/.github/workflows/ms.cache.redisenterprise.yml new file mode 100644 index 0000000000..e7882a5cfa --- /dev/null +++ b/.github/workflows/ms.cache.redisenterprise.yml @@ -0,0 +1,85 @@ +name: 'Cache - Redis Enterprise' + +on: + workflow_dispatch: + inputs: + staticValidation: + type: boolean + description: 'Execute static validation' + required: false + default: true + deploymentValidation: + type: boolean + description: 'Execute deployment validation' + required: false + default: true + removeDeployment: + type: boolean + description: 'Remove deployed module' + required: false + default: true + prerelease: + type: boolean + description: 'Publish prerelease module' + required: false + default: false + push: + branches: + - main + paths: + - 'modules/cache/redis-enterprise/**' + - 'modules/network/private-endpoint/**' + - '.github/actions/templates/**' + - '.github/workflows/template.module.yml' + - '.github/workflows/ms.cache.redisenterprise.yml' + - 'utilities/pipelines/**' + - '!utilities/pipelines/deploymentRemoval/**' + - '!*/**/README.md' + +env: + modulePath: 'modules/cache/redis' + workflowPath: '.github/workflows/ms.cache.redisenterprise.yml' + +concurrency: + group: ${{ github.workflow }} + +jobs: + ########################### + # Initialize pipeline # + ########################### + job_initialize_pipeline: + runs-on: ubuntu-20.04 + name: 'Initialize pipeline' + steps: + - name: 'Checkout' + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: 'Set input parameters to output variables' + id: get-workflow-param + uses: ./.github/actions/templates/getWorkflowInput + with: + workflowPath: '${{ env.workflowPath}}' + - name: 'Get parameter file paths' + id: get-module-test-file-paths + uses: ./.github/actions/templates/getModuleTestFiles + with: + modulePath: '${{ env.modulePath }}' + outputs: + workflowInput: ${{ steps.get-workflow-param.outputs.workflowInput }} + moduleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.moduleTestFilePaths }} + modulePath: '${{ env.modulePath }}' + + ############################## + # Call reusable workflow # + ############################## + call-workflow-passing-data: + name: 'Module' + needs: + - job_initialize_pipeline + uses: ./.github/workflows/template.module.yml + with: + workflowInput: '${{ needs.job_initialize_pipeline.outputs.workflowInput }}' + moduleTestFilePaths: '${{ needs.job_initialize_pipeline.outputs.moduleTestFilePaths }}' + modulePath: '${{ needs.job_initialize_pipeline.outputs.modulePath}}' + secrets: inherit diff --git a/modules/cache/redis-enterprise/README.md b/modules/cache/redis-enterprise/README.md index 713fbd99f7..c4789c7bd5 100644 --- a/modules/cache/redis-enterprise/README.md +++ b/modules/cache/redis-enterprise/README.md @@ -1,6 +1,6 @@ -# Redis Cache `[Microsoft.Cache/Redis]` +# Redis Cache Enterprise `[Microsoft.Cache/redisEnterprise]` -This module deploys a Redis Cache. +This module deploys a Redis Cache Enterprise. ## Navigation @@ -16,7 +16,7 @@ This module deploys a Redis Cache. | :-- | :-- | | `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | | `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | -| `Microsoft.Cache/redis` | [2021-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Cache/2021-06-01/redis) | +| `Microsoft.Cache/redisEnterprise` | [2022-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Cache/2022-01-01/redisEnterprise) | | `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | | `Microsoft.Network/privateEndpoints` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints) | | `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints/privateDnsZoneGroups) | @@ -33,7 +33,7 @@ This module deploys a Redis Cache. | Parameter Name | Type | Default Value | Allowed Values | Description | | :-- | :-- | :-- | :-- | :-- | -| `capacity` | int | `1` | `[0, 1, 2, 3, 4, 5, 6]` | The size of the Redis cache to deploy. Valid values: for C (Basic/Standard) family (0, 1, 2, 3, 4, 5, 6), for P (Premium) family (1, 2, 3, 4). | +| `capacity` | int | `2` | | The size of the RedisEnterprise cluster. Defaults to 2. Valid values are (2, 4, 6, ...) for Enterprise SKUs and (3, 9, 15, ...) for Flash SKUs. | | `diagnosticEventHubAuthorizationRuleId` | string | `''` | | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | `diagnosticEventHubName` | string | `''` | | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | `diagnosticLogCategoriesToEnable` | array | `[allLogs]` | `['', allLogs, ConnectedClientList]` | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | @@ -42,25 +42,13 @@ This module deploys a Redis Cache. | `diagnosticStorageAccountId` | string | `''` | | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | `diagnosticWorkspaceId` | string | `''` | | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | `enableDefaultTelemetry` | bool | `True` | | Enable telemetry via a Globally Unique Identifier (GUID). | -| `enableNonSslPort` | bool | `False` | | Specifies whether the non-ssl Redis server port (6379) is enabled. | | `location` | string | `[resourceGroup().location]` | | The location to deploy the Redis cache service. | | `lock` | string | `''` | `['', CanNotDelete, ReadOnly]` | Specify the type of lock. | | `minimumTlsVersion` | string | `'1.2'` | `[1.0, 1.1, 1.2]` | Requires clients to use a specified TLS version (or higher) to connect. | | `privateEndpoints` | array | `[]` | | Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible. | -| `publicNetworkAccess` | string | `''` | `['', Disabled, Enabled]` | Whether or not public network access is allowed for this resource. For security reasons it should be disabled. If not specified, it will be disabled by default if private endpoints are set. | -| `redisConfiguration` | object | `{object}` | | All Redis Settings. Few possible keys: rdb-backup-enabled,rdb-storage-connection-string,rdb-backup-frequency,maxmemory-delta,maxmemory-policy,notify-keyspace-events,maxmemory-samples,slowlog-log-slower-than,slowlog-max-len,list-max-ziplist-entries,list-max-ziplist-value,hash-max-ziplist-entries,hash-max-ziplist-value,set-max-intset-entries,zset-max-ziplist-entries,zset-max-ziplist-value etc. | -| `redisVersion` | string | `'6'` | `[4, 6]` | Redis version. Only major version will be used in PUT/PATCH request with current valid values: (4, 6). | -| `replicasPerMaster` | int | `1` | | The number of replicas to be created per primary. | -| `replicasPerPrimary` | int | `1` | | The number of replicas to be created per primary. | | `roleAssignments` | array | `[]` | | Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | -| `shardCount` | int | `1` | | The number of shards to be created on a Premium Cluster Cache. | -| `skuName` | string | `'Basic'` | `[Basic, Premium, Standard]` | The type of Redis cache to deploy. | -| `staticIP` | string | `''` | | Static IP address. Optionally, may be specified when deploying a Redis cache inside an existing Azure Virtual Network; auto assigned by default. | -| `subnetId` | string | `''` | | The full resource ID of a subnet in a virtual network to deploy the Redis cache in. Example format: /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/Microsoft.{Network|ClassicNetwork}/VirtualNetworks/vnet1/subnets/subnet1. | -| `systemAssignedIdentity` | bool | `False` | | Enables system assigned managed identity on the resource. | +| `skuName` | string | `'Enterprise_E10'` | `[Enterprise_E10, Enterprise_E100, Enterprise_E20, Enterprise_E50, EnterpriseFlash_F1500, EnterpriseFlash_F300, EnterpriseFlash_F700]` | The type of RedisEnterprise cluster to deploy. | | `tags` | object | `{object}` | | Tags of the resource. | -| `tenantSettings` | object | `{object}` | | A dictionary of tenant settings. | -| `userAssignedIdentities` | object | `{object}` | | The ID(s) to assign to the resource. | | `zoneRedundant` | bool | `True` | | When true, replicas will be provisioned in availability zones specified in the zones parameter. | | `zones` | array | `[]` | | If the zoneRedundant parameter is true, replicas will be provisioned in the availability zones specified here. Otherwise, the service will choose where replicas are deployed. | @@ -337,11 +325,9 @@ privateEndpoints: [ | :-- | :-- | :-- | | `hostName` | string | Redis hostname. | | `location` | string | The location the resource was deployed into. | -| `name` | string | The resource name. | -| `resourceGroupName` | string | The name of the resource group the Redis cache was created in. | -| `resourceId` | string | The resource ID. | -| `sslPort` | int | Redis SSL port. | -| `subnetId` | string | The full resource ID of a subnet in a virtual network where the Redis cache was deployed in. | +| `name` | string | The name of the redis cache enterprise. | +| `resourceGroupName` | string | The name of the resource group the redis cache enterprise was created in. | +| `resourceId` | string | The resource ID of the redis cache enterprise. | ## Cross-referenced modules @@ -365,11 +351,11 @@ The following module usage examples are retrieved from the content of the files

via Bicep module ```bicep -module redis './cache/redis/main.bicep' = { - name: '${uniqueString(deployment().name, location)}-test-crcom' +module redisEnterprise './cache/redis-enterprise/main.bicep' = { + name: '${uniqueString(deployment().name, location)}-test-crecom' params: { // Required parameters - name: 'crcom001' + name: 'crecom001' // Non-required parameters capacity: 2 diagnosticEventHubAuthorizationRuleId: '' @@ -378,7 +364,6 @@ module redis './cache/redis/main.bicep' = { diagnosticStorageAccountId: '' diagnosticWorkspaceId: '' enableDefaultTelemetry: '' - enableNonSslPort: true lock: 'CanNotDelete' minimumTlsVersion: '1.2' privateEndpoints: [ @@ -397,11 +382,6 @@ module redis './cache/redis/main.bicep' = { } } ] - publicNetworkAccess: 'Enabled' - redisVersion: '6' - shardCount: 1 - skuName: 'Premium' - systemAssignedIdentity: true tags: { 'hidden-title': 'This is visible in the resource name' resourceType: 'Redis Cache' @@ -429,7 +409,7 @@ module redis './cache/redis/main.bicep' = { "parameters": { // Required parameters "name": { - "value": "crcom001" + "value": "crecom001" }, // Non-required parameters "capacity": { @@ -453,9 +433,6 @@ module redis './cache/redis/main.bicep' = { "enableDefaultTelemetry": { "value": "" }, - "enableNonSslPort": { - "value": true - }, "lock": { "value": "CanNotDelete" }, @@ -480,21 +457,6 @@ module redis './cache/redis/main.bicep' = { } ] }, - "publicNetworkAccess": { - "value": "Enabled" - }, - "redisVersion": { - "value": "6" - }, - "shardCount": { - "value": 1 - }, - "skuName": { - "value": "Premium" - }, - "systemAssignedIdentity": { - "value": true - }, "tags": { "value": { "hidden-title": "This is visible in the resource name", @@ -524,11 +486,11 @@ module redis './cache/redis/main.bicep' = { via Bicep module ```bicep -module redis './cache/redis/main.bicep' = { - name: '${uniqueString(deployment().name, location)}-test-crmin' +module redisEnterprise './cache/redis-enterprise/main.bicep' = { + name: '${uniqueString(deployment().name, location)}-test-cremin' params: { // Required parameters - name: 'crmin001' + name: 'cremin001' // Non-required parameters enableDefaultTelemetry: '' } @@ -549,7 +511,7 @@ module redis './cache/redis/main.bicep' = { "parameters": { // Required parameters "name": { - "value": "crmin001" + "value": "cremin001" }, // Non-required parameters "enableDefaultTelemetry": { diff --git a/modules/cache/redis-enterprise/main.bicep b/modules/cache/redis-enterprise/main.bicep index 88eff95375..48ce37aee2 100644 --- a/modules/cache/redis-enterprise/main.bicep +++ b/modules/cache/redis-enterprise/main.bicep @@ -124,7 +124,7 @@ resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (ena } } -resource redisCacheEnterprise 'Microsoft.Cache/redisEnterprise@2023-07-01' = { +resource redisCacheEnterprise 'Microsoft.Cache/redisEnterprise@2022-01-01' = { name: name location: location tags: tags diff --git a/modules/cache/redis-enterprise/main.json b/modules/cache/redis-enterprise/main.json index d93c58f9ba..0c0e34f024 100644 --- a/modules/cache/redis-enterprise/main.json +++ b/modules/cache/redis-enterprise/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.21.1.54444", - "templateHash": "1782588459974283676" + "templateHash": "11103107364849919148" }, "name": "Redis Cache Enterprise", "description": "This module deploys a Redis Cache Enterprise.", @@ -217,7 +217,7 @@ }, { "type": "Microsoft.Cache/redisEnterprise", - "apiVersion": "2023-07-01", + "apiVersion": "2022-01-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", @@ -1003,14 +1003,14 @@ "metadata": { "description": "Redis hostname." }, - "value": "[reference(resourceId('Microsoft.Cache/redisEnterprise', parameters('name')), '2023-07-01').hostName]" + "value": "[reference(resourceId('Microsoft.Cache/redisEnterprise', parameters('name')), '2022-01-01').hostName]" }, "location": { "type": "string", "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Cache/redisEnterprise', parameters('name')), '2023-07-01', 'full').location]" + "value": "[reference(resourceId('Microsoft.Cache/redisEnterprise', parameters('name')), '2022-01-01', 'full').location]" } } } \ No newline at end of file From 183b58aeee5387a6b7c893a3a691fc2cdf9031ab Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Thu, 14 Sep 2023 15:09:20 +1200 Subject: [PATCH 03/17] updated redis --- .azuredevops/modulePipelines/ms.cache.redisenterprise.yml | 2 +- .github/workflows/ms.cache.redisenterprise.yml | 2 +- .../redis-enterprise/.test/common/dependencies.bicep | 2 +- .../cache/redis-enterprise/.test/common/main.test.bicep | 4 ++-- modules/cache/redis-enterprise/README.md | 8 +++++--- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/.azuredevops/modulePipelines/ms.cache.redisenterprise.yml b/.azuredevops/modulePipelines/ms.cache.redisenterprise.yml index 1747ee91a9..4b5de630bb 100644 --- a/.azuredevops/modulePipelines/ms.cache.redisenterprise.yml +++ b/.azuredevops/modulePipelines/ms.cache.redisenterprise.yml @@ -40,7 +40,7 @@ variables: - template: '../../settings.yml' - group: 'PLATFORM_VARIABLES' - name: modulePath - value: '/modules/cache/redis' + value: '/modules/cache/redis-enterprise' stages: - template: /.azuredevops/pipelineTemplates/stages.module.yml diff --git a/.github/workflows/ms.cache.redisenterprise.yml b/.github/workflows/ms.cache.redisenterprise.yml index e7882a5cfa..600c10df60 100644 --- a/.github/workflows/ms.cache.redisenterprise.yml +++ b/.github/workflows/ms.cache.redisenterprise.yml @@ -37,7 +37,7 @@ on: - '!*/**/README.md' env: - modulePath: 'modules/cache/redis' + modulePath: 'modules/cache/redis-enterprise' workflowPath: '.github/workflows/ms.cache.redisenterprise.yml' concurrency: diff --git a/modules/cache/redis-enterprise/.test/common/dependencies.bicep b/modules/cache/redis-enterprise/.test/common/dependencies.bicep index 6e785bcc07..1c46f0598e 100644 --- a/modules/cache/redis-enterprise/.test/common/dependencies.bicep +++ b/modules/cache/redis-enterprise/.test/common/dependencies.bicep @@ -27,7 +27,7 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { } resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { - name: 'privatelink.azuresynapse.net' + name: 'privatelink.redisenterprise.cache.azure.net' location: 'global' resource virtualNetworkLinks 'virtualNetworkLinks@2020-06-01' = { diff --git a/modules/cache/redis-enterprise/.test/common/main.test.bicep b/modules/cache/redis-enterprise/.test/common/main.test.bicep index 7a2bd4069f..2a5b78db74 100644 --- a/modules/cache/redis-enterprise/.test/common/main.test.bicep +++ b/modules/cache/redis-enterprise/.test/common/main.test.bicep @@ -72,7 +72,7 @@ module testDeployment '../../main.bicep' = { lock: 'CanNotDelete' minimumTlsVersion: '1.2' zoneRedundant: true - zones: [ 1, 2 ] + zones: [ 1, 2, 3 ] privateEndpoints: [ { privateDnsZoneGroup: { @@ -80,7 +80,7 @@ module testDeployment '../../main.bicep' = { nestedDependencies.outputs.privateDNSResourceId ] } - service: 'redisCache' + service: 'redisEnterprise' subnetResourceId: nestedDependencies.outputs.subnetResourceId tags: { 'hidden-title': 'This is visible in the resource name' diff --git a/modules/cache/redis-enterprise/README.md b/modules/cache/redis-enterprise/README.md index c4789c7bd5..f677c1a00c 100644 --- a/modules/cache/redis-enterprise/README.md +++ b/modules/cache/redis-enterprise/README.md @@ -373,7 +373,7 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { '' ] } - service: 'redisCache' + service: 'redisEnterprise' subnetResourceId: '' tags: { Environment: 'Non-Prod' @@ -390,6 +390,7 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { zones: [ 1 2 + 3 ] } } @@ -447,7 +448,7 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { "" ] }, - "service": "redisCache", + "service": "redisEnterprise", "subnetResourceId": "", "tags": { "Environment": "Non-Prod", @@ -469,7 +470,8 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { "zones": { "value": [ 1, - 2 + 2, + 3 ] } } From 7cdf7593476a1035048c40082eee59b3015653db Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Fri, 15 Sep 2023 15:38:05 +1200 Subject: [PATCH 04/17] updated redis with databases --- .../.test/common/main.test.bicep | 38 ++- modules/cache/redis-enterprise/README.md | 115 ++++++-- .../cache/redis-enterprise/database/README.md | 60 ++++ .../redis-enterprise/database/main.bicep | 118 ++++++++ .../cache/redis-enterprise/database/main.json | 199 +++++++++++++ .../redis-enterprise/database/version.json | 7 + modules/cache/redis-enterprise/main.bicep | 46 ++- modules/cache/redis-enterprise/main.json | 268 +++++++++++++++++- 8 files changed, 798 insertions(+), 53 deletions(-) create mode 100644 modules/cache/redis-enterprise/database/README.md create mode 100644 modules/cache/redis-enterprise/database/main.bicep create mode 100644 modules/cache/redis-enterprise/database/main.json create mode 100644 modules/cache/redis-enterprise/database/version.json diff --git a/modules/cache/redis-enterprise/.test/common/main.test.bicep b/modules/cache/redis-enterprise/.test/common/main.test.bicep index 2a5b78db74..baff5f5514 100644 --- a/modules/cache/redis-enterprise/.test/common/main.test.bicep +++ b/modules/cache/redis-enterprise/.test/common/main.test.bicep @@ -72,7 +72,6 @@ module testDeployment '../../main.bicep' = { lock: 'CanNotDelete' minimumTlsVersion: '1.2' zoneRedundant: true - zones: [ 1, 2, 3 ] privateEndpoints: [ { privateDnsZoneGroup: { @@ -89,6 +88,43 @@ module testDeployment '../../main.bicep' = { } } ] + databases: [ + { + name: '${namePrefix}${serviceShort}-db-01' + } + { + name: '${namePrefix}${serviceShort}-db-02' + clusteringPolicy: 'EnterpriseCluster' + evictionPolicy: 'AllKeysLFU' + persistenceAofEnabled: true + persistenceAofFrequency: 'always' + persistenceRdbEnabled: true + persistenceRdbFrequency: '12h' + port: 5000 + } + { + name: '${namePrefix}${serviceShort}-db-03' + persistenceAofEnabled: true + persistenceRdbEnabled: true + port: 6000 + modules: [ + { + name: 'RedisBloom' + } + { + name: 'RedisTimeSeries' + } + ] + geoReplication: { + groupNickname: '${namePrefix}${serviceShort}-db-03-rep' + linkedDatabases: [ + { + id: '${namePrefix}${serviceShort}-db-01' + } + ] + } + } + ] tags: { 'hidden-title': 'This is visible in the resource name' resourceType: 'Redis Cache' diff --git a/modules/cache/redis-enterprise/README.md b/modules/cache/redis-enterprise/README.md index f677c1a00c..eb56f87d6e 100644 --- a/modules/cache/redis-enterprise/README.md +++ b/modules/cache/redis-enterprise/README.md @@ -14,12 +14,13 @@ This module deploys a Redis Cache Enterprise. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | -| `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | -| `Microsoft.Cache/redisEnterprise` | [2022-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Cache/2022-01-01/redisEnterprise) | -| `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | -| `Microsoft.Network/privateEndpoints` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints) | -| `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints/privateDnsZoneGroups) | +| `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates) | +| `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates) | +| `Microsoft.Cache/redisEnterprise` | [2022-01-01](https://learn.microsoft.com/en-us/azure/templates) | +| `Microsoft.Cache/redisEnterprise/databases` | [2022-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Cache/redisEnterprise) | +| `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates) | +| `Microsoft.Network/privateEndpoints` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates) | +| `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/privateEndpoints) | ## Parameters @@ -27,30 +28,30 @@ This module deploys a Redis Cache Enterprise. | Parameter Name | Type | Description | | :-- | :-- | :-- | -| `name` | string | The name of the Redis cache resource. | +| `name` | string | The name of the Redis Cache Enerprise resource. | **Optional parameters** | Parameter Name | Type | Default Value | Allowed Values | Description | | :-- | :-- | :-- | :-- | :-- | -| `capacity` | int | `2` | | The size of the RedisEnterprise cluster. Defaults to 2. Valid values are (2, 4, 6, ...) for Enterprise SKUs and (3, 9, 15, ...) for Flash SKUs. | +| `capacity` | int | `2` | | The size of the Redis Enterprise Cluster. Defaults to 2. Valid values are (2, 4, 6, ...) for Enterprise SKUs and (3, 9, 15, ...) for Flash SKUs. | +| `databases` | array | `[]` | | The databases to create in the Redis Cache Enterprise Cluster. | | `diagnosticEventHubAuthorizationRuleId` | string | `''` | | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | `diagnosticEventHubName` | string | `''` | | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | -| `diagnosticLogCategoriesToEnable` | array | `[allLogs]` | `['', allLogs, ConnectedClientList]` | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| `diagnosticLogCategoriesToEnable` | array | `[]` | `['', allLogs, audit, ConnectionEvents]` | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | | `diagnosticMetricsToEnable` | array | `[AllMetrics]` | `[AllMetrics]` | The name of metrics that will be streamed. | | `diagnosticSettingsName` | string | `''` | | The name of the diagnostic setting, if deployed. If left empty, it defaults to "-diagnosticSettings". | | `diagnosticStorageAccountId` | string | `''` | | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | `diagnosticWorkspaceId` | string | `''` | | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | | `enableDefaultTelemetry` | bool | `True` | | Enable telemetry via a Globally Unique Identifier (GUID). | -| `location` | string | `[resourceGroup().location]` | | The location to deploy the Redis cache service. | +| `location` | string | `[resourceGroup().location]` | | The geo-location where the resource lives. | | `lock` | string | `''` | `['', CanNotDelete, ReadOnly]` | Specify the type of lock. | | `minimumTlsVersion` | string | `'1.2'` | `[1.0, 1.1, 1.2]` | Requires clients to use a specified TLS version (or higher) to connect. | | `privateEndpoints` | array | `[]` | | Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible. | | `roleAssignments` | array | `[]` | | Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | -| `skuName` | string | `'Enterprise_E10'` | `[Enterprise_E10, Enterprise_E100, Enterprise_E20, Enterprise_E50, EnterpriseFlash_F1500, EnterpriseFlash_F300, EnterpriseFlash_F700]` | The type of RedisEnterprise cluster to deploy. | +| `skuName` | string | `'Enterprise_E10'` | `[Enterprise_E10, Enterprise_E100, Enterprise_E20, Enterprise_E50, EnterpriseFlash_F1500, EnterpriseFlash_F300, EnterpriseFlash_F700]` | The type of Redis Enterprise Cluster to deploy. | | `tags` | object | `{object}` | | Tags of the resource. | -| `zoneRedundant` | bool | `True` | | When true, replicas will be provisioned in availability zones specified in the zones parameter. | -| `zones` | array | `[]` | | If the zoneRedundant parameter is true, replicas will be provisioned in the availability zones specified here. Otherwise, the service will choose where replicas are deployed. | +| `zoneRedundant` | bool | `True` | | When true, the cluster will be deployed across availability zones. | ### Parameter Usage: `roleAssignments` @@ -358,6 +359,43 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { name: 'crecom001' // Non-required parameters capacity: 2 + databases: [ + { + name: 'crecom-db-01' + } + { + clusteringPolicy: 'EnterpriseCluster' + evictionPolicy: 'AllKeysLFU' + name: 'crecom-db-02' + persistenceAofEnabled: true + persistenceAofFrequency: 'always' + persistenceRdbEnabled: true + persistenceRdbFrequency: '12h' + port: 5000 + } + { + geoReplication: { + groupNickname: 'crecom-db-03-rep' + linkedDatabases: [ + { + id: 'crecom-db-01' + } + ] + } + modules: [ + { + name: 'RedisBloom' + } + { + name: 'RedisTimeSeries' + } + ] + name: 'crecom-db-03' + persistenceAofEnabled: true + persistenceRdbEnabled: true + port: 6000 + } + ] diagnosticEventHubAuthorizationRuleId: '' diagnosticEventHubName: '' diagnosticSettingsName: 'redisdiagnostics' @@ -387,11 +425,6 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { resourceType: 'Redis Cache' } zoneRedundant: true - zones: [ - 1 - 2 - 3 - ] } } ``` @@ -416,6 +449,45 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { "capacity": { "value": 2 }, + "databases": { + "value": [ + { + "name": "crecom-db-01" + }, + { + "clusteringPolicy": "EnterpriseCluster", + "evictionPolicy": "AllKeysLFU", + "name": "crecom-db-02", + "persistenceAofEnabled": true, + "persistenceAofFrequency": "always", + "persistenceRdbEnabled": true, + "persistenceRdbFrequency": "12h", + "port": 5000 + }, + { + "geoReplication": { + "groupNickname": "crecom-db-03-rep", + "linkedDatabases": [ + { + "id": "crecom-db-01" + } + ] + }, + "modules": [ + { + "name": "RedisBloom" + }, + { + "name": "RedisTimeSeries" + } + ], + "name": "crecom-db-03", + "persistenceAofEnabled": true, + "persistenceRdbEnabled": true, + "port": 6000 + } + ] + }, "diagnosticEventHubAuthorizationRuleId": { "value": "" }, @@ -466,13 +538,6 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { }, "zoneRedundant": { "value": true - }, - "zones": { - "value": [ - 1, - 2, - 3 - ] } } } diff --git a/modules/cache/redis-enterprise/database/README.md b/modules/cache/redis-enterprise/database/README.md new file mode 100644 index 0000000000..e4a893a494 --- /dev/null +++ b/modules/cache/redis-enterprise/database/README.md @@ -0,0 +1,60 @@ +# Redis Cache Enterprise Databases `[Microsoft.Cache/redisEnterprise/databases]` + +This module deploys a Redis Cache Enterprise Database. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Cache/redisEnterprise/databases` | [2022-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Cache/redisEnterprise) | + +## Parameters + +**Required parameters** + +| Parameter Name | Type | Description | +| :-- | :-- | :-- | +| `name` | string | The name of the database. | + +**Conditional parameters** + +| Parameter Name | Type | Default Value | Description | +| :-- | :-- | :-- | :-- | +| `persistenceAofEnabled` | bool | `False` | Sets whether AOF is enabled. Required if setting AOF frequency. | +| `persistenceRdbEnabled` | bool | `False` | Sets whether RDB is enabled. Required if setting RDB frequency. | +| `redisCacheEnterpriseName` | string | | The name of the parent Redis Cache Enterprise Cluster. Required if the template is used in a standalone deployment. | + +**Optional parameters** + +| Parameter Name | Type | Default Value | Allowed Values | Description | +| :-- | :-- | :-- | :-- | :-- | +| `clientProtocol` | string | `'Encrypted'` | `[Encrypted, Plaintext]` | Specifies whether redis clients can connect using TLS-encrypted or plaintext redis protocols. Default is TLS-encrypted. | +| `clusteringPolicy` | string | `'OSSCluster'` | `[EnterpriseCluster, OSSCluster]` | Clustering policy - default is OSSCluster. Specified at create time. | +| `enableDefaultTelemetry` | bool | `True` | | Enable telemetry via a Globally Unique Identifier (GUID). | +| `evictionPolicy` | string | `'VolatileLRU'` | `[AllKeysLFU, AllKeysLRU, AllKeysRandom, NoEviction, VolatileLFU, VolatileLRU, VolatileRandom, VolatileTTL]` | Redis eviction policy - default is VolatileLRU. | +| `geoReplication` | object | `{object}` | | Optional set of properties to configure geo replication for this database. | +| `location` | string | `[resourceGroup().location]` | | Location for all resources. | +| `modules` | array | `[]` | | Optional set of redis modules to enable in this database - modules can only be added at creation time. | +| `persistenceAofFrequency` | string | `''` | `['', 1s, always]` | Sets the frequency at which data is written to disk. Can be set when AOF is enabled. | +| `persistenceRdbFrequency` | string | `''` | `['', 12h, 1h, 6h]` | Sets the frequency at which a snapshot of the database is created. Can be set when RDB is enabled. | +| `port` | int | `-1` | | TCP port of the database endpoint. Specified at create time. Default is (-1) meaning value is not set and defaults to an available port. | + + +## Outputs + +| Output Name | Type | Description | +| :-- | :-- | :-- | +| `name` | string | The name of the deployed database. | +| `resourceGroupName` | string | The resource group of the deployed database. | +| `resourceId` | string | The resource ID of the deployed database. | + +## Cross-referenced modules + +_None_ diff --git a/modules/cache/redis-enterprise/database/main.bicep b/modules/cache/redis-enterprise/database/main.bicep new file mode 100644 index 0000000000..66ec1d245f --- /dev/null +++ b/modules/cache/redis-enterprise/database/main.bicep @@ -0,0 +1,118 @@ +metadata name = 'Redis Cache Enterprise Databases' +metadata description = 'This module deploys a Redis Cache Enterprise Database.' +metadata owner = 'Azure/module-maintainers' + +@description('Required. The name of the database.') +param name string + +@description('Conditional. The name of the parent Redis Cache Enterprise Cluster. Required if the template is used in a standalone deployment.') +param redisCacheEnterpriseName string + +@allowed([ + 'Encrypted' + 'Plaintext' +]) +@description('Optional. Specifies whether redis clients can connect using TLS-encrypted or plaintext redis protocols. Default is TLS-encrypted.') +param clientProtocol string = 'Encrypted' + +@allowed([ + 'EnterpriseCluster' + 'OSSCluster' +]) +@description('Optional. Clustering policy - default is OSSCluster. Specified at create time.') +param clusteringPolicy string = 'OSSCluster' + +@allowed([ + 'AllKeysLFU' + 'AllKeysLRU' + 'AllKeysRandom' + 'NoEviction' + 'VolatileLFU' + 'VolatileLRU' + 'VolatileRandom' + 'VolatileTTL' +]) +@description('Optional. Redis eviction policy - default is VolatileLRU.') +param evictionPolicy string = 'VolatileLRU' + +@description('Optional. Optional set of properties to configure geo replication for this database.') +param geoReplication object = {} + +@description('Optional. Optional set of redis modules to enable in this database - modules can only be added at creation time.') +param modules array = [] + +@description('Conditional. Sets whether AOF is enabled. Required if setting AOF frequency.') +param persistenceAofEnabled bool = false + +@allowed([ + '' + '1s' + 'always' +]) +@description('Optional. Sets the frequency at which data is written to disk. Can be set when AOF is enabled.') +param persistenceAofFrequency string = '' + +@description('Conditional. Sets whether RDB is enabled. Required if setting RDB frequency.') +param persistenceRdbEnabled bool = false + +@allowed([ + '' + '12h' + '1h' + '6h' +]) +@description('Optional. Sets the frequency at which a snapshot of the database is created. Can be set when RDB is enabled.') +param persistenceRdbFrequency string = '' + +@description('Optional. TCP port of the database endpoint. Specified at create time. Default is (-1) meaning value is not set and defaults to an available port.') +param port int = -1 + +@description('Optional. Location for all resources.') +param location string = resourceGroup().location + +@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +param enableDefaultTelemetry bool = true + +resource defaultTelemetry 'Microsoft.Resources/deployments@2022-09-01' = if (enableDefaultTelemetry) { + name: 'pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-${uniqueString(deployment().name, location)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + } + } +} + +resource redisCacheEnterprise 'Microsoft.Cache/redisEnterprise@2022-01-01' existing = { + name: redisCacheEnterpriseName +} + +resource database 'Microsoft.Cache/redisEnterprise/databases@2022-01-01' = { + name: name + parent: redisCacheEnterprise + properties: { + clientProtocol: !empty(clientProtocol) ? clientProtocol : null + clusteringPolicy: !empty(clusteringPolicy) ? clusteringPolicy : null + evictionPolicy: !empty(evictionPolicy) ? evictionPolicy : null + geoReplication: !empty(geoReplication) ? geoReplication : null + modules: !empty(modules) ? modules : null + persistence: { + aofEnabled: persistenceAofEnabled + aofFrequency: !empty(persistenceAofFrequency) ? persistenceAofFrequency : null + rdbEnabled: persistenceRdbEnabled + rdbFrequency: !empty(persistenceRdbFrequency) ? persistenceRdbFrequency : null + } + port: port != -1 ? port : null + } +} + +@description('The name of the deployed database.') +output name string = database.name + +@description('The resource ID of the deployed database.') +output resourceId string = database.id + +@description('The resource group of the deployed database.') +output resourceGroupName string = resourceGroup().name diff --git a/modules/cache/redis-enterprise/database/main.json b/modules/cache/redis-enterprise/database/main.json new file mode 100644 index 0000000000..699725f9f3 --- /dev/null +++ b/modules/cache/redis-enterprise/database/main.json @@ -0,0 +1,199 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.21.1.54444", + "templateHash": "17740766783826706234" + }, + "name": "Redis Cache Enterprise Databases", + "description": "This module deploys a Redis Cache Enterprise Database.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the database." + } + }, + "redisCacheEnterpriseName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Redis Cache Enterprise Cluster. Required if the template is used in a standalone deployment." + } + }, + "clientProtocol": { + "type": "string", + "defaultValue": "Encrypted", + "allowedValues": [ + "Encrypted", + "Plaintext" + ], + "metadata": { + "description": "Optional. Specifies whether redis clients can connect using TLS-encrypted or plaintext redis protocols. Default is TLS-encrypted." + } + }, + "clusteringPolicy": { + "type": "string", + "defaultValue": "OSSCluster", + "allowedValues": [ + "EnterpriseCluster", + "OSSCluster" + ], + "metadata": { + "description": "Optional. Clustering policy - default is OSSCluster. Specified at create time." + } + }, + "evictionPolicy": { + "type": "string", + "defaultValue": "VolatileLRU", + "allowedValues": [ + "AllKeysLFU", + "AllKeysLRU", + "AllKeysRandom", + "NoEviction", + "VolatileLFU", + "VolatileLRU", + "VolatileRandom", + "VolatileTTL" + ], + "metadata": { + "description": "Optional. Redis eviction policy - default is VolatileLRU." + } + }, + "geoReplication": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Optional set of properties to configure geo replication for this database." + } + }, + "modules": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Optional set of redis modules to enable in this database - modules can only be added at creation time." + } + }, + "persistenceAofEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Conditional. Sets whether AOF is enabled. Required if setting AOF frequency." + } + }, + "persistenceAofFrequency": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "", + "1s", + "always" + ], + "metadata": { + "description": "Optional. Sets the frequency at which data is written to disk. Can be set when AOF is enabled." + } + }, + "persistenceRdbEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Conditional. Sets whether RDB is enabled. Required if setting RDB frequency." + } + }, + "persistenceRdbFrequency": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "", + "12h", + "1h", + "6h" + ], + "metadata": { + "description": "Optional. Sets the frequency at which a snapshot of the database is created. Can be set when RDB is enabled." + } + }, + "port": { + "type": "int", + "defaultValue": -1, + "metadata": { + "description": "Optional. TCP port of the database endpoint. Specified at create time. Default is (-1) meaning value is not set and defaults to an available port." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + } + }, + "resources": [ + { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + { + "type": "Microsoft.Cache/redisEnterprise/databases", + "apiVersion": "2022-01-01", + "name": "[format('{0}/{1}', parameters('redisCacheEnterpriseName'), parameters('name'))]", + "properties": { + "clientProtocol": "[if(not(empty(parameters('clientProtocol'))), parameters('clientProtocol'), null())]", + "clusteringPolicy": "[if(not(empty(parameters('clusteringPolicy'))), parameters('clusteringPolicy'), null())]", + "evictionPolicy": "[if(not(empty(parameters('evictionPolicy'))), parameters('evictionPolicy'), null())]", + "geoReplication": "[if(not(empty(parameters('geoReplication'))), parameters('geoReplication'), null())]", + "modules": "[if(not(empty(parameters('modules'))), parameters('modules'), null())]", + "persistence": { + "aofEnabled": "[parameters('persistenceAofEnabled')]", + "aofFrequency": "[if(not(empty(parameters('persistenceAofFrequency'))), parameters('persistenceAofFrequency'), null())]", + "rdbEnabled": "[parameters('persistenceRdbEnabled')]", + "rdbFrequency": "[if(not(empty(parameters('persistenceRdbFrequency'))), parameters('persistenceRdbFrequency'), null())]" + }, + "port": "[if(not(equals(parameters('port'), -1)), parameters('port'), null())]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed database." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed database." + }, + "value": "[resourceId('Microsoft.Cache/redisEnterprise/databases', parameters('redisCacheEnterpriseName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed database." + }, + "value": "[resourceGroup().name]" + } + } +} \ No newline at end of file diff --git a/modules/cache/redis-enterprise/database/version.json b/modules/cache/redis-enterprise/database/version.json new file mode 100644 index 0000000000..96236a61ba --- /dev/null +++ b/modules/cache/redis-enterprise/database/version.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.4", + "pathFilters": [ + "./main.json" + ] +} diff --git a/modules/cache/redis-enterprise/main.bicep b/modules/cache/redis-enterprise/main.bicep index 48ce37aee2..130716e8f9 100644 --- a/modules/cache/redis-enterprise/main.bicep +++ b/modules/cache/redis-enterprise/main.bicep @@ -2,10 +2,10 @@ metadata name = 'Redis Cache Enterprise' metadata description = 'This module deploys a Redis Cache Enterprise.' metadata owner = 'Azure/module-maintainers' -@description('Optional. The location to deploy the Redis cache service.') +@description('Optional. The geo-location where the resource lives.') param location string = resourceGroup().location -@description('Required. The name of the Redis cache resource.') +@description('Required. The name of the Redis Cache Enerprise resource.') param name string @allowed([ @@ -30,7 +30,7 @@ param tags object = {} @description('Optional. Requires clients to use a specified TLS version (or higher) to connect.') param minimumTlsVersion string = '1.2' -@description('Optional. The size of the RedisEnterprise cluster. Defaults to 2. Valid values are (2, 4, 6, ...) for Enterprise SKUs and (3, 9, 15, ...) for Flash SKUs.') +@description('Optional. The size of the Redis Enterprise Cluster. Defaults to 2. Valid values are (2, 4, 6, ...) for Enterprise SKUs and (3, 9, 15, ...) for Flash SKUs.') param capacity int = 2 @allowed([ @@ -42,18 +42,18 @@ param capacity int = 2 'Enterprise_E20' 'Enterprise_E50' ]) -@description('Optional. The type of RedisEnterprise cluster to deploy.') +@description('Optional. The type of Redis Enterprise Cluster to deploy.') param skuName string = 'Enterprise_E10' -@description('Optional. When true, replicas will be provisioned in availability zones specified in the zones parameter.') +@description('Optional. When true, the cluster will be deployed across availability zones.') param zoneRedundant bool = true -@description('Optional. If the zoneRedundant parameter is true, replicas will be provisioned in the availability zones specified here. Otherwise, the service will choose where replicas are deployed.') -param zones array = [] - @description('Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible.') param privateEndpoints array = [] +@description('Optional. The databases to create in the Redis Cache Enterprise Cluster.') +param databases array = [] + @description('Optional. The name of the diagnostic setting, if deployed. If left empty, it defaults to "-diagnosticSettings".') param diagnosticSettingsName string = '' @@ -73,10 +73,11 @@ param diagnosticEventHubName string = '' @allowed([ '' 'allLogs' - 'ConnectedClientList' + 'ConnectionEvents' + 'audit' ]) param diagnosticLogCategoriesToEnable array = [ - 'allLogs' + '' ] @description('Optional. The name of metrics that will be streamed.') @@ -90,7 +91,7 @@ param diagnosticMetricsToEnable array = [ @description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') param enableDefaultTelemetry bool = true -var availabilityZones = zoneRedundant ? !empty(zones) ? zones : pickZones('Microsoft.Cache', 'redisEnterprise', location, 3) : [] +var availabilityZones = zoneRedundant ? pickZones('Microsoft.Cache', 'redisEnterprise', location, 3) : [] var diagnosticsLogsSpecified = [for category in filter(diagnosticLogCategoriesToEnable, item => item != 'allLogs' && item != ''): { category: category @@ -173,6 +174,26 @@ module redisCacheEnterprise_rbac '.bicep/nested_roleAssignments.bicep' = [for (r } }] +module redisCacheEnterprise_databases 'database/main.bicep' = [for (database, index) in databases: { + name: '${uniqueString(deployment().name, location)}-redisCacheEnterprise-DB-${index}' + params: { + name: database.name + redisCacheEnterpriseName: redisCacheEnterprise.name + location: location + clientProtocol: contains(database, 'clientProtocol') ? database.clientProtocol : 'Encrypted' + clusteringPolicy: contains(database, 'clusteringPolicy') ? database.clusteringPolicy : 'OSSCluster' + evictionPolicy: contains(database, 'evictionPolicy') ? database.evictionPolicy : 'VolatileLRU' + geoReplication: contains(database, 'geoReplication') ? database.geoReplication : {} + modules: contains(database, 'modules') ? database.modules : [] + persistenceAofEnabled: contains(database, 'persistenceAofEnabled') ? database.persistenceAofEnabled : false + persistenceAofFrequency: contains(database, 'persistenceAofFrequency') ? database.persistenceAofFrequency : '' + persistenceRdbEnabled: contains(database, 'persistenceRdbEnabled') ? database.persistenceRdbEnabled : false + persistenceRdbFrequency: contains(database, 'persistenceRdbFrequency') ? database.persistenceRdbFrequency : '' + port: contains(database, 'port') ? database.port : -1 + enableDefaultTelemetry: enableReferencedModulesTelemetry + } +}] + module redisCacheEnterprise_privateEndpoints '../../network/private-endpoint/main.bicep' = [for (privateEndpoint, index) in privateEndpoints: { name: '${uniqueString(deployment().name, location)}-redisCacheEnterprise-PrivateEndpoint-${index}' params: { @@ -208,8 +229,5 @@ output resourceGroupName string = resourceGroup().name @description('Redis hostname.') output hostName string = redisCacheEnterprise.properties.hostName -//@description('The full resource ID of a subnet in a virtual network where the Redis cache was deployed in.') -//output subnetId string = !empty(subnetId) ? redisCacheEnterprise.properties.subnetId : '' - @description('The location the resource was deployed into.') output location string = redisCacheEnterprise.location diff --git a/modules/cache/redis-enterprise/main.json b/modules/cache/redis-enterprise/main.json index 0c0e34f024..4ca01a8717 100644 --- a/modules/cache/redis-enterprise/main.json +++ b/modules/cache/redis-enterprise/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.21.1.54444", - "templateHash": "11103107364849919148" + "templateHash": "11003351351537958776" }, "name": "Redis Cache Enterprise", "description": "This module deploys a Redis Cache Enterprise.", @@ -16,13 +16,13 @@ "type": "string", "defaultValue": "[resourceGroup().location]", "metadata": { - "description": "Optional. The location to deploy the Redis cache service." + "description": "Optional. The geo-location where the resource lives." } }, "name": { "type": "string", "metadata": { - "description": "Required. The name of the Redis cache resource." + "description": "Required. The name of the Redis Cache Enerprise resource." } }, "lock": { @@ -67,7 +67,7 @@ "type": "int", "defaultValue": 2, "metadata": { - "description": "Optional. The size of the RedisEnterprise cluster. Defaults to 2. Valid values are (2, 4, 6, ...) for Enterprise SKUs and (3, 9, 15, ...) for Flash SKUs." + "description": "Optional. The size of the Redis Enterprise Cluster. Defaults to 2. Valid values are (2, 4, 6, ...) for Enterprise SKUs and (3, 9, 15, ...) for Flash SKUs." } }, "skuName": { @@ -83,28 +83,28 @@ "Enterprise_E50" ], "metadata": { - "description": "Optional. The type of RedisEnterprise cluster to deploy." + "description": "Optional. The type of Redis Enterprise Cluster to deploy." } }, "zoneRedundant": { "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. When true, replicas will be provisioned in availability zones specified in the zones parameter." + "description": "Optional. When true, the cluster will be deployed across availability zones." } }, - "zones": { + "privateEndpoints": { "type": "array", "defaultValue": [], "metadata": { - "description": "Optional. If the zoneRedundant parameter is true, replicas will be provisioned in the availability zones specified here. Otherwise, the service will choose where replicas are deployed." + "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible." } }, - "privateEndpoints": { + "databases": { "type": "array", "defaultValue": [], "metadata": { - "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible." + "description": "Optional. The databases to create in the Redis Cache Enterprise Cluster." } }, "diagnosticSettingsName": { @@ -145,12 +145,13 @@ "diagnosticLogCategoriesToEnable": { "type": "array", "defaultValue": [ - "allLogs" + "" ], "allowedValues": [ "", "allLogs", - "ConnectedClientList" + "ConnectionEvents", + "audit" ], "metadata": { "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." @@ -196,7 +197,7 @@ } } ], - "availabilityZones": "[if(parameters('zoneRedundant'), if(not(empty(parameters('zones'))), parameters('zones'), pickZones('Microsoft.Cache', 'redisEnterprise', parameters('location'), 3)), createArray())]", + "availabilityZones": "[if(parameters('zoneRedundant'), pickZones('Microsoft.Cache', 'redisEnterprise', parameters('location'), 3), createArray())]", "diagnosticsLogs": "[if(contains(parameters('diagnosticLogCategoriesToEnable'), 'allLogs'), createArray(createObject('categoryGroup', 'allLogs', 'enabled', true())), if(contains(parameters('diagnosticLogCategoriesToEnable'), ''), createArray(), variables('diagnosticsLogsSpecified')))]", "enableReferencedModulesTelemetry": false }, @@ -411,6 +412,247 @@ "[resourceId('Microsoft.Cache/redisEnterprise', parameters('name'))]" ] }, + { + "copy": { + "name": "redisCacheEnterprise_databases", + "count": "[length(parameters('databases'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-redisCacheEnterprise-DB-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[parameters('databases')[copyIndex()].name]" + }, + "redisCacheEnterpriseName": { + "value": "[parameters('name')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "clientProtocol": "[if(contains(parameters('databases')[copyIndex()], 'clientProtocol'), createObject('value', parameters('databases')[copyIndex()].clientProtocol), createObject('value', 'Encrypted'))]", + "clusteringPolicy": "[if(contains(parameters('databases')[copyIndex()], 'clusteringPolicy'), createObject('value', parameters('databases')[copyIndex()].clusteringPolicy), createObject('value', 'OSSCluster'))]", + "evictionPolicy": "[if(contains(parameters('databases')[copyIndex()], 'evictionPolicy'), createObject('value', parameters('databases')[copyIndex()].evictionPolicy), createObject('value', 'VolatileLRU'))]", + "geoReplication": "[if(contains(parameters('databases')[copyIndex()], 'geoReplication'), createObject('value', parameters('databases')[copyIndex()].geoReplication), createObject('value', createObject()))]", + "modules": "[if(contains(parameters('databases')[copyIndex()], 'modules'), createObject('value', parameters('databases')[copyIndex()].modules), createObject('value', createArray()))]", + "persistenceAofEnabled": "[if(contains(parameters('databases')[copyIndex()], 'persistenceAofEnabled'), createObject('value', parameters('databases')[copyIndex()].persistenceAofEnabled), createObject('value', false()))]", + "persistenceAofFrequency": "[if(contains(parameters('databases')[copyIndex()], 'persistenceAofFrequency'), createObject('value', parameters('databases')[copyIndex()].persistenceAofFrequency), createObject('value', ''))]", + "persistenceRdbEnabled": "[if(contains(parameters('databases')[copyIndex()], 'persistenceRdbEnabled'), createObject('value', parameters('databases')[copyIndex()].persistenceRdbEnabled), createObject('value', false()))]", + "persistenceRdbFrequency": "[if(contains(parameters('databases')[copyIndex()], 'persistenceRdbFrequency'), createObject('value', parameters('databases')[copyIndex()].persistenceRdbFrequency), createObject('value', ''))]", + "port": "[if(contains(parameters('databases')[copyIndex()], 'port'), createObject('value', parameters('databases')[copyIndex()].port), createObject('value', -1))]", + "enableDefaultTelemetry": { + "value": "[variables('enableReferencedModulesTelemetry')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.21.1.54444", + "templateHash": "17740766783826706234" + }, + "name": "Redis Cache Enterprise Databases", + "description": "This module deploys a Redis Cache Enterprise Database.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the database." + } + }, + "redisCacheEnterpriseName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Redis Cache Enterprise Cluster. Required if the template is used in a standalone deployment." + } + }, + "clientProtocol": { + "type": "string", + "defaultValue": "Encrypted", + "allowedValues": [ + "Encrypted", + "Plaintext" + ], + "metadata": { + "description": "Optional. Specifies whether redis clients can connect using TLS-encrypted or plaintext redis protocols. Default is TLS-encrypted." + } + }, + "clusteringPolicy": { + "type": "string", + "defaultValue": "OSSCluster", + "allowedValues": [ + "EnterpriseCluster", + "OSSCluster" + ], + "metadata": { + "description": "Optional. Clustering policy - default is OSSCluster. Specified at create time." + } + }, + "evictionPolicy": { + "type": "string", + "defaultValue": "VolatileLRU", + "allowedValues": [ + "AllKeysLFU", + "AllKeysLRU", + "AllKeysRandom", + "NoEviction", + "VolatileLFU", + "VolatileLRU", + "VolatileRandom", + "VolatileTTL" + ], + "metadata": { + "description": "Optional. Redis eviction policy - default is VolatileLRU." + } + }, + "geoReplication": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Optional set of properties to configure geo replication for this database." + } + }, + "modules": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Optional set of redis modules to enable in this database - modules can only be added at creation time." + } + }, + "persistenceAofEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Conditional. Sets whether AOF is enabled. Required if setting AOF frequency." + } + }, + "persistenceAofFrequency": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "", + "1s", + "always" + ], + "metadata": { + "description": "Optional. Sets the frequency at which data is written to disk. Can be set when AOF is enabled." + } + }, + "persistenceRdbEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Conditional. Sets whether RDB is enabled. Required if setting RDB frequency." + } + }, + "persistenceRdbFrequency": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "", + "12h", + "1h", + "6h" + ], + "metadata": { + "description": "Optional. Sets the frequency at which a snapshot of the database is created. Can be set when RDB is enabled." + } + }, + "port": { + "type": "int", + "defaultValue": -1, + "metadata": { + "description": "Optional. TCP port of the database endpoint. Specified at create time. Default is (-1) meaning value is not set and defaults to an available port." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + } + }, + "resources": [ + { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + { + "type": "Microsoft.Cache/redisEnterprise/databases", + "apiVersion": "2022-01-01", + "name": "[format('{0}/{1}', parameters('redisCacheEnterpriseName'), parameters('name'))]", + "properties": { + "clientProtocol": "[if(not(empty(parameters('clientProtocol'))), parameters('clientProtocol'), null())]", + "clusteringPolicy": "[if(not(empty(parameters('clusteringPolicy'))), parameters('clusteringPolicy'), null())]", + "evictionPolicy": "[if(not(empty(parameters('evictionPolicy'))), parameters('evictionPolicy'), null())]", + "geoReplication": "[if(not(empty(parameters('geoReplication'))), parameters('geoReplication'), null())]", + "modules": "[if(not(empty(parameters('modules'))), parameters('modules'), null())]", + "persistence": { + "aofEnabled": "[parameters('persistenceAofEnabled')]", + "aofFrequency": "[if(not(empty(parameters('persistenceAofFrequency'))), parameters('persistenceAofFrequency'), null())]", + "rdbEnabled": "[parameters('persistenceRdbEnabled')]", + "rdbFrequency": "[if(not(empty(parameters('persistenceRdbFrequency'))), parameters('persistenceRdbFrequency'), null())]" + }, + "port": "[if(not(equals(parameters('port'), -1)), parameters('port'), null())]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed database." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed database." + }, + "value": "[resourceId('Microsoft.Cache/redisEnterprise/databases', parameters('redisCacheEnterpriseName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed database." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Cache/redisEnterprise', parameters('name'))]" + ] + }, { "copy": { "name": "redisCacheEnterprise_privateEndpoints", From 3172bd30d62bbba1aa46e955b0c70a5c1a514142 Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Fri, 15 Sep 2023 16:21:55 +1200 Subject: [PATCH 05/17] updated params --- .../.test/common/main.test.bicep | 26 +------- modules/cache/redis-enterprise/README.md | 62 ++++--------------- .../cache/redis-enterprise/database/README.md | 14 ++--- .../redis-enterprise/database/main.bicep | 11 ++-- .../cache/redis-enterprise/database/main.json | 20 +++--- modules/cache/redis-enterprise/main.bicep | 1 - 6 files changed, 29 insertions(+), 105 deletions(-) diff --git a/modules/cache/redis-enterprise/.test/common/main.test.bicep b/modules/cache/redis-enterprise/.test/common/main.test.bicep index baff5f5514..7dfc5b08b2 100644 --- a/modules/cache/redis-enterprise/.test/common/main.test.bicep +++ b/modules/cache/redis-enterprise/.test/common/main.test.bicep @@ -90,23 +90,8 @@ module testDeployment '../../main.bicep' = { ] databases: [ { - name: '${namePrefix}${serviceShort}-db-01' - } - { - name: '${namePrefix}${serviceShort}-db-02' clusteringPolicy: 'EnterpriseCluster' evictionPolicy: 'AllKeysLFU' - persistenceAofEnabled: true - persistenceAofFrequency: 'always' - persistenceRdbEnabled: true - persistenceRdbFrequency: '12h' - port: 5000 - } - { - name: '${namePrefix}${serviceShort}-db-03' - persistenceAofEnabled: true - persistenceRdbEnabled: true - port: 6000 modules: [ { name: 'RedisBloom' @@ -115,14 +100,9 @@ module testDeployment '../../main.bicep' = { name: 'RedisTimeSeries' } ] - geoReplication: { - groupNickname: '${namePrefix}${serviceShort}-db-03-rep' - linkedDatabases: [ - { - id: '${namePrefix}${serviceShort}-db-01' - } - ] - } + persistenceAofEnabled: true + persistenceAofFrequency: 'always' + port: 10000 } ] tags: { diff --git a/modules/cache/redis-enterprise/README.md b/modules/cache/redis-enterprise/README.md index eb56f87d6e..572d630070 100644 --- a/modules/cache/redis-enterprise/README.md +++ b/modules/cache/redis-enterprise/README.md @@ -14,13 +14,13 @@ This module deploys a Redis Cache Enterprise. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates) | -| `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates) | -| `Microsoft.Cache/redisEnterprise` | [2022-01-01](https://learn.microsoft.com/en-us/azure/templates) | -| `Microsoft.Cache/redisEnterprise/databases` | [2022-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Cache/redisEnterprise) | -| `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates) | -| `Microsoft.Network/privateEndpoints` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates) | -| `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/privateEndpoints) | +| `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | +| `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | +| `Microsoft.Cache/redisEnterprise` | [2022-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Cache/2022-01-01/redisEnterprise) | +| `Microsoft.Cache/redisEnterprise/databases` | [2022-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Cache/2022-01-01/redisEnterprise/databases) | +| `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | +| `Microsoft.Network/privateEndpoints` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints) | +| `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints/privateDnsZoneGroups) | ## Parameters @@ -360,28 +360,9 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { // Non-required parameters capacity: 2 databases: [ - { - name: 'crecom-db-01' - } { clusteringPolicy: 'EnterpriseCluster' evictionPolicy: 'AllKeysLFU' - name: 'crecom-db-02' - persistenceAofEnabled: true - persistenceAofFrequency: 'always' - persistenceRdbEnabled: true - persistenceRdbFrequency: '12h' - port: 5000 - } - { - geoReplication: { - groupNickname: 'crecom-db-03-rep' - linkedDatabases: [ - { - id: 'crecom-db-01' - } - ] - } modules: [ { name: 'RedisBloom' @@ -390,10 +371,9 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { name: 'RedisTimeSeries' } ] - name: 'crecom-db-03' persistenceAofEnabled: true - persistenceRdbEnabled: true - port: 6000 + persistenceAofFrequency: 'always' + port: 10000 } ] diagnosticEventHubAuthorizationRuleId: '' @@ -451,28 +431,9 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { }, "databases": { "value": [ - { - "name": "crecom-db-01" - }, { "clusteringPolicy": "EnterpriseCluster", "evictionPolicy": "AllKeysLFU", - "name": "crecom-db-02", - "persistenceAofEnabled": true, - "persistenceAofFrequency": "always", - "persistenceRdbEnabled": true, - "persistenceRdbFrequency": "12h", - "port": 5000 - }, - { - "geoReplication": { - "groupNickname": "crecom-db-03-rep", - "linkedDatabases": [ - { - "id": "crecom-db-01" - } - ] - }, "modules": [ { "name": "RedisBloom" @@ -481,10 +442,9 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { "name": "RedisTimeSeries" } ], - "name": "crecom-db-03", "persistenceAofEnabled": true, - "persistenceRdbEnabled": true, - "port": 6000 + "persistenceAofFrequency": "always", + "port": 10000 } ] }, diff --git a/modules/cache/redis-enterprise/database/README.md b/modules/cache/redis-enterprise/database/README.md index e4a893a494..05bce7553f 100644 --- a/modules/cache/redis-enterprise/database/README.md +++ b/modules/cache/redis-enterprise/database/README.md @@ -13,22 +13,16 @@ This module deploys a Redis Cache Enterprise Database. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.Cache/redisEnterprise/databases` | [2022-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Cache/redisEnterprise) | +| `Microsoft.Cache/redisEnterprise/databases` | [2022-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Cache/2022-01-01/redisEnterprise/databases) | ## Parameters -**Required parameters** - -| Parameter Name | Type | Description | -| :-- | :-- | :-- | -| `name` | string | The name of the database. | - **Conditional parameters** | Parameter Name | Type | Default Value | Description | | :-- | :-- | :-- | :-- | -| `persistenceAofEnabled` | bool | `False` | Sets whether AOF is enabled. Required if setting AOF frequency. | -| `persistenceRdbEnabled` | bool | `False` | Sets whether RDB is enabled. Required if setting RDB frequency. | +| `persistenceAofEnabled` | bool | `False` | Sets whether AOF is enabled. Required if setting AOF frequency. AOF and RDB cannot be enabled at the same time. | +| `persistenceRdbEnabled` | bool | `False` | Sets whether RDB is enabled. Required if setting RDB frequency. AOF and RDB cannot be enabled at the same time. | | `redisCacheEnterpriseName` | string | | The name of the parent Redis Cache Enterprise Cluster. Required if the template is used in a standalone deployment. | **Optional parameters** @@ -44,7 +38,7 @@ This module deploys a Redis Cache Enterprise Database. | `modules` | array | `[]` | | Optional set of redis modules to enable in this database - modules can only be added at creation time. | | `persistenceAofFrequency` | string | `''` | `['', 1s, always]` | Sets the frequency at which data is written to disk. Can be set when AOF is enabled. | | `persistenceRdbFrequency` | string | `''` | `['', 12h, 1h, 6h]` | Sets the frequency at which a snapshot of the database is created. Can be set when RDB is enabled. | -| `port` | int | `-1` | | TCP port of the database endpoint. Specified at create time. Default is (-1) meaning value is not set and defaults to an available port. | +| `port` | int | `-1` | | TCP port of the database endpoint. Specified at create time. Default is (-1) meaning value is not set and defaults to an available port. Current supported port is 10000. | ## Outputs diff --git a/modules/cache/redis-enterprise/database/main.bicep b/modules/cache/redis-enterprise/database/main.bicep index 66ec1d245f..09ffe4e899 100644 --- a/modules/cache/redis-enterprise/database/main.bicep +++ b/modules/cache/redis-enterprise/database/main.bicep @@ -2,9 +2,6 @@ metadata name = 'Redis Cache Enterprise Databases' metadata description = 'This module deploys a Redis Cache Enterprise Database.' metadata owner = 'Azure/module-maintainers' -@description('Required. The name of the database.') -param name string - @description('Conditional. The name of the parent Redis Cache Enterprise Cluster. Required if the template is used in a standalone deployment.') param redisCacheEnterpriseName string @@ -41,7 +38,7 @@ param geoReplication object = {} @description('Optional. Optional set of redis modules to enable in this database - modules can only be added at creation time.') param modules array = [] -@description('Conditional. Sets whether AOF is enabled. Required if setting AOF frequency.') +@description('Conditional. Sets whether AOF is enabled. Required if setting AOF frequency. AOF and RDB cannot be enabled at the same time.') param persistenceAofEnabled bool = false @allowed([ @@ -52,7 +49,7 @@ param persistenceAofEnabled bool = false @description('Optional. Sets the frequency at which data is written to disk. Can be set when AOF is enabled.') param persistenceAofFrequency string = '' -@description('Conditional. Sets whether RDB is enabled. Required if setting RDB frequency.') +@description('Conditional. Sets whether RDB is enabled. Required if setting RDB frequency. AOF and RDB cannot be enabled at the same time.') param persistenceRdbEnabled bool = false @allowed([ @@ -64,7 +61,7 @@ param persistenceRdbEnabled bool = false @description('Optional. Sets the frequency at which a snapshot of the database is created. Can be set when RDB is enabled.') param persistenceRdbFrequency string = '' -@description('Optional. TCP port of the database endpoint. Specified at create time. Default is (-1) meaning value is not set and defaults to an available port.') +@description('Optional. TCP port of the database endpoint. Specified at create time. Default is (-1) meaning value is not set and defaults to an available port. Current supported port is 10000.') param port int = -1 @description('Optional. Location for all resources.') @@ -90,7 +87,7 @@ resource redisCacheEnterprise 'Microsoft.Cache/redisEnterprise@2022-01-01' exist } resource database 'Microsoft.Cache/redisEnterprise/databases@2022-01-01' = { - name: name + name: 'default' parent: redisCacheEnterprise properties: { clientProtocol: !empty(clientProtocol) ? clientProtocol : null diff --git a/modules/cache/redis-enterprise/database/main.json b/modules/cache/redis-enterprise/database/main.json index 699725f9f3..dda5561a0b 100644 --- a/modules/cache/redis-enterprise/database/main.json +++ b/modules/cache/redis-enterprise/database/main.json @@ -5,19 +5,13 @@ "_generator": { "name": "bicep", "version": "0.21.1.54444", - "templateHash": "17740766783826706234" + "templateHash": "6399828648151211255" }, "name": "Redis Cache Enterprise Databases", "description": "This module deploys a Redis Cache Enterprise Database.", "owner": "Azure/module-maintainers" }, "parameters": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the database." - } - }, "redisCacheEnterpriseName": { "type": "string", "metadata": { @@ -81,7 +75,7 @@ "type": "bool", "defaultValue": false, "metadata": { - "description": "Conditional. Sets whether AOF is enabled. Required if setting AOF frequency." + "description": "Conditional. Sets whether AOF is enabled. Required if setting AOF frequency. AOF and RDB cannot be enabled at the same time." } }, "persistenceAofFrequency": { @@ -100,7 +94,7 @@ "type": "bool", "defaultValue": false, "metadata": { - "description": "Conditional. Sets whether RDB is enabled. Required if setting RDB frequency." + "description": "Conditional. Sets whether RDB is enabled. Required if setting RDB frequency. AOF and RDB cannot be enabled at the same time." } }, "persistenceRdbFrequency": { @@ -120,7 +114,7 @@ "type": "int", "defaultValue": -1, "metadata": { - "description": "Optional. TCP port of the database endpoint. Specified at create time. Default is (-1) meaning value is not set and defaults to an available port." + "description": "Optional. TCP port of the database endpoint. Specified at create time. Default is (-1) meaning value is not set and defaults to an available port. Current supported port is 10000." } }, "location": { @@ -156,7 +150,7 @@ { "type": "Microsoft.Cache/redisEnterprise/databases", "apiVersion": "2022-01-01", - "name": "[format('{0}/{1}', parameters('redisCacheEnterpriseName'), parameters('name'))]", + "name": "[format('{0}/{1}', parameters('redisCacheEnterpriseName'), 'default')]", "properties": { "clientProtocol": "[if(not(empty(parameters('clientProtocol'))), parameters('clientProtocol'), null())]", "clusteringPolicy": "[if(not(empty(parameters('clusteringPolicy'))), parameters('clusteringPolicy'), null())]", @@ -179,14 +173,14 @@ "metadata": { "description": "The name of the deployed database." }, - "value": "[parameters('name')]" + "value": "default" }, "resourceId": { "type": "string", "metadata": { "description": "The resource ID of the deployed database." }, - "value": "[resourceId('Microsoft.Cache/redisEnterprise/databases', parameters('redisCacheEnterpriseName'), parameters('name'))]" + "value": "[resourceId('Microsoft.Cache/redisEnterprise/databases', parameters('redisCacheEnterpriseName'), 'default')]" }, "resourceGroupName": { "type": "string", diff --git a/modules/cache/redis-enterprise/main.bicep b/modules/cache/redis-enterprise/main.bicep index 130716e8f9..a5cb8a3c3c 100644 --- a/modules/cache/redis-enterprise/main.bicep +++ b/modules/cache/redis-enterprise/main.bicep @@ -177,7 +177,6 @@ module redisCacheEnterprise_rbac '.bicep/nested_roleAssignments.bicep' = [for (r module redisCacheEnterprise_databases 'database/main.bicep' = [for (database, index) in databases: { name: '${uniqueString(deployment().name, location)}-redisCacheEnterprise-DB-${index}' params: { - name: database.name redisCacheEnterpriseName: redisCacheEnterprise.name location: location clientProtocol: contains(database, 'clientProtocol') ? database.clientProtocol : 'Encrypted' From 4094bc33481588aae259203d62929a30ca7149a3 Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Fri, 15 Sep 2023 16:58:10 +1200 Subject: [PATCH 06/17] added geo replication support --- .../.test/common/main.test.bicep | 2 +- .../.test/geo/dependencies.bicep | 41 +++++++ .../.test/geo/main.test.bicep | 81 ++++++++++++ modules/cache/redis-enterprise/README.md | 115 +++++++++++++++++- .../cache/redis-enterprise/database/README.md | 6 +- .../redis-enterprise/database/main.bicep | 6 +- .../cache/redis-enterprise/database/main.json | 8 +- modules/cache/redis-enterprise/main.json | 27 ++-- 8 files changed, 254 insertions(+), 32 deletions(-) create mode 100644 modules/cache/redis-enterprise/.test/geo/dependencies.bicep create mode 100644 modules/cache/redis-enterprise/.test/geo/main.test.bicep diff --git a/modules/cache/redis-enterprise/.test/common/main.test.bicep b/modules/cache/redis-enterprise/.test/common/main.test.bicep index 7dfc5b08b2..f41716b90f 100644 --- a/modules/cache/redis-enterprise/.test/common/main.test.bicep +++ b/modules/cache/redis-enterprise/.test/common/main.test.bicep @@ -107,7 +107,7 @@ module testDeployment '../../main.bicep' = { ] tags: { 'hidden-title': 'This is visible in the resource name' - resourceType: 'Redis Cache' + resourceType: 'Redis Cache Enterprise' } } } diff --git a/modules/cache/redis-enterprise/.test/geo/dependencies.bicep b/modules/cache/redis-enterprise/.test/geo/dependencies.bicep new file mode 100644 index 0000000000..b83ead44e5 --- /dev/null +++ b/modules/cache/redis-enterprise/.test/geo/dependencies.bicep @@ -0,0 +1,41 @@ +@description('Optional. The location to deploy resources to.') +param location string = resourceGroup().location + +@description('Required. The name of the Redis Cache Enterprise to create.') +param redisCacheEnterpriseName string + +resource redisCacheEnterprise 'Microsoft.Cache/redisEnterprise@2022-01-01' = { + name: redisCacheEnterpriseName + location: location + sku: { + name: 'Enterprise_E10' + capacity: 2 + } + properties: { + minimumTlsVersion: '1.2' + } + zones: [ + '1' + '2' + '3' + ] + + resource database 'databases@2022-01-01' = { + name: 'default' + properties: { + clusteringPolicy: 'EnterpriseCluster' + evictionPolicy: 'AllKeysLFU' + modules: [ + { + name: 'RediSearch' + } + { + name: 'RedisJSON' + } + ] + } + } +} + +@description('The resource ID of the created Redis Cache Enterprise database.') +output redisCacheEnterpriseDatabaseResourceId string = redisCacheEnterprise::database.id diff --git a/modules/cache/redis-enterprise/.test/geo/main.test.bicep b/modules/cache/redis-enterprise/.test/geo/main.test.bicep new file mode 100644 index 0000000000..dba097ec0c --- /dev/null +++ b/modules/cache/redis-enterprise/.test/geo/main.test.bicep @@ -0,0 +1,81 @@ +targetScope = 'subscription' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'ms.cache.redisenterprise-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param location 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 = 'cregeo' + +@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +param enableDefaultTelemetry bool = true + +@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: location +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-nestedDependencies' + params: { + redisCacheEnterpriseName: 'dep-${namePrefix}-rce-${serviceShort}' + } +} + +// ============== // +// Test Execution // +// ============== // + +module testDeployment '../../main.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}' + params: { + enableDefaultTelemetry: enableDefaultTelemetry + name: '${namePrefix}${serviceShort}001' + capacity: 2 + zoneRedundant: true + databases: [ + { + clusteringPolicy: 'EnterpriseCluster' + evictionPolicy: 'AllKeysLFU' + modules: [ + { + name: 'RediSearch' + } + { + name: 'RedisJSON' + } + ] + geoReplication: { + groupNickname: '${namePrefix}${serviceShort}-geo-grp' + linkedDatabases: [ + { + id: nestedDependencies.outputs.redisCacheEnterpriseDatabaseResourceId + } + ] + } + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + resourceType: 'Redis Cache Enterprise' + } + } +} diff --git a/modules/cache/redis-enterprise/README.md b/modules/cache/redis-enterprise/README.md index 572d630070..cead73c609 100644 --- a/modules/cache/redis-enterprise/README.md +++ b/modules/cache/redis-enterprise/README.md @@ -402,7 +402,7 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { ] tags: { 'hidden-title': 'This is visible in the resource name' - resourceType: 'Redis Cache' + resourceType: 'Redis Cache Enterprise' } zoneRedundant: true } @@ -493,7 +493,7 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { "tags": { "value": { "hidden-title": "This is visible in the resource name", - "resourceType": "Redis Cache" + "resourceType": "Redis Cache Enterprise" } }, "zoneRedundant": { @@ -506,7 +506,116 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = {

-

Example 2: Min

+

Example 2: Geo

+ +
+ +via Bicep module + +```bicep +module redisEnterprise './cache/redis-enterprise/main.bicep' = { + name: '${uniqueString(deployment().name, location)}-test-cregeo' + params: { + // Required parameters + name: 'cregeo001' + // Non-required parameters + capacity: 2 + databases: [ + { + clusteringPolicy: 'EnterpriseCluster' + evictionPolicy: 'AllKeysLFU' + geoReplication: { + groupNickname: 'cregeo-geo-grp' + linkedDatabases: [ + { + id: '' + } + ] + } + modules: [ + { + name: 'RediSearch' + } + { + name: 'RedisJSON' + } + ] + } + ] + enableDefaultTelemetry: '' + tags: { + 'hidden-title': 'This is visible in the resource name' + resourceType: 'Redis Cache Enterprise' + } + zoneRedundant: true + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "cregeo001" + }, + // Non-required parameters + "capacity": { + "value": 2 + }, + "databases": { + "value": [ + { + "clusteringPolicy": "EnterpriseCluster", + "evictionPolicy": "AllKeysLFU", + "geoReplication": { + "groupNickname": "cregeo-geo-grp", + "linkedDatabases": [ + { + "id": "" + } + ] + }, + "modules": [ + { + "name": "RediSearch" + }, + { + "name": "RedisJSON" + } + ] + } + ] + }, + "enableDefaultTelemetry": { + "value": "" + }, + "tags": { + "value": { + "hidden-title": "This is visible in the resource name", + "resourceType": "Redis Cache Enterprise" + } + }, + "zoneRedundant": { + "value": true + } + } +} +``` + +
+

+ +

Example 3: Min

diff --git a/modules/cache/redis-enterprise/database/README.md b/modules/cache/redis-enterprise/database/README.md index 05bce7553f..49ec8db98a 100644 --- a/modules/cache/redis-enterprise/database/README.md +++ b/modules/cache/redis-enterprise/database/README.md @@ -21,8 +21,8 @@ This module deploys a Redis Cache Enterprise Database. | Parameter Name | Type | Default Value | Description | | :-- | :-- | :-- | :-- | -| `persistenceAofEnabled` | bool | `False` | Sets whether AOF is enabled. Required if setting AOF frequency. AOF and RDB cannot be enabled at the same time. | -| `persistenceRdbEnabled` | bool | `False` | Sets whether RDB is enabled. Required if setting RDB frequency. AOF and RDB cannot be enabled at the same time. | +| `persistenceAofEnabled` | bool | `False` | Sets whether AOF is enabled. Required if setting AOF frequency. AOF and RDB persistence cannot be enabled at the same time. | +| `persistenceRdbEnabled` | bool | `False` | Sets whether RDB is enabled. Required if setting RDB frequency. RDB and AOF persistence cannot be enabled at the same time. | | `redisCacheEnterpriseName` | string | | The name of the parent Redis Cache Enterprise Cluster. Required if the template is used in a standalone deployment. | **Optional parameters** @@ -33,7 +33,7 @@ This module deploys a Redis Cache Enterprise Database. | `clusteringPolicy` | string | `'OSSCluster'` | `[EnterpriseCluster, OSSCluster]` | Clustering policy - default is OSSCluster. Specified at create time. | | `enableDefaultTelemetry` | bool | `True` | | Enable telemetry via a Globally Unique Identifier (GUID). | | `evictionPolicy` | string | `'VolatileLRU'` | `[AllKeysLFU, AllKeysLRU, AllKeysRandom, NoEviction, VolatileLFU, VolatileLRU, VolatileRandom, VolatileTTL]` | Redis eviction policy - default is VolatileLRU. | -| `geoReplication` | object | `{object}` | | Optional set of properties to configure geo replication for this database. | +| `geoReplication` | object | `{object}` | | Optional set of properties to configure geo replication for this database. Geo replication prerequisites must be met. See "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-how-to-active-geo-replication#active-geo-replication-prerequisites" for more information. | | `location` | string | `[resourceGroup().location]` | | Location for all resources. | | `modules` | array | `[]` | | Optional set of redis modules to enable in this database - modules can only be added at creation time. | | `persistenceAofFrequency` | string | `''` | `['', 1s, always]` | Sets the frequency at which data is written to disk. Can be set when AOF is enabled. | diff --git a/modules/cache/redis-enterprise/database/main.bicep b/modules/cache/redis-enterprise/database/main.bicep index 09ffe4e899..88c0d93454 100644 --- a/modules/cache/redis-enterprise/database/main.bicep +++ b/modules/cache/redis-enterprise/database/main.bicep @@ -32,13 +32,13 @@ param clusteringPolicy string = 'OSSCluster' @description('Optional. Redis eviction policy - default is VolatileLRU.') param evictionPolicy string = 'VolatileLRU' -@description('Optional. Optional set of properties to configure geo replication for this database.') +@description('Optional. Optional set of properties to configure geo replication for this database. Geo replication prerequisites must be met. See "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-how-to-active-geo-replication#active-geo-replication-prerequisites" for more information.') param geoReplication object = {} @description('Optional. Optional set of redis modules to enable in this database - modules can only be added at creation time.') param modules array = [] -@description('Conditional. Sets whether AOF is enabled. Required if setting AOF frequency. AOF and RDB cannot be enabled at the same time.') +@description('Conditional. Sets whether AOF is enabled. Required if setting AOF frequency. AOF and RDB persistence cannot be enabled at the same time.') param persistenceAofEnabled bool = false @allowed([ @@ -49,7 +49,7 @@ param persistenceAofEnabled bool = false @description('Optional. Sets the frequency at which data is written to disk. Can be set when AOF is enabled.') param persistenceAofFrequency string = '' -@description('Conditional. Sets whether RDB is enabled. Required if setting RDB frequency. AOF and RDB cannot be enabled at the same time.') +@description('Conditional. Sets whether RDB is enabled. Required if setting RDB frequency. RDB and AOF persistence cannot be enabled at the same time.') param persistenceRdbEnabled bool = false @allowed([ diff --git a/modules/cache/redis-enterprise/database/main.json b/modules/cache/redis-enterprise/database/main.json index dda5561a0b..7fbc855d17 100644 --- a/modules/cache/redis-enterprise/database/main.json +++ b/modules/cache/redis-enterprise/database/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.21.1.54444", - "templateHash": "6399828648151211255" + "templateHash": "14063731469491395921" }, "name": "Redis Cache Enterprise Databases", "description": "This module deploys a Redis Cache Enterprise Database.", @@ -61,7 +61,7 @@ "type": "object", "defaultValue": {}, "metadata": { - "description": "Optional. Optional set of properties to configure geo replication for this database." + "description": "Optional. Optional set of properties to configure geo replication for this database. Geo replication prerequisites must be met. See \"https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-how-to-active-geo-replication#active-geo-replication-prerequisites\" for more information." } }, "modules": { @@ -75,7 +75,7 @@ "type": "bool", "defaultValue": false, "metadata": { - "description": "Conditional. Sets whether AOF is enabled. Required if setting AOF frequency. AOF and RDB cannot be enabled at the same time." + "description": "Conditional. Sets whether AOF is enabled. Required if setting AOF frequency. AOF and RDB persistence cannot be enabled at the same time." } }, "persistenceAofFrequency": { @@ -94,7 +94,7 @@ "type": "bool", "defaultValue": false, "metadata": { - "description": "Conditional. Sets whether RDB is enabled. Required if setting RDB frequency. AOF and RDB cannot be enabled at the same time." + "description": "Conditional. Sets whether RDB is enabled. Required if setting RDB frequency. RDB and AOF persistence cannot be enabled at the same time." } }, "persistenceRdbFrequency": { diff --git a/modules/cache/redis-enterprise/main.json b/modules/cache/redis-enterprise/main.json index 4ca01a8717..f6bc944dbf 100644 --- a/modules/cache/redis-enterprise/main.json +++ b/modules/cache/redis-enterprise/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.21.1.54444", - "templateHash": "11003351351537958776" + "templateHash": "2370045353021199422" }, "name": "Redis Cache Enterprise", "description": "This module deploys a Redis Cache Enterprise.", @@ -426,9 +426,6 @@ }, "mode": "Incremental", "parameters": { - "name": { - "value": "[parameters('databases')[copyIndex()].name]" - }, "redisCacheEnterpriseName": { "value": "[parameters('name')]" }, @@ -456,19 +453,13 @@ "_generator": { "name": "bicep", "version": "0.21.1.54444", - "templateHash": "17740766783826706234" + "templateHash": "14063731469491395921" }, "name": "Redis Cache Enterprise Databases", "description": "This module deploys a Redis Cache Enterprise Database.", "owner": "Azure/module-maintainers" }, "parameters": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the database." - } - }, "redisCacheEnterpriseName": { "type": "string", "metadata": { @@ -518,7 +509,7 @@ "type": "object", "defaultValue": {}, "metadata": { - "description": "Optional. Optional set of properties to configure geo replication for this database." + "description": "Optional. Optional set of properties to configure geo replication for this database. Geo replication prerequisites must be met. See \"https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-how-to-active-geo-replication#active-geo-replication-prerequisites\" for more information." } }, "modules": { @@ -532,7 +523,7 @@ "type": "bool", "defaultValue": false, "metadata": { - "description": "Conditional. Sets whether AOF is enabled. Required if setting AOF frequency." + "description": "Conditional. Sets whether AOF is enabled. Required if setting AOF frequency. AOF and RDB persistence cannot be enabled at the same time." } }, "persistenceAofFrequency": { @@ -551,7 +542,7 @@ "type": "bool", "defaultValue": false, "metadata": { - "description": "Conditional. Sets whether RDB is enabled. Required if setting RDB frequency." + "description": "Conditional. Sets whether RDB is enabled. Required if setting RDB frequency. RDB and AOF persistence cannot be enabled at the same time." } }, "persistenceRdbFrequency": { @@ -571,7 +562,7 @@ "type": "int", "defaultValue": -1, "metadata": { - "description": "Optional. TCP port of the database endpoint. Specified at create time. Default is (-1) meaning value is not set and defaults to an available port." + "description": "Optional. TCP port of the database endpoint. Specified at create time. Default is (-1) meaning value is not set and defaults to an available port. Current supported port is 10000." } }, "location": { @@ -607,7 +598,7 @@ { "type": "Microsoft.Cache/redisEnterprise/databases", "apiVersion": "2022-01-01", - "name": "[format('{0}/{1}', parameters('redisCacheEnterpriseName'), parameters('name'))]", + "name": "[format('{0}/{1}', parameters('redisCacheEnterpriseName'), 'default')]", "properties": { "clientProtocol": "[if(not(empty(parameters('clientProtocol'))), parameters('clientProtocol'), null())]", "clusteringPolicy": "[if(not(empty(parameters('clusteringPolicy'))), parameters('clusteringPolicy'), null())]", @@ -630,14 +621,14 @@ "metadata": { "description": "The name of the deployed database." }, - "value": "[parameters('name')]" + "value": "default" }, "resourceId": { "type": "string", "metadata": { "description": "The resource ID of the deployed database." }, - "value": "[resourceId('Microsoft.Cache/redisEnterprise/databases', parameters('redisCacheEnterpriseName'), parameters('name'))]" + "value": "[resourceId('Microsoft.Cache/redisEnterprise/databases', parameters('redisCacheEnterpriseName'), 'default')]" }, "resourceGroupName": { "type": "string", From 331973cbe2d3840b66c9aeca66ebc5972d0feebb Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Sat, 16 Sep 2023 07:42:01 +1000 Subject: [PATCH 07/17] Updated geo --- modules/cache/redis-enterprise/.test/geo/dependencies.bicep | 2 +- modules/cache/redis-enterprise/.test/geo/main.test.bicep | 2 +- modules/cache/redis-enterprise/README.md | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/cache/redis-enterprise/.test/geo/dependencies.bicep b/modules/cache/redis-enterprise/.test/geo/dependencies.bicep index b83ead44e5..392ddefced 100644 --- a/modules/cache/redis-enterprise/.test/geo/dependencies.bicep +++ b/modules/cache/redis-enterprise/.test/geo/dependencies.bicep @@ -24,7 +24,7 @@ resource redisCacheEnterprise 'Microsoft.Cache/redisEnterprise@2022-01-01' = { name: 'default' properties: { clusteringPolicy: 'EnterpriseCluster' - evictionPolicy: 'AllKeysLFU' + evictionPolicy: 'NoEviction' modules: [ { name: 'RediSearch' diff --git a/modules/cache/redis-enterprise/.test/geo/main.test.bicep b/modules/cache/redis-enterprise/.test/geo/main.test.bicep index dba097ec0c..20adf94132 100644 --- a/modules/cache/redis-enterprise/.test/geo/main.test.bicep +++ b/modules/cache/redis-enterprise/.test/geo/main.test.bicep @@ -54,7 +54,7 @@ module testDeployment '../../main.bicep' = { databases: [ { clusteringPolicy: 'EnterpriseCluster' - evictionPolicy: 'AllKeysLFU' + evictionPolicy: 'NoEviction' modules: [ { name: 'RediSearch' diff --git a/modules/cache/redis-enterprise/README.md b/modules/cache/redis-enterprise/README.md index cead73c609..ea500e0af3 100644 --- a/modules/cache/redis-enterprise/README.md +++ b/modules/cache/redis-enterprise/README.md @@ -523,7 +523,7 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { databases: [ { clusteringPolicy: 'EnterpriseCluster' - evictionPolicy: 'AllKeysLFU' + evictionPolicy: 'NoEviction' geoReplication: { groupNickname: 'cregeo-geo-grp' linkedDatabases: [ @@ -576,7 +576,7 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { "value": [ { "clusteringPolicy": "EnterpriseCluster", - "evictionPolicy": "AllKeysLFU", + "evictionPolicy": "NoEviction", "geoReplication": { "groupNickname": "cregeo-geo-grp", "linkedDatabases": [ From 8a7b2c2afd577866b27b5b2ff91378cab31a2dcb Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Sat, 16 Sep 2023 12:23:41 +1000 Subject: [PATCH 08/17] updated tests --- .../.test/common/main.test.bicep | 2 +- .../.test/geo/dependencies.bicep | 22 ++++++++++++++-- .../.test/geo/main.test.bicep | 13 ++++++++-- modules/cache/redis-enterprise/README.md | 26 ++++++++++++++----- .../cache/redis-enterprise/database/README.md | 14 +++++----- .../redis-enterprise/database/main.bicep | 8 +++--- 6 files changed, 62 insertions(+), 23 deletions(-) diff --git a/modules/cache/redis-enterprise/.test/common/main.test.bicep b/modules/cache/redis-enterprise/.test/common/main.test.bicep index f41716b90f..09cb3be37f 100644 --- a/modules/cache/redis-enterprise/.test/common/main.test.bicep +++ b/modules/cache/redis-enterprise/.test/common/main.test.bicep @@ -101,7 +101,7 @@ module testDeployment '../../main.bicep' = { } ] persistenceAofEnabled: true - persistenceAofFrequency: 'always' + persistenceAofFrequency: '1s' port: 10000 } ] diff --git a/modules/cache/redis-enterprise/.test/geo/dependencies.bicep b/modules/cache/redis-enterprise/.test/geo/dependencies.bicep index 392ddefced..31cbbe50bf 100644 --- a/modules/cache/redis-enterprise/.test/geo/dependencies.bicep +++ b/modules/cache/redis-enterprise/.test/geo/dependencies.bicep @@ -4,6 +4,8 @@ param location string = resourceGroup().location @description('Required. The name of the Redis Cache Enterprise to create.') param redisCacheEnterpriseName string +var redisCacheEnterpriseExpectedResourceID = '${resourceGroup().id}/providers/Microsoft.Cache/redisEnterprise/${redisCacheEnterpriseName}' + resource redisCacheEnterprise 'Microsoft.Cache/redisEnterprise@2022-01-01' = { name: redisCacheEnterpriseName location: location @@ -25,17 +27,33 @@ resource redisCacheEnterprise 'Microsoft.Cache/redisEnterprise@2022-01-01' = { properties: { clusteringPolicy: 'EnterpriseCluster' evictionPolicy: 'NoEviction' + persistence: { + aofEnabled: false + rdbEnabled: false + } modules: [ { - name: 'RediSearch' + name: 'RedisJSON' } { - name: 'RedisJSON' + name: 'RediSearch' } ] + geoReplication: { + groupNickname: '${redisCacheEnterpriseName}-geo-group' + linkedDatabases: [ + { + id: '${redisCacheEnterpriseExpectedResourceID}/databases/default' + } + ] + } + port: 10000 } } } @description('The resource ID of the created Redis Cache Enterprise database.') output redisCacheEnterpriseDatabaseResourceId string = redisCacheEnterprise::database.id + +@description('The geo replication group nickname of the created Redis Cache Enterprise database.') +output redisCacheEnterpriseDatabaseGeoReplicationGroupNickname string = redisCacheEnterprise::database.properties.geoReplication.groupNickname diff --git a/modules/cache/redis-enterprise/.test/geo/main.test.bicep b/modules/cache/redis-enterprise/.test/geo/main.test.bicep index 20adf94132..492bd50848 100644 --- a/modules/cache/redis-enterprise/.test/geo/main.test.bicep +++ b/modules/cache/redis-enterprise/.test/geo/main.test.bicep @@ -43,18 +43,22 @@ module nestedDependencies 'dependencies.bicep' = { // Test Execution // // ============== // +var redisCacheEnterpriseName = '${namePrefix}${serviceShort}001' +var redisCacheEnterpriseExpectedResourceID = '${resourceGroup.id}/providers/Microsoft.Cache/redisEnterprise/${redisCacheEnterpriseName}' + module testDeployment '../../main.bicep' = { scope: resourceGroup name: '${uniqueString(deployment().name, location)}-test-${serviceShort}' params: { enableDefaultTelemetry: enableDefaultTelemetry - name: '${namePrefix}${serviceShort}001' + name: redisCacheEnterpriseName capacity: 2 zoneRedundant: true databases: [ { clusteringPolicy: 'EnterpriseCluster' evictionPolicy: 'NoEviction' + port: 10000 modules: [ { name: 'RediSearch' @@ -64,13 +68,18 @@ module testDeployment '../../main.bicep' = { } ] geoReplication: { - groupNickname: '${namePrefix}${serviceShort}-geo-grp' + groupNickname: nestedDependencies.outputs.redisCacheEnterpriseDatabaseGeoReplicationGroupNickname linkedDatabases: [ { id: nestedDependencies.outputs.redisCacheEnterpriseDatabaseResourceId } + { + id: '${redisCacheEnterpriseExpectedResourceID}/databases/default' + } ] } + persistenceAofEnabled: false + persistenceRdbEnabled: false } ] tags: { diff --git a/modules/cache/redis-enterprise/README.md b/modules/cache/redis-enterprise/README.md index ea500e0af3..576d2d733e 100644 --- a/modules/cache/redis-enterprise/README.md +++ b/modules/cache/redis-enterprise/README.md @@ -372,7 +372,7 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { } ] persistenceAofEnabled: true - persistenceAofFrequency: 'always' + persistenceAofFrequency: '1s' port: 10000 } ] @@ -443,7 +443,7 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { } ], "persistenceAofEnabled": true, - "persistenceAofFrequency": "always", + "persistenceAofFrequency": "1s", "port": 10000 } ] @@ -517,7 +517,7 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { name: '${uniqueString(deployment().name, location)}-test-cregeo' params: { // Required parameters - name: 'cregeo001' + name: '' // Non-required parameters capacity: 2 databases: [ @@ -525,11 +525,14 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { clusteringPolicy: 'EnterpriseCluster' evictionPolicy: 'NoEviction' geoReplication: { - groupNickname: 'cregeo-geo-grp' + groupNickname: '' linkedDatabases: [ { id: '' } + { + id: '' + } ] } modules: [ @@ -540,6 +543,9 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { name: 'RedisJSON' } ] + persistenceAofEnabled: false + persistenceRdbEnabled: false + port: 10000 } ] enableDefaultTelemetry: '' @@ -566,7 +572,7 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { "parameters": { // Required parameters "name": { - "value": "cregeo001" + "value": "" }, // Non-required parameters "capacity": { @@ -578,8 +584,11 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { "clusteringPolicy": "EnterpriseCluster", "evictionPolicy": "NoEviction", "geoReplication": { - "groupNickname": "cregeo-geo-grp", + "groupNickname": "", "linkedDatabases": [ + { + "id": "" + }, { "id": "" } @@ -592,7 +601,10 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { { "name": "RedisJSON" } - ] + ], + "persistenceAofEnabled": false, + "persistenceRdbEnabled": false, + "port": 10000 } ] }, diff --git a/modules/cache/redis-enterprise/database/README.md b/modules/cache/redis-enterprise/database/README.md index 49ec8db98a..ff2cbefeee 100644 --- a/modules/cache/redis-enterprise/database/README.md +++ b/modules/cache/redis-enterprise/database/README.md @@ -19,11 +19,11 @@ This module deploys a Redis Cache Enterprise Database. **Conditional parameters** -| Parameter Name | Type | Default Value | Description | -| :-- | :-- | :-- | :-- | -| `persistenceAofEnabled` | bool | `False` | Sets whether AOF is enabled. Required if setting AOF frequency. AOF and RDB persistence cannot be enabled at the same time. | -| `persistenceRdbEnabled` | bool | `False` | Sets whether RDB is enabled. Required if setting RDB frequency. RDB and AOF persistence cannot be enabled at the same time. | -| `redisCacheEnterpriseName` | string | | The name of the parent Redis Cache Enterprise Cluster. Required if the template is used in a standalone deployment. | +| Parameter Name | Type | Default Value | Allowed Values | Description | +| :-- | :-- | :-- | :-- | :-- | +| `persistenceAofFrequency` | string | `''` | `['', 1s, always]` | Sets the frequency at which data is written to disk. Required if AOF persistence is enabled. | +| `persistenceRdbFrequency` | string | `''` | `['', 12h, 1h, 6h]` | Sets the frequency at which a snapshot of the database is created. Required if RDB persistence is enabled. | +| `redisCacheEnterpriseName` | string | | | The name of the parent Redis Cache Enterprise Cluster. Required if the template is used in a standalone deployment. | **Optional parameters** @@ -36,8 +36,8 @@ This module deploys a Redis Cache Enterprise Database. | `geoReplication` | object | `{object}` | | Optional set of properties to configure geo replication for this database. Geo replication prerequisites must be met. See "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-how-to-active-geo-replication#active-geo-replication-prerequisites" for more information. | | `location` | string | `[resourceGroup().location]` | | Location for all resources. | | `modules` | array | `[]` | | Optional set of redis modules to enable in this database - modules can only be added at creation time. | -| `persistenceAofFrequency` | string | `''` | `['', 1s, always]` | Sets the frequency at which data is written to disk. Can be set when AOF is enabled. | -| `persistenceRdbFrequency` | string | `''` | `['', 12h, 1h, 6h]` | Sets the frequency at which a snapshot of the database is created. Can be set when RDB is enabled. | +| `persistenceAofEnabled` | bool | `False` | | Sets whether AOF is enabled. Required if setting AOF frequency. AOF and RDB persistence cannot be enabled at the same time. | +| `persistenceRdbEnabled` | bool | `False` | | Sets whether RDB is enabled. RDB and AOF persistence cannot be enabled at the same time | | `port` | int | `-1` | | TCP port of the database endpoint. Specified at create time. Default is (-1) meaning value is not set and defaults to an available port. Current supported port is 10000. | diff --git a/modules/cache/redis-enterprise/database/main.bicep b/modules/cache/redis-enterprise/database/main.bicep index 88c0d93454..55497a1d78 100644 --- a/modules/cache/redis-enterprise/database/main.bicep +++ b/modules/cache/redis-enterprise/database/main.bicep @@ -38,7 +38,7 @@ param geoReplication object = {} @description('Optional. Optional set of redis modules to enable in this database - modules can only be added at creation time.') param modules array = [] -@description('Conditional. Sets whether AOF is enabled. Required if setting AOF frequency. AOF and RDB persistence cannot be enabled at the same time.') +@description('Optional. Sets whether AOF is enabled. Required if setting AOF frequency. AOF and RDB persistence cannot be enabled at the same time.') param persistenceAofEnabled bool = false @allowed([ @@ -46,10 +46,10 @@ param persistenceAofEnabled bool = false '1s' 'always' ]) -@description('Optional. Sets the frequency at which data is written to disk. Can be set when AOF is enabled.') +@description('Conditional. Sets the frequency at which data is written to disk. Required if AOF persistence is enabled.') param persistenceAofFrequency string = '' -@description('Conditional. Sets whether RDB is enabled. Required if setting RDB frequency. RDB and AOF persistence cannot be enabled at the same time.') +@description('Optional. Sets whether RDB is enabled. RDB and AOF persistence cannot be enabled at the same time') param persistenceRdbEnabled bool = false @allowed([ @@ -58,7 +58,7 @@ param persistenceRdbEnabled bool = false '1h' '6h' ]) -@description('Optional. Sets the frequency at which a snapshot of the database is created. Can be set when RDB is enabled.') +@description('Conditional. Sets the frequency at which a snapshot of the database is created. Required if RDB persistence is enabled.') param persistenceRdbFrequency string = '' @description('Optional. TCP port of the database endpoint. Specified at create time. Default is (-1) meaning value is not set and defaults to an available port. Current supported port is 10000.') From 28c6c2a4020d0e5f03d5b265d7e9ff46b7d0e8d6 Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Sat, 16 Sep 2023 13:13:51 +1000 Subject: [PATCH 09/17] updated templates --- modules/cache/redis-enterprise/database/README.md | 2 +- modules/cache/redis-enterprise/database/main.bicep | 2 +- modules/cache/redis-enterprise/database/main.json | 10 +++++----- modules/cache/redis-enterprise/main.json | 12 ++++++------ 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/modules/cache/redis-enterprise/database/README.md b/modules/cache/redis-enterprise/database/README.md index ff2cbefeee..669f1249de 100644 --- a/modules/cache/redis-enterprise/database/README.md +++ b/modules/cache/redis-enterprise/database/README.md @@ -37,7 +37,7 @@ This module deploys a Redis Cache Enterprise Database. | `location` | string | `[resourceGroup().location]` | | Location for all resources. | | `modules` | array | `[]` | | Optional set of redis modules to enable in this database - modules can only be added at creation time. | | `persistenceAofEnabled` | bool | `False` | | Sets whether AOF is enabled. Required if setting AOF frequency. AOF and RDB persistence cannot be enabled at the same time. | -| `persistenceRdbEnabled` | bool | `False` | | Sets whether RDB is enabled. RDB and AOF persistence cannot be enabled at the same time | +| `persistenceRdbEnabled` | bool | `False` | | Sets whether RDB is enabled. RDB and AOF persistence cannot be enabled at the same time. | | `port` | int | `-1` | | TCP port of the database endpoint. Specified at create time. Default is (-1) meaning value is not set and defaults to an available port. Current supported port is 10000. | diff --git a/modules/cache/redis-enterprise/database/main.bicep b/modules/cache/redis-enterprise/database/main.bicep index 55497a1d78..95f26dff75 100644 --- a/modules/cache/redis-enterprise/database/main.bicep +++ b/modules/cache/redis-enterprise/database/main.bicep @@ -49,7 +49,7 @@ param persistenceAofEnabled bool = false @description('Conditional. Sets the frequency at which data is written to disk. Required if AOF persistence is enabled.') param persistenceAofFrequency string = '' -@description('Optional. Sets whether RDB is enabled. RDB and AOF persistence cannot be enabled at the same time') +@description('Optional. Sets whether RDB is enabled. RDB and AOF persistence cannot be enabled at the same time.') param persistenceRdbEnabled bool = false @allowed([ diff --git a/modules/cache/redis-enterprise/database/main.json b/modules/cache/redis-enterprise/database/main.json index 7fbc855d17..55f97dbb2b 100644 --- a/modules/cache/redis-enterprise/database/main.json +++ b/modules/cache/redis-enterprise/database/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.21.1.54444", - "templateHash": "14063731469491395921" + "templateHash": "16974139838344848652" }, "name": "Redis Cache Enterprise Databases", "description": "This module deploys a Redis Cache Enterprise Database.", @@ -75,7 +75,7 @@ "type": "bool", "defaultValue": false, "metadata": { - "description": "Conditional. Sets whether AOF is enabled. Required if setting AOF frequency. AOF and RDB persistence cannot be enabled at the same time." + "description": "Optional. Sets whether AOF is enabled. Required if setting AOF frequency. AOF and RDB persistence cannot be enabled at the same time." } }, "persistenceAofFrequency": { @@ -87,14 +87,14 @@ "always" ], "metadata": { - "description": "Optional. Sets the frequency at which data is written to disk. Can be set when AOF is enabled." + "description": "Conditional. Sets the frequency at which data is written to disk. Required if AOF persistence is enabled." } }, "persistenceRdbEnabled": { "type": "bool", "defaultValue": false, "metadata": { - "description": "Conditional. Sets whether RDB is enabled. Required if setting RDB frequency. RDB and AOF persistence cannot be enabled at the same time." + "description": "Optional. Sets whether RDB is enabled. RDB and AOF persistence cannot be enabled at the same time." } }, "persistenceRdbFrequency": { @@ -107,7 +107,7 @@ "6h" ], "metadata": { - "description": "Optional. Sets the frequency at which a snapshot of the database is created. Can be set when RDB is enabled." + "description": "Conditional. Sets the frequency at which a snapshot of the database is created. Required if RDB persistence is enabled." } }, "port": { diff --git a/modules/cache/redis-enterprise/main.json b/modules/cache/redis-enterprise/main.json index f6bc944dbf..bbfec7679a 100644 --- a/modules/cache/redis-enterprise/main.json +++ b/modules/cache/redis-enterprise/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.21.1.54444", - "templateHash": "2370045353021199422" + "templateHash": "11678354912342293007" }, "name": "Redis Cache Enterprise", "description": "This module deploys a Redis Cache Enterprise.", @@ -453,7 +453,7 @@ "_generator": { "name": "bicep", "version": "0.21.1.54444", - "templateHash": "14063731469491395921" + "templateHash": "16974139838344848652" }, "name": "Redis Cache Enterprise Databases", "description": "This module deploys a Redis Cache Enterprise Database.", @@ -523,7 +523,7 @@ "type": "bool", "defaultValue": false, "metadata": { - "description": "Conditional. Sets whether AOF is enabled. Required if setting AOF frequency. AOF and RDB persistence cannot be enabled at the same time." + "description": "Optional. Sets whether AOF is enabled. Required if setting AOF frequency. AOF and RDB persistence cannot be enabled at the same time." } }, "persistenceAofFrequency": { @@ -535,14 +535,14 @@ "always" ], "metadata": { - "description": "Optional. Sets the frequency at which data is written to disk. Can be set when AOF is enabled." + "description": "Conditional. Sets the frequency at which data is written to disk. Required if AOF persistence is enabled." } }, "persistenceRdbEnabled": { "type": "bool", "defaultValue": false, "metadata": { - "description": "Conditional. Sets whether RDB is enabled. Required if setting RDB frequency. RDB and AOF persistence cannot be enabled at the same time." + "description": "Optional. Sets whether RDB is enabled. RDB and AOF persistence cannot be enabled at the same time." } }, "persistenceRdbFrequency": { @@ -555,7 +555,7 @@ "6h" ], "metadata": { - "description": "Optional. Sets the frequency at which a snapshot of the database is created. Can be set when RDB is enabled." + "description": "Conditional. Sets the frequency at which a snapshot of the database is created. Required if RDB persistence is enabled." } }, "port": { From 43654ed43ba8bb1916421070364f5232c6b26df3 Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Sat, 16 Sep 2023 21:23:25 +1000 Subject: [PATCH 10/17] Updated test cases --- modules/cache/redis-enterprise/.test/common/main.test.bicep | 1 + modules/cache/redis-enterprise/README.md | 2 ++ 2 files changed, 3 insertions(+) diff --git a/modules/cache/redis-enterprise/.test/common/main.test.bicep b/modules/cache/redis-enterprise/.test/common/main.test.bicep index 09cb3be37f..a004da1eb2 100644 --- a/modules/cache/redis-enterprise/.test/common/main.test.bicep +++ b/modules/cache/redis-enterprise/.test/common/main.test.bicep @@ -102,6 +102,7 @@ module testDeployment '../../main.bicep' = { ] persistenceAofEnabled: true persistenceAofFrequency: '1s' + persistenceRdbEnabled: false port: 10000 } ] diff --git a/modules/cache/redis-enterprise/README.md b/modules/cache/redis-enterprise/README.md index 576d2d733e..7df5c6f188 100644 --- a/modules/cache/redis-enterprise/README.md +++ b/modules/cache/redis-enterprise/README.md @@ -373,6 +373,7 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { ] persistenceAofEnabled: true persistenceAofFrequency: '1s' + persistenceRdbEnabled: false port: 10000 } ] @@ -444,6 +445,7 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { ], "persistenceAofEnabled": true, "persistenceAofFrequency": "1s", + "persistenceRdbEnabled": false, "port": 10000 } ] From 824080d030f76f9302eea466a6ccdc56ada0d8fd Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Sat, 16 Sep 2023 21:46:01 +1000 Subject: [PATCH 11/17] updated readmes and added RBAC --- .../.test/common/dependencies.bicep | 11 ++++++++++ .../.test/common/main.test.bicep | 10 ++++++++++ modules/cache/redis-enterprise/README.md | 20 +++++++++++++++++++ .../cache/redis-enterprise/database/README.md | 2 +- .../redis-enterprise/database/main.bicep | 2 +- .../cache/redis-enterprise/database/main.json | 4 ++-- 6 files changed, 45 insertions(+), 4 deletions(-) diff --git a/modules/cache/redis-enterprise/.test/common/dependencies.bicep b/modules/cache/redis-enterprise/.test/common/dependencies.bicep index 1c46f0598e..179f4e64a2 100644 --- a/modules/cache/redis-enterprise/.test/common/dependencies.bicep +++ b/modules/cache/redis-enterprise/.test/common/dependencies.bicep @@ -4,6 +4,9 @@ param location string = resourceGroup().location @description('Required. The name of the Virtual Network to create.') param virtualNetworkName string +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + var addressPrefix = '10.0.0.0/16' resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { @@ -42,8 +45,16 @@ resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { } } +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + @description('The resource ID of the created Virtual Network Subnet.') output subnetResourceId string = virtualNetwork.properties.subnets[0].id @description('The resource ID of the created Private DNS Zone.') output privateDNSResourceId string = privateDNSZone.id + +@description('The principal ID of the created Managed Identity.') +output managedIdentityPrincipalId string = managedIdentity.properties.principalId diff --git a/modules/cache/redis-enterprise/.test/common/main.test.bicep b/modules/cache/redis-enterprise/.test/common/main.test.bicep index a004da1eb2..5763a64296 100644 --- a/modules/cache/redis-enterprise/.test/common/main.test.bicep +++ b/modules/cache/redis-enterprise/.test/common/main.test.bicep @@ -36,6 +36,7 @@ module nestedDependencies 'dependencies.bicep' = { name: '${uniqueString(deployment().name, location)}-nestedDependencies' params: { virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + managedIdentityName: 'dep-${namePrefix}-msi-ds-${serviceShort}' } } @@ -70,6 +71,15 @@ module testDeployment '../../main.bicep' = { diagnosticEventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName diagnosticSettingsName: 'redisdiagnostics' lock: 'CanNotDelete' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalIds: [ + nestedDependencies.outputs.managedIdentityPrincipalId + ] + principalType: 'ServicePrincipal' + } + ] minimumTlsVersion: '1.2' zoneRedundant: true privateEndpoints: [ diff --git a/modules/cache/redis-enterprise/README.md b/modules/cache/redis-enterprise/README.md index 7df5c6f188..9efbe665ee 100644 --- a/modules/cache/redis-enterprise/README.md +++ b/modules/cache/redis-enterprise/README.md @@ -401,6 +401,15 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { } } ] + roleAssignments: [ + { + principalIds: [ + '' + ] + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Reader' + } + ] tags: { 'hidden-title': 'This is visible in the resource name' resourceType: 'Redis Cache Enterprise' @@ -492,6 +501,17 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { } ] }, + "roleAssignments": { + "value": [ + { + "principalIds": [ + "" + ], + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Reader" + } + ] + }, "tags": { "value": { "hidden-title": "This is visible in the resource name", diff --git a/modules/cache/redis-enterprise/database/README.md b/modules/cache/redis-enterprise/database/README.md index 669f1249de..19f52545ce 100644 --- a/modules/cache/redis-enterprise/database/README.md +++ b/modules/cache/redis-enterprise/database/README.md @@ -30,7 +30,7 @@ This module deploys a Redis Cache Enterprise Database. | Parameter Name | Type | Default Value | Allowed Values | Description | | :-- | :-- | :-- | :-- | :-- | | `clientProtocol` | string | `'Encrypted'` | `[Encrypted, Plaintext]` | Specifies whether redis clients can connect using TLS-encrypted or plaintext redis protocols. Default is TLS-encrypted. | -| `clusteringPolicy` | string | `'OSSCluster'` | `[EnterpriseCluster, OSSCluster]` | Clustering policy - default is OSSCluster. Specified at create time. | +| `clusteringPolicy` | string | `'OSSCluster'` | `[EnterpriseCluster, OSSCluster]` | Specifies the clustering policy to enable at creation time of the Redis Cache Enterprise Cluster. | | `enableDefaultTelemetry` | bool | `True` | | Enable telemetry via a Globally Unique Identifier (GUID). | | `evictionPolicy` | string | `'VolatileLRU'` | `[AllKeysLFU, AllKeysLRU, AllKeysRandom, NoEviction, VolatileLFU, VolatileLRU, VolatileRandom, VolatileTTL]` | Redis eviction policy - default is VolatileLRU. | | `geoReplication` | object | `{object}` | | Optional set of properties to configure geo replication for this database. Geo replication prerequisites must be met. See "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-how-to-active-geo-replication#active-geo-replication-prerequisites" for more information. | diff --git a/modules/cache/redis-enterprise/database/main.bicep b/modules/cache/redis-enterprise/database/main.bicep index 95f26dff75..793f8294a4 100644 --- a/modules/cache/redis-enterprise/database/main.bicep +++ b/modules/cache/redis-enterprise/database/main.bicep @@ -16,7 +16,7 @@ param clientProtocol string = 'Encrypted' 'EnterpriseCluster' 'OSSCluster' ]) -@description('Optional. Clustering policy - default is OSSCluster. Specified at create time.') +@description('Optional. Specifies the clustering policy to enable at creation time of the Redis Cache Enterprise Cluster.') param clusteringPolicy string = 'OSSCluster' @allowed([ diff --git a/modules/cache/redis-enterprise/database/main.json b/modules/cache/redis-enterprise/database/main.json index 55f97dbb2b..27d234923b 100644 --- a/modules/cache/redis-enterprise/database/main.json +++ b/modules/cache/redis-enterprise/database/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.21.1.54444", - "templateHash": "16974139838344848652" + "templateHash": "16731424701559883139" }, "name": "Redis Cache Enterprise Databases", "description": "This module deploys a Redis Cache Enterprise Database.", @@ -37,7 +37,7 @@ "OSSCluster" ], "metadata": { - "description": "Optional. Clustering policy - default is OSSCluster. Specified at create time." + "description": "Optional. Specifies the clustering policy to enable at creation time of the Redis Cache Enterprise Cluster." } }, "evictionPolicy": { From 829edef315187674a134070c8e3afa6209cd4b4b Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Sat, 16 Sep 2023 21:48:13 +1000 Subject: [PATCH 12/17] updated main.json --- modules/cache/redis-enterprise/main.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/cache/redis-enterprise/main.json b/modules/cache/redis-enterprise/main.json index bbfec7679a..d8e7876ddc 100644 --- a/modules/cache/redis-enterprise/main.json +++ b/modules/cache/redis-enterprise/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.21.1.54444", - "templateHash": "11678354912342293007" + "templateHash": "944049645680553986" }, "name": "Redis Cache Enterprise", "description": "This module deploys a Redis Cache Enterprise.", @@ -453,7 +453,7 @@ "_generator": { "name": "bicep", "version": "0.21.1.54444", - "templateHash": "16974139838344848652" + "templateHash": "16731424701559883139" }, "name": "Redis Cache Enterprise Databases", "description": "This module deploys a Redis Cache Enterprise Database.", @@ -485,7 +485,7 @@ "OSSCluster" ], "metadata": { - "description": "Optional. Clustering policy - default is OSSCluster. Specified at create time." + "description": "Optional. Specifies the clustering policy to enable at creation time of the Redis Cache Enterprise Cluster." } }, "evictionPolicy": { From 9cef3c9d9a220f43b2fbaa37686aceae9ba11d91 Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Sun, 17 Sep 2023 06:44:32 +1000 Subject: [PATCH 13/17] Updated doco and tests --- .../.test/common/main.test.bicep | 2 + modules/cache/redis-enterprise/README.md | 6 ++- .../cache/redis-enterprise/database/README.md | 51 +++++++++++++++++++ modules/cache/redis-enterprise/main.bicep | 4 +- 4 files changed, 60 insertions(+), 3 deletions(-) diff --git a/modules/cache/redis-enterprise/.test/common/main.test.bicep b/modules/cache/redis-enterprise/.test/common/main.test.bicep index 5763a64296..3f45efa094 100644 --- a/modules/cache/redis-enterprise/.test/common/main.test.bicep +++ b/modules/cache/redis-enterprise/.test/common/main.test.bicep @@ -105,9 +105,11 @@ module testDeployment '../../main.bicep' = { modules: [ { name: 'RedisBloom' + args: 'ERROR_RATE 0.00 INITIAL_SIZE 400' } { name: 'RedisTimeSeries' + args: 'RETENTION_POLICY 20' } ] persistenceAofEnabled: true diff --git a/modules/cache/redis-enterprise/README.md b/modules/cache/redis-enterprise/README.md index 9efbe665ee..07172c9feb 100644 --- a/modules/cache/redis-enterprise/README.md +++ b/modules/cache/redis-enterprise/README.md @@ -38,7 +38,7 @@ This module deploys a Redis Cache Enterprise. | `databases` | array | `[]` | | The databases to create in the Redis Cache Enterprise Cluster. | | `diagnosticEventHubAuthorizationRuleId` | string | `''` | | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | `diagnosticEventHubName` | string | `''` | | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | -| `diagnosticLogCategoriesToEnable` | array | `[]` | `['', allLogs, audit, ConnectionEvents]` | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| `diagnosticLogCategoriesToEnable` | array | `[]` | `['', audit, ConnectionEvents]` | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource, but currently not supported for Redis Cache Enterprise. Set to '' to disable log collection. | | `diagnosticMetricsToEnable` | array | `[AllMetrics]` | `[AllMetrics]` | The name of metrics that will be streamed. | | `diagnosticSettingsName` | string | `''` | | The name of the diagnostic setting, if deployed. If left empty, it defaults to "-diagnosticSettings". | | `diagnosticStorageAccountId` | string | `''` | | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | @@ -365,9 +365,11 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { evictionPolicy: 'AllKeysLFU' modules: [ { + args: 'ERROR_RATE 0.00 INITIAL_SIZE 400' name: 'RedisBloom' } { + args: 'RETENTION_POLICY 20' name: 'RedisTimeSeries' } ] @@ -446,9 +448,11 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { "evictionPolicy": "AllKeysLFU", "modules": [ { + "args": "ERROR_RATE 0.00 INITIAL_SIZE 400", "name": "RedisBloom" }, { + "args": "RETENTION_POLICY 20", "name": "RedisTimeSeries" } ], diff --git a/modules/cache/redis-enterprise/database/README.md b/modules/cache/redis-enterprise/database/README.md index 19f52545ce..56513c79f7 100644 --- a/modules/cache/redis-enterprise/database/README.md +++ b/modules/cache/redis-enterprise/database/README.md @@ -41,6 +41,57 @@ This module deploys a Redis Cache Enterprise Database. | `port` | int | `-1` | | TCP port of the database endpoint. Specified at create time. Default is (-1) meaning value is not set and defaults to an available port. Current supported port is 10000. | +### Parameter Usage: `modules` + +Optional set of Redis modules to enable in this database. Modules can only be added at creation time. Each module requires a name (e.g. 'RedisBloom', 'RediSearch', 'RedisTimeSeries') and optionally an argument (e.g. 'ERROR_RATE 0.01 INITIAL_SIZE 400'). See [Redis Cache modules documentation](https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-redis-modules) for more information. + +
+ +Parameter JSON format + +```json +"modules": { + "value": [ + { + "name": "RedisBloom", + "args": "ERROR_RATE 0.00 INITIAL_SIZE 400" + }, + { + "name": "RedisTimeSeries", + "args": "RETENTION_POLICY 20" + }, + { + "name": "RediSearch" + } + ] +} +``` + +
+ +
+ +Bicep format + +```bicep +modules: [ + { + name: 'RedisBloom' + args: 'ERROR_RATE 0.00 INITIAL_SIZE 400' + } + { + name: 'RedisTimeSeries' + args: 'RETENTION_POLICY 20' + } + { + name: 'RediSearch' + } +] +``` + +
+

+ ## Outputs | Output Name | Type | Description | diff --git a/modules/cache/redis-enterprise/main.bicep b/modules/cache/redis-enterprise/main.bicep index a5cb8a3c3c..97372b7761 100644 --- a/modules/cache/redis-enterprise/main.bicep +++ b/modules/cache/redis-enterprise/main.bicep @@ -69,10 +69,10 @@ param diagnosticEventHubAuthorizationRuleId string = '' @description('Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') param diagnosticEventHubName string = '' -@description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') +@description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource, but currently not supported for Redis Cache Enterprise. Set to \'\' to disable log collection.') @allowed([ '' - 'allLogs' + // 'allLogs' 'ConnectionEvents' 'audit' ]) From af709b1a49a1f20b6249dd2546bd4d9d9af27a64 Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Sun, 17 Sep 2023 06:48:51 +1000 Subject: [PATCH 14/17] updated JSON --- modules/cache/redis-enterprise/main.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/cache/redis-enterprise/main.json b/modules/cache/redis-enterprise/main.json index d8e7876ddc..8e5b157615 100644 --- a/modules/cache/redis-enterprise/main.json +++ b/modules/cache/redis-enterprise/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.21.1.54444", - "templateHash": "944049645680553986" + "templateHash": "14564256646537619194" }, "name": "Redis Cache Enterprise", "description": "This module deploys a Redis Cache Enterprise.", @@ -149,12 +149,11 @@ ], "allowedValues": [ "", - "allLogs", "ConnectionEvents", "audit" ], "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource, but currently not supported for Redis Cache Enterprise. Set to '' to disable log collection." } }, "diagnosticMetricsToEnable": { From f2bf4a2bcadae19cd6c42d3710ca1c9a0ab2d154 Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Sun, 17 Sep 2023 07:06:03 +1000 Subject: [PATCH 15/17] Updated tests --- modules/cache/redis-enterprise/.test/common/main.test.bicep | 2 +- modules/cache/redis-enterprise/README.md | 4 ++-- modules/cache/redis-enterprise/database/README.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/cache/redis-enterprise/.test/common/main.test.bicep b/modules/cache/redis-enterprise/.test/common/main.test.bicep index 3f45efa094..d7db3fb278 100644 --- a/modules/cache/redis-enterprise/.test/common/main.test.bicep +++ b/modules/cache/redis-enterprise/.test/common/main.test.bicep @@ -105,7 +105,7 @@ module testDeployment '../../main.bicep' = { modules: [ { name: 'RedisBloom' - args: 'ERROR_RATE 0.00 INITIAL_SIZE 400' + args: 'ERROR_RATE 1.00 INITIAL_SIZE 400' } { name: 'RedisTimeSeries' diff --git a/modules/cache/redis-enterprise/README.md b/modules/cache/redis-enterprise/README.md index 07172c9feb..a83cff89d3 100644 --- a/modules/cache/redis-enterprise/README.md +++ b/modules/cache/redis-enterprise/README.md @@ -365,7 +365,7 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { evictionPolicy: 'AllKeysLFU' modules: [ { - args: 'ERROR_RATE 0.00 INITIAL_SIZE 400' + args: 'ERROR_RATE 1.00 INITIAL_SIZE 400' name: 'RedisBloom' } { @@ -448,7 +448,7 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { "evictionPolicy": "AllKeysLFU", "modules": [ { - "args": "ERROR_RATE 0.00 INITIAL_SIZE 400", + "args": "ERROR_RATE 1.00 INITIAL_SIZE 400", "name": "RedisBloom" }, { diff --git a/modules/cache/redis-enterprise/database/README.md b/modules/cache/redis-enterprise/database/README.md index 56513c79f7..b4cfcd3cb1 100644 --- a/modules/cache/redis-enterprise/database/README.md +++ b/modules/cache/redis-enterprise/database/README.md @@ -77,7 +77,7 @@ Optional set of Redis modules to enable in this database. Modules can only be ad modules: [ { name: 'RedisBloom' - args: 'ERROR_RATE 0.00 INITIAL_SIZE 400' + args: 'ERROR_RATE 1.00 INITIAL_SIZE 400' } { name: 'RedisTimeSeries' From 6f475cab671791d6d9544beb67adffb4925a81da Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Sun, 17 Sep 2023 09:01:08 +1000 Subject: [PATCH 16/17] Updated test cases --- modules/cache/redis-enterprise/.test/common/main.test.bicep | 1 - modules/cache/redis-enterprise/README.md | 2 -- 2 files changed, 3 deletions(-) diff --git a/modules/cache/redis-enterprise/.test/common/main.test.bicep b/modules/cache/redis-enterprise/.test/common/main.test.bicep index d7db3fb278..fe85adb34b 100644 --- a/modules/cache/redis-enterprise/.test/common/main.test.bicep +++ b/modules/cache/redis-enterprise/.test/common/main.test.bicep @@ -105,7 +105,6 @@ module testDeployment '../../main.bicep' = { modules: [ { name: 'RedisBloom' - args: 'ERROR_RATE 1.00 INITIAL_SIZE 400' } { name: 'RedisTimeSeries' diff --git a/modules/cache/redis-enterprise/README.md b/modules/cache/redis-enterprise/README.md index a83cff89d3..5dbfef954d 100644 --- a/modules/cache/redis-enterprise/README.md +++ b/modules/cache/redis-enterprise/README.md @@ -365,7 +365,6 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { evictionPolicy: 'AllKeysLFU' modules: [ { - args: 'ERROR_RATE 1.00 INITIAL_SIZE 400' name: 'RedisBloom' } { @@ -448,7 +447,6 @@ module redisEnterprise './cache/redis-enterprise/main.bicep' = { "evictionPolicy": "AllKeysLFU", "modules": [ { - "args": "ERROR_RATE 1.00 INITIAL_SIZE 400", "name": "RedisBloom" }, { From 276cf36d42b9cb815d8cdacaea4457e24bf874e6 Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Sun, 17 Sep 2023 11:30:59 +1000 Subject: [PATCH 17/17] Updated versions --- modules/cache/redis-enterprise/database/version.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/cache/redis-enterprise/database/version.json b/modules/cache/redis-enterprise/database/version.json index 96236a61ba..04a0dd1a80 100644 --- a/modules/cache/redis-enterprise/database/version.json +++ b/modules/cache/redis-enterprise/database/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.4", + "version": "0.5", "pathFilters": [ "./main.json" ]