Skip to content

Commit

Permalink
fix: update avm/res/container-registry/registry cache-rule to sup…
Browse files Browse the repository at this point in the history
…port unauthenticated repositories and wildcards (#3764)

## Description

Updating the ACR module to allow for unauthenticated cache rules and
wildcard repositories. Today, the module:

- Errantly tries to include the asterisk from a wildcard repository in
the name, causing a deployment failure
- Errantly marks the `credentialSetResourceId` property as required when
it's not required for some repositories like Microsoft Artifact Registry
(`mcr.microsoft.com`)

### Changes

- [x] Make `credentialSetResourceId` optional (nullable)
- [x] Fix `name` parameter to replace wilcards in the `sourceRepository`
parameter
- [x] Run generation of readme files
- [x] Update existing unit test to create a cache rule for MCR without
an explicit name or credential set specified.
- [x] Ran generation on all modules since Bicep no-longer requires
`dependsOn`
  - This was required to get a successful build

### Resolves

- [x] Fixes #3741

## Pipeline Reference

<!-- Insert your Pipeline Status Badge below -->

| Pipeline |
| -------- |
|
[![avm.res.container-registry.registry](https://github.com/seesharprun/bicep-registry-modules/actions/workflows/avm.res.container-registry.registry.yml/badge.svg)](https://github.com/seesharprun/bicep-registry-modules/actions/workflows/avm.res.container-registry.registry.yml)
|

## 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:
- [x] Bugfix containing backwards-compatible bug fixes, and I have NOT
bumped the MAJOR or MINOR version in `version.json`:
- [x] Someone has opened a bug report issue, and I have included "Closes
#{bug_report_issue_number}" in the PR description.
- [ ] The bug was found by the module author, and no one has opened an
issue to report it yet.
- [ ] Feature update backwards compatible feature updates, and I have
bumped the MINOR version in `version.json`.
- [ ] Breaking changes and I have bumped the MAJOR version in
`version.json`.
  - [ ] Update to documentation

## Checklist

- [x] I'm sure there are no other open Pull Requests for the same
update/change
- [x] I have run `Set-AVMModule` locally to generate the supporting
module files.
- [ ] 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 -->

---------

Co-authored-by: Alexander Sehr <[email protected]>
  • Loading branch information
seesharprun and AlexanderSehr authored Jan 25, 2025
1 parent 7eccdb8 commit de31485
Show file tree
Hide file tree
Showing 12 changed files with 59 additions and 375 deletions.
171 changes: 10 additions & 161 deletions avm/res/container-registry/registry/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,164 +35,13 @@ The following section provides usage examples for the module, which were used to
>**Note**: To reference the module, please use the following syntax `br/public:avm/res/container-registry/registry:<version>`.
- [Using cache rules](#example-1-using-cache-rules)
- [Using only defaults](#example-2-using-only-defaults)
- [Using encryption with Customer-Managed-Key](#example-3-using-encryption-with-customer-managed-key)
- [Using large parameter set](#example-4-using-large-parameter-set)
- [Using `scopeMaps` in parameter set](#example-5-using-scopemaps-in-parameter-set)
- [WAF-aligned](#example-6-waf-aligned)
- [Using only defaults](#example-1-using-only-defaults)
- [Using encryption with Customer-Managed-Key](#example-2-using-encryption-with-customer-managed-key)
- [Using large parameter set](#example-3-using-large-parameter-set)
- [Using `scopeMaps` in parameter set](#example-4-using-scopemaps-in-parameter-set)
- [WAF-aligned](#example-5-waf-aligned)

### Example 1: _Using cache rules_

This instance deploys the module with a credential set and a cache rule.


<details>

<summary>via Bicep module</summary>

```bicep
module registry 'br/public:avm/res/container-registry/registry:<version>' = {
name: 'registryDeployment'
params: {
// Required parameters
name: '<name>'
// Non-required parameters
acrAdminUserEnabled: false
acrSku: 'Standard'
cacheRules: [
{
credentialSetResourceId: '<credentialSetResourceId>'
name: 'customRule'
sourceRepository: 'docker.io/library/hello-world'
targetRepository: 'cached-docker-hub/hello-world'
}
]
credentialSets: [
{
authCredentials: [
{
name: 'Credential1'
passwordSecretIdentifier: '<passwordSecretIdentifier>'
usernameSecretIdentifier: '<usernameSecretIdentifier>'
}
]
loginServer: 'docker.io'
managedIdentities: {
systemAssigned: true
}
name: 'default'
}
]
location: '<location>'
}
}
```

</details>
<p>

<details>

<summary>via JSON parameters file</summary>

```json
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
// Required parameters
"name": {
"value": "<name>"
},
// Non-required parameters
"acrAdminUserEnabled": {
"value": false
},
"acrSku": {
"value": "Standard"
},
"cacheRules": {
"value": [
{
"credentialSetResourceId": "<credentialSetResourceId>",
"name": "customRule",
"sourceRepository": "docker.io/library/hello-world",
"targetRepository": "cached-docker-hub/hello-world"
}
]
},
"credentialSets": {
"value": [
{
"authCredentials": [
{
"name": "Credential1",
"passwordSecretIdentifier": "<passwordSecretIdentifier>",
"usernameSecretIdentifier": "<usernameSecretIdentifier>"
}
],
"loginServer": "docker.io",
"managedIdentities": {
"systemAssigned": true
},
"name": "default"
}
]
},
"location": {
"value": "<location>"
}
}
}
```

</details>
<p>

<details>

<summary>via Bicep parameters file</summary>

```bicep-params
using 'br/public:avm/res/container-registry/registry:<version>'
// Required parameters
param name = '<name>'
// Non-required parameters
param acrAdminUserEnabled = false
param acrSku = 'Standard'
param cacheRules = [
{
credentialSetResourceId: '<credentialSetResourceId>'
name: 'customRule'
sourceRepository: 'docker.io/library/hello-world'
targetRepository: 'cached-docker-hub/hello-world'
}
]
param credentialSets = [
{
authCredentials: [
{
name: 'Credential1'
passwordSecretIdentifier: '<passwordSecretIdentifier>'
usernameSecretIdentifier: '<usernameSecretIdentifier>'
}
]
loginServer: 'docker.io'
managedIdentities: {
systemAssigned: true
}
name: 'default'
}
]
param location = '<location>'
```

</details>
<p>

### Example 2: _Using only defaults_
### Example 1: _Using only defaults_

This instance deploys the module with the minimum set of required parameters.

Expand Down Expand Up @@ -261,7 +110,7 @@ param location = '<location>'
</details>
<p>

### Example 3: _Using encryption with Customer-Managed-Key_
### Example 2: _Using encryption with Customer-Managed-Key_

This instance deploys the module using Customer-Managed-Keys using a User-Assigned Identity to access the Customer-Managed-Key secret.

Expand Down Expand Up @@ -369,7 +218,7 @@ param publicNetworkAccess = 'Disabled'
</details>
<p>

### Example 4: _Using large parameter set_
### Example 3: _Using large parameter set_

This instance deploys the module with most of its features enabled.

Expand Down Expand Up @@ -770,7 +619,7 @@ param webhooks = [
</details>
<p>

### Example 5: _Using `scopeMaps` in parameter set_
### Example 4: _Using `scopeMaps` in parameter set_

This instance deploys the module with the scopeMaps feature.

Expand Down Expand Up @@ -868,7 +717,7 @@ param scopeMaps = [
</details>
<p>

### Example 6: _WAF-aligned_
### Example 5: _WAF-aligned_

This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework.

Expand Down
18 changes: 9 additions & 9 deletions avm/res/container-registry/registry/cache-rule/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,17 @@ Cache for Azure Container Registry (Preview) feature allows users to cache conta

| Parameter | Type | Description |
| :-- | :-- | :-- |
| [`credentialSetResourceId`](#parameter-credentialsetresourceid) | string | The resource ID of the credential store which is associated with the cache rule. |
| [`registryName`](#parameter-registryname) | string | The name of the parent registry. Required if the template is used in a standalone deployment. |
| [`sourceRepository`](#parameter-sourcerepository) | string | Source repository pulled from upstream. |

**Optional parameters**

| Parameter | Type | Description |
| :-- | :-- | :-- |
| [`credentialSetResourceId`](#parameter-credentialsetresourceid) | string | The resource ID of the credential store which is associated with the cache rule. |
| [`name`](#parameter-name) | string | The name of the cache rule. Will be derived from the source repository name if not defined. |
| [`targetRepository`](#parameter-targetrepository) | string | Target repository specified in docker pull command. E.g.: docker pull myregistry.azurecr.io/{targetRepository}:{tag}. |

### Parameter: `credentialSetResourceId`

The resource ID of the credential store which is associated with the cache rule.

- Required: Yes
- Type: string

### Parameter: `registryName`

The name of the parent registry. Required if the template is used in a standalone deployment.
Expand All @@ -52,13 +45,20 @@ Source repository pulled from upstream.
- Required: Yes
- Type: string

### Parameter: `credentialSetResourceId`

The resource ID of the credential store which is associated with the cache rule.

- Required: No
- Type: string

### Parameter: `name`

The name of the cache rule. Will be derived from the source repository name if not defined.

- Required: No
- Type: string
- Default: `[replace(replace(parameters('sourceRepository'), '/', '-'), '.', '-')]`
- Default: `[replace(replace(replace(parameters('sourceRepository'), '/', '-'), '.', '-'), '*', '')]`

### Parameter: `targetRepository`

Expand Down
6 changes: 3 additions & 3 deletions avm/res/container-registry/registry/cache-rule/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ metadata description = 'Cache for Azure Container Registry (Preview) feature all
param registryName string

@description('Optional. The name of the cache rule. Will be derived from the source repository name if not defined.')
param name string = replace(replace(sourceRepository, '/', '-'), '.', '-')
param name string = replace(replace(replace(sourceRepository, '/', '-'), '.', '-'), '*', '')

@description('Required. Source repository pulled from upstream.')
param sourceRepository string

@description('Optional. Target repository specified in docker pull command. E.g.: docker pull myregistry.azurecr.io/{targetRepository}:{tag}.')
param targetRepository string = sourceRepository

@description('Required. The resource ID of the credential store which is associated with the cache rule.')
param credentialSetResourceId string
@description('Optional. The resource ID of the credential store which is associated with the cache rule.')
param credentialSetResourceId string?

resource registry 'Microsoft.ContainerRegistry/registries@2023-06-01-preview' existing = {
name: registryName
Expand Down
20 changes: 14 additions & 6 deletions avm/res/container-registry/registry/cache-rule/main.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"languageVersion": "2.0",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.32.4.45862",
"templateHash": "10741185719400519703"
"templateHash": "10966757769768845548"
},
"name": "Container Registries Cache",
"description": "Cache for Azure Container Registry (Preview) feature allows users to cache container images in a private container registry. Cache for ACR, is a preview feature available in Basic, Standard, and Premium service tiers ([ref](https://learn.microsoft.com/en-us/azure/container-registry/tutorial-registry-cache))."
Expand All @@ -19,7 +20,7 @@
},
"name": {
"type": "string",
"defaultValue": "[replace(replace(parameters('sourceRepository'), '/', '-'), '.', '-')]",
"defaultValue": "[replace(replace(replace(parameters('sourceRepository'), '/', '-'), '.', '-'), '*', '')]",
"metadata": {
"description": "Optional. The name of the cache rule. Will be derived from the source repository name if not defined."
}
Expand All @@ -39,13 +40,20 @@
},
"credentialSetResourceId": {
"type": "string",
"nullable": true,
"metadata": {
"description": "Required. The resource ID of the credential store which is associated with the cache rule."
"description": "Optional. The resource ID of the credential store which is associated with the cache rule."
}
}
},
"resources": [
{
"resources": {
"registry": {
"existing": true,
"type": "Microsoft.ContainerRegistry/registries",
"apiVersion": "2023-06-01-preview",
"name": "[parameters('registryName')]"
},
"cacheRule": {
"type": "Microsoft.ContainerRegistry/registries/cacheRules",
"apiVersion": "2023-06-01-preview",
"name": "[format('{0}/{1}', parameters('registryName'), parameters('name'))]",
Expand All @@ -55,7 +63,7 @@
"credentialSetResourceId": "[parameters('credentialSetResourceId')]"
}
}
],
},
"outputs": {
"name": {
"type": "string",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,4 @@
"value": "[coalesce(tryGet(tryGet(reference('credentialSet', '2023-11-01-preview', 'full'), 'identity'), 'principalId'), '')]"
}
}
}
}
4 changes: 2 additions & 2 deletions avm/res/container-registry/registry/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -361,9 +361,9 @@ module registry_cacheRules 'cache-rule/main.bicep' = [
params: {
registryName: registry.name
sourceRepository: cacheRule.sourceRepository
name: cacheRule.?name ?? replace(replace(cacheRule.sourceRepository, '/', '-'), '.', '-')
name: cacheRule.?name ?? replace(replace(replace(cacheRule.sourceRepository, '/', '-'), '.', '-'), '*', '')
targetRepository: cacheRule.?targetRepository ?? cacheRule.sourceRepository
credentialSetResourceId: cacheRule.?credentialSetResourceId
credentialSetResourceId: !empty(cacheRule.?credentialSetResourceId) ? cacheRule.?credentialSetResourceId : null // Must only be set if condition is set
}
dependsOn: [
registry_credentialSets
Expand Down
Loading

0 comments on commit de31485

Please sign in to comment.