Skip to content

Commit

Permalink
feat: avm/res/cache/redis: Support exporting StackExchange.Redis co…
Browse files Browse the repository at this point in the history
…nnection strings to Key Vault (#4343)

## Description

Add support for exporting TLS-enabled [StackExchange.Redis connection
strings](https://stackexchange.github.io/StackExchange.Redis/Configuration.html#basic-configuration-strings)
to Key Vault:

```
<name>.redis.cache.windows.net:6380,password=<accesskey>,ssl=True,abortConnect=False
```

I've kept the same parameters as what's shown in portal's Authentication
blade:

![image](https://github.com/user-attachments/assets/6a2d5256-ec62-44b5-94a6-5bebe6838d9c)

Usage example:
```bicep
module redis 'br/public:avm/res/cache/redis:<version>' = {
  name: 'redisDeployment'
  params: {
    // Required parameters
    name: 'kvref'
    // Non-required parameters
    location: '<location>'
    secretsExportConfiguration: {
      keyVaultResourceId: '<keyVaultResourceId>'
      primaryStackExchangeRedisConnectionStringName: 'custom-primaryStackExchangeRedisConnectionString-name'
      secondaryStackExchangeRedisConnectionStringName: 'custom-secondaryStackExchangeRedisConnectionString-name'
    }
  }
}
```

## Pipeline Reference
Ran the `kv-secrets` E2E test locally and passed:

![image](https://github.com/user-attachments/assets/df6d8dd8-64cc-44a9-b210-b917ded81190)

| Pipeline |
| -------- |
|          |

## Type of Change

<!-- Use the checkboxes [x] on the options that are relevant. -->

- [ ] Update to CI Environment or utilities (Non-module affecting
changes)
- [x] Azure Verified Module updates:
- [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT
bumped the MAJOR or MINOR version in `version.json`:
- [ ] Someone has opened a bug report issue, and I have included "Closes
#{bug_report_issue_number}" in the PR description.
- [ ] The bug was found by the module author, and no one has opened an
issue to report it yet.
- [x] Feature update backwards compatible feature updates, and I have
bumped the MINOR version in `version.json`.
- [ ] Breaking changes and I have bumped the MAJOR version in
`version.json`.
  - [ ] Update to documentation

## Checklist

- [x] I'm sure there are no other open Pull Requests for the same
update/change
- [x] I have run `Set-AVMModule` locally to generate the supporting
module files.
- [ ] My corresponding pipelines / checks run clean and green without
any errors or warnings

<!-- Please keep up to date with the contribution guide at
https://aka.ms/avm/contribute/bicep -->
  • Loading branch information
JeffreyCA authored Jan 29, 2025
1 parent 109bfbe commit 3fb7c6e
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 6 deletions.
26 changes: 25 additions & 1 deletion avm/res/cache/redis/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,10 @@ module redis 'br/public:avm/res/cache/redis:<version>' = {
keyVaultResourceId: '<keyVaultResourceId>'
primaryAccessKeyName: 'custom-primaryAccessKey-name'
primaryConnectionStringName: 'custom-primaryConnectionString-name'
primaryStackExchangeRedisConnectionStringName: 'custom-primaryStackExchangeRedisConnectionString-name'
secondaryAccessKeyName: 'custom-secondaryAccessKey-name'
secondaryConnectionStringName: 'custom-secondaryConnectionString-name'
secondaryStackExchangeRedisConnectionStringName: 'custom-secondaryStackExchangeRedisConnectionString-name'
}
}
}
Expand Down Expand Up @@ -277,8 +279,10 @@ module redis 'br/public:avm/res/cache/redis:<version>' = {
"keyVaultResourceId": "<keyVaultResourceId>",
"primaryAccessKeyName": "custom-primaryAccessKey-name",
"primaryConnectionStringName": "custom-primaryConnectionString-name",
"primaryStackExchangeRedisConnectionStringName": "custom-primaryStackExchangeRedisConnectionString-name",
"secondaryAccessKeyName": "custom-secondaryAccessKey-name",
"secondaryConnectionStringName": "custom-secondaryConnectionString-name"
"secondaryConnectionStringName": "custom-secondaryConnectionString-name",
"secondaryStackExchangeRedisConnectionStringName": "custom-secondaryStackExchangeRedisConnectionString-name"
}
}
}
Expand All @@ -303,8 +307,10 @@ param secretsExportConfiguration = {
keyVaultResourceId: '<keyVaultResourceId>'
primaryAccessKeyName: 'custom-primaryAccessKey-name'
primaryConnectionStringName: 'custom-primaryConnectionString-name'
primaryStackExchangeRedisConnectionStringName: 'custom-primaryStackExchangeRedisConnectionString-name'
secondaryAccessKeyName: 'custom-secondaryAccessKey-name'
secondaryConnectionStringName: 'custom-secondaryConnectionString-name'
secondaryStackExchangeRedisConnectionStringName: 'custom-secondaryStackExchangeRedisConnectionString-name'
}
```

Expand Down Expand Up @@ -2110,8 +2116,10 @@ Key vault reference and secret settings for the module's secrets export.
| :-- | :-- | :-- |
| [`primaryAccessKeyName`](#parameter-secretsexportconfigurationprimaryaccesskeyname) | string | The primaryAccessKey secret name to create. |
| [`primaryConnectionStringName`](#parameter-secretsexportconfigurationprimaryconnectionstringname) | string | The primaryConnectionString secret name to create. |
| [`primaryStackExchangeRedisConnectionStringName`](#parameter-secretsexportconfigurationprimarystackexchangeredisconnectionstringname) | string | The primaryStackExchangeRedisConnectionString secret name to create. |
| [`secondaryAccessKeyName`](#parameter-secretsexportconfigurationsecondaryaccesskeyname) | string | The secondaryAccessKey secret name to create. |
| [`secondaryConnectionStringName`](#parameter-secretsexportconfigurationsecondaryconnectionstringname) | string | The secondaryConnectionString secret name to create. |
| [`secondaryStackExchangeRedisConnectionStringName`](#parameter-secretsexportconfigurationsecondarystackexchangeredisconnectionstringname) | string | The secondaryStackExchangeRedisConnectionString secret name to create. |

### Parameter: `secretsExportConfiguration.keyVaultResourceId`

Expand All @@ -2137,6 +2145,14 @@ The primaryConnectionString secret name to create.
- Type: string
- MinValue: 1

### Parameter: `secretsExportConfiguration.primaryStackExchangeRedisConnectionStringName`

The primaryStackExchangeRedisConnectionString secret name to create.

- Required: No
- Type: string
- MinValue: 1

### Parameter: `secretsExportConfiguration.secondaryAccessKeyName`

The secondaryAccessKey secret name to create.
Expand All @@ -2153,6 +2169,14 @@ The secondaryConnectionString secret name to create.
- Type: string
- MinValue: 1

### Parameter: `secretsExportConfiguration.secondaryStackExchangeRedisConnectionStringName`

The secondaryStackExchangeRedisConnectionString secret name to create.

- Required: No
- Type: string
- MinValue: 1

### Parameter: `shardCount`

The number of shards to be created on a Premium Cluster Cache.
Expand Down
4 changes: 2 additions & 2 deletions avm/res/cache/redis/linked-servers/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.32.4.45862",
"templateHash": "395538410437204745"
"version": "0.33.13.18514",
"templateHash": "11294861621866290910"
},
"name": "Redis Cache Linked Servers",
"description": "This module connects a primary and secondary Redis Cache together for geo-replication."
Expand Down
22 changes: 22 additions & 0 deletions avm/res/cache/redis/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,14 @@ module secretsExport 'modules/keyVaultExport.bicep' = if (secretsExportConfigura
}
]
: [],
contains(secretsExportConfiguration!, 'primaryStackExchangeRedisConnectionStringName')
? [
{
name: secretsExportConfiguration!.?primaryStackExchangeRedisConnectionStringName
value: '${redis.properties.hostName}:6380,password=${redis.listKeys().primaryKey},ssl=True,abortConnect=False'
}
]
: [],
contains(secretsExportConfiguration!, 'secondaryAccessKeyName')
? [
{
Expand All @@ -413,6 +421,14 @@ module secretsExport 'modules/keyVaultExport.bicep' = if (secretsExportConfigura
value: 'rediss://:${redis.listKeys().secondaryKey}@${redis.properties.hostName}:6380'
}
]
: [],
contains(secretsExportConfiguration!, 'secondaryStackExchangeRedisConnectionStringName')
? [
{
name: secretsExportConfiguration!.?secondaryStackExchangeRedisConnectionStringName
value: '${redis.properties.hostName}:6380,password=${redis.listKeys().secondaryKey},ssl=True,abortConnect=False'
}
]
: []
)
}
Expand Down Expand Up @@ -514,9 +530,15 @@ type secretsExportConfigurationType = {
@description('Optional. The primaryConnectionString secret name to create.')
primaryConnectionStringName: string?

@description('Optional. The primaryStackExchangeRedisConnectionString secret name to create.')
primaryStackExchangeRedisConnectionStringName: string?

@description('Optional. The secondaryAccessKey secret name to create.')
secondaryAccessKeyName: string?

@description('Optional. The secondaryConnectionString secret name to create.')
secondaryConnectionStringName: string?

@description('Optional. The secondaryStackExchangeRedisConnectionString secret name to create.')
secondaryStackExchangeRedisConnectionStringName: string?
}
18 changes: 16 additions & 2 deletions avm/res/cache/redis/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"_generator": {
"name": "bicep",
"version": "0.33.13.18514",
"templateHash": "6280028405930372235"
"templateHash": "14266403126769654218"
},
"name": "Redis Cache",
"description": "This module deploys a Redis Cache."
Expand Down Expand Up @@ -138,6 +138,13 @@
"description": "Optional. The primaryConnectionString secret name to create."
}
},
"primaryStackExchangeRedisConnectionStringName": {
"type": "string",
"nullable": true,
"metadata": {
"description": "Optional. The primaryStackExchangeRedisConnectionString secret name to create."
}
},
"secondaryAccessKeyName": {
"type": "string",
"nullable": true,
Expand All @@ -151,6 +158,13 @@
"metadata": {
"description": "Optional. The secondaryConnectionString secret name to create."
}
},
"secondaryStackExchangeRedisConnectionStringName": {
"type": "string",
"nullable": true,
"metadata": {
"description": "Optional. The secondaryStackExchangeRedisConnectionString secret name to create."
}
}
},
"metadata": {
Expand Down Expand Up @@ -2047,7 +2061,7 @@
"value": "[last(split(coalesce(tryGet(parameters('secretsExportConfiguration'), 'keyVaultResourceId'), '//'), '/'))]"
},
"secretsToSet": {
"value": "[union(createArray(), if(contains(parameters('secretsExportConfiguration'), 'primaryAccessKeyName'), createArray(createObject('name', tryGet(parameters('secretsExportConfiguration'), 'primaryAccessKeyName'), 'value', listKeys(resourceId('Microsoft.Cache/redis', parameters('name')), '2024-11-01').primaryKey)), createArray()), if(contains(parameters('secretsExportConfiguration'), 'primaryConnectionStringName'), createArray(createObject('name', tryGet(parameters('secretsExportConfiguration'), 'primaryConnectionStringName'), 'value', format('rediss://:{0}@{1}:6380', listKeys(resourceId('Microsoft.Cache/redis', parameters('name')), '2024-11-01').primaryKey, reference('redis').hostName))), createArray()), if(contains(parameters('secretsExportConfiguration'), 'secondaryAccessKeyName'), createArray(createObject('name', tryGet(parameters('secretsExportConfiguration'), 'secondaryAccessKeyName'), 'value', listKeys(resourceId('Microsoft.Cache/redis', parameters('name')), '2024-11-01').secondaryKey)), createArray()), if(contains(parameters('secretsExportConfiguration'), 'secondaryConnectionStringName'), createArray(createObject('name', tryGet(parameters('secretsExportConfiguration'), 'secondaryConnectionStringName'), 'value', format('rediss://:{0}@{1}:6380', listKeys(resourceId('Microsoft.Cache/redis', parameters('name')), '2024-11-01').secondaryKey, reference('redis').hostName))), createArray()))]"
"value": "[union(createArray(), if(contains(parameters('secretsExportConfiguration'), 'primaryAccessKeyName'), createArray(createObject('name', tryGet(parameters('secretsExportConfiguration'), 'primaryAccessKeyName'), 'value', listKeys(resourceId('Microsoft.Cache/redis', parameters('name')), '2024-11-01').primaryKey)), createArray()), if(contains(parameters('secretsExportConfiguration'), 'primaryConnectionStringName'), createArray(createObject('name', tryGet(parameters('secretsExportConfiguration'), 'primaryConnectionStringName'), 'value', format('rediss://:{0}@{1}:6380', listKeys(resourceId('Microsoft.Cache/redis', parameters('name')), '2024-11-01').primaryKey, reference('redis').hostName))), createArray()), if(contains(parameters('secretsExportConfiguration'), 'primaryStackExchangeRedisConnectionStringName'), createArray(createObject('name', tryGet(parameters('secretsExportConfiguration'), 'primaryStackExchangeRedisConnectionStringName'), 'value', format('{0}:6380,password={1},ssl=True,abortConnect=False', reference('redis').hostName, listKeys(resourceId('Microsoft.Cache/redis', parameters('name')), '2024-11-01').primaryKey))), createArray()), if(contains(parameters('secretsExportConfiguration'), 'secondaryAccessKeyName'), createArray(createObject('name', tryGet(parameters('secretsExportConfiguration'), 'secondaryAccessKeyName'), 'value', listKeys(resourceId('Microsoft.Cache/redis', parameters('name')), '2024-11-01').secondaryKey)), createArray()), if(contains(parameters('secretsExportConfiguration'), 'secondaryConnectionStringName'), createArray(createObject('name', tryGet(parameters('secretsExportConfiguration'), 'secondaryConnectionStringName'), 'value', format('rediss://:{0}@{1}:6380', listKeys(resourceId('Microsoft.Cache/redis', parameters('name')), '2024-11-01').secondaryKey, reference('redis').hostName))), createArray()), if(contains(parameters('secretsExportConfiguration'), 'secondaryStackExchangeRedisConnectionStringName'), createArray(createObject('name', tryGet(parameters('secretsExportConfiguration'), 'secondaryStackExchangeRedisConnectionStringName'), 'value', format('{0}:6380,password={1},ssl=True,abortConnect=False', reference('redis').hostName, listKeys(resourceId('Microsoft.Cache/redis', parameters('name')), '2024-11-01').secondaryKey))), createArray()))]"
}
},
"template": {
Expand Down
2 changes: 2 additions & 0 deletions avm/res/cache/redis/tests/e2e/kv-secrets/main.test.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,10 @@ module testDeployment '../../../main.bicep' = {
keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId
primaryAccessKeyName: 'custom-primaryAccessKey-name'
primaryConnectionStringName: 'custom-primaryConnectionString-name'
primaryStackExchangeRedisConnectionStringName: 'custom-primaryStackExchangeRedisConnectionString-name'
secondaryAccessKeyName: 'custom-secondaryAccessKey-name'
secondaryConnectionStringName: 'custom-secondaryConnectionString-name'
secondaryStackExchangeRedisConnectionStringName: 'custom-secondaryStackExchangeRedisConnectionString-name'
}
}
}
2 changes: 1 addition & 1 deletion avm/res/cache/redis/version.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "https://aka.ms/bicep-registry-module-version-file-schema#",
"version": "0.11",
"version": "0.12",
"pathFilters": [
"./main.json"
]
Expand Down

0 comments on commit 3fb7c6e

Please sign in to comment.