Skip to content

Commit ef04016

Browse files
johnsonshiclaude
andauthored
Add Managed Identity storage access mode support to ACR Transfer templates (#867)
- Add storageAccessMode parameter to ExportPipeline and ImportPipeline templates - Support both SasToken (default) and ManagedIdentity authentication modes - Conditionally create Key Vault access policies only for SasToken mode - Update API version to 2025-06-01-preview for all pipeline resources - Simplify README to reference official documentation at aka.ms/acr/transfer - Update parameter descriptions to clarify mode-specific requirements Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 6e15f09 commit ef04016

7 files changed

Lines changed: 83 additions & 17 deletions

File tree

docs/image-transfer/ExportPipelines/azuredeploy.json

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
2+
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
33
"contentVersion": "1.0.0.0",
44
"parameters": {
55
"location": {
@@ -56,6 +56,17 @@
5656
"description": "The list of all options configured for the pipeline."
5757
},
5858
"defaultValue": []
59+
},
60+
"storageAccessMode": {
61+
"type": "string",
62+
"defaultValue": "SasToken",
63+
"allowedValues": [
64+
"SasToken",
65+
"ManagedIdentity"
66+
],
67+
"metadata": {
68+
"description": "The storage access mode for the export pipeline. Use 'SasToken' to authenticate via a SAS token stored in Key Vault, or 'ManagedIdentity' to authenticate directly using an Entra managed identity."
69+
}
5970
}
6071
},
6172
"variables": {
@@ -78,29 +89,31 @@
7889
"type": "Microsoft.ContainerRegistry/registries/exportPipelines/",
7990
"name": "[concat(parameters('registryName'), '/', parameters('exportPipelineName'))]",
8091
"location": "[parameters('location')]",
81-
"apiVersion": "2019-12-01-preview",
92+
"apiVersion": "2025-06-01-preview",
8293
"identity": "[if(not(empty(parameters('userAssignedIdentity'))), variables('userIdentity'), variables('systemIdentity'))]",
8394
"properties": {
8495
"target": {
8596
"type": "[variables('targetType')]",
8697
"uri": "[parameters('targetUri')]",
87-
"keyVaultUri": "[concat(reference(resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName')), '2019-09-01').vaultUri, 'secrets/', parameters('sasTokenSecretName'))]"
98+
"keyVaultUri": "[concat(reference(resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName')), '2023-07-01').vaultUri, 'secrets/', parameters('sasTokenSecretName'))]",
99+
"storageAccessMode": "[parameters('storageAccessMode')]"
88100
},
89101
"options": "[parameters('options')]"
90102
}
91103
},
92104
{
105+
"condition": "[equals(parameters('storageAccessMode'), 'SasToken')]",
93106
"type": "Microsoft.KeyVault/vaults/accessPolicies",
94107
"name": "[concat(parameters('keyVaultName'), '/add')]",
95-
"apiVersion": "2019-09-01",
108+
"apiVersion": "2023-07-01",
96109
"dependsOn": [
97110
"[resourceId('Microsoft.ContainerRegistry/registries/exportPipelines', parameters('registryName'), parameters('exportPipelineName'))]"
98111
],
99112
"properties": {
100113
"accessPolicies": [
101114
{
102115
"tenantId": "[subscription().tenantId]",
103-
"objectId": "[if(not(empty(parameters('userAssignedIdentity'))), reference(parameters('userAssignedIdentity'), '2018-11-30').principalId, reference(resourceId('Microsoft.ContainerRegistry/registries/exportPipelines', parameters('registryName'), parameters('exportPipelineName')), '2019-12-01-preview', 'Full').identity.principalId)]",
116+
"objectId": "[if(not(empty(parameters('userAssignedIdentity'))), reference(parameters('userAssignedIdentity'), '2023-01-31').principalId, reference(resourceId('Microsoft.ContainerRegistry/registries/exportPipelines', parameters('registryName'), parameters('exportPipelineName')), '2025-06-01-preview', 'Full').identity.principalId)]",
104117
"permissions": {
105118
"secrets": "[variables('keyVaultSecretsPermissions')]"
106119
}

docs/image-transfer/ExportPipelines/azuredeploy.parameters.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
"OverwriteBlobs",
2323
"ContinueOnErrors"
2424
]
25+
},
26+
"storageAccessMode": {
27+
"value": "SasToken"
2528
}
2629
}
27-
}
30+
}

docs/image-transfer/ImportPipelines/azuredeploy.json

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
2+
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
33
"contentVersion": "1.0.0.0",
44
"parameters": {
55
"location": {
@@ -67,6 +67,17 @@
6767
"description": "The list of all options configured for the pipeline."
6868
},
6969
"defaultValue": []
70+
},
71+
"storageAccessMode": {
72+
"type": "string",
73+
"defaultValue": "SasToken",
74+
"allowedValues": [
75+
"SasToken",
76+
"ManagedIdentity"
77+
],
78+
"metadata": {
79+
"description": "The storage access mode for the import pipeline. Use 'SasToken' to authenticate via a SAS token stored in Key Vault, or 'ManagedIdentity' to authenticate directly using an Entra managed identity."
80+
}
7081
}
7182
},
7283
"variables": {
@@ -89,13 +100,14 @@
89100
"type": "Microsoft.ContainerRegistry/registries/importPipelines/",
90101
"name": "[concat(parameters('registryName'), '/', parameters('importPipelineName'))]",
91102
"location": "[parameters('location')]",
92-
"apiVersion": "2019-12-01-preview",
103+
"apiVersion": "2025-06-01-preview",
93104
"identity": "[if(not(empty(parameters('userAssignedIdentity'))), variables('userIdentity'), variables('systemIdentity'))]",
94105
"properties": {
95106
"source": {
96107
"type": "[variables('sourceType')]",
97108
"uri": "[parameters('sourceUri')]",
98-
"keyVaultUri": "[concat(reference(resourceId('Microsoft.KeyVault/vaults', parameters('KeyVaultName')), '2019-09-01').vaultUri, 'secrets/', parameters('sasTokenSecretName'))]"
109+
"keyVaultUri": "[concat(reference(resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName')), '2023-07-01').vaultUri, 'secrets/', parameters('sasTokenSecretName'))]",
110+
"storageAccessMode": "[parameters('storageAccessMode')]"
99111
},
100112
"trigger": {
101113
"sourceTrigger": {
@@ -106,17 +118,18 @@
106118
}
107119
},
108120
{
121+
"condition": "[equals(parameters('storageAccessMode'), 'SasToken')]",
109122
"type": "Microsoft.KeyVault/vaults/accessPolicies",
110123
"name": "[concat(parameters('keyVaultName'), '/add')]",
111-
"apiVersion": "2019-09-01",
124+
"apiVersion": "2023-07-01",
112125
"dependsOn": [
113126
"[resourceId('Microsoft.ContainerRegistry/registries/importPipelines', parameters('registryName'), parameters('importPipelineName'))]"
114127
],
115128
"properties": {
116129
"accessPolicies": [
117130
{
118131
"tenantId": "[subscription().tenantId]",
119-
"objectId": "[if(not(empty(parameters('userAssignedIdentity'))), reference(parameters('userAssignedIdentity'), '2018-11-30').principalId, reference(resourceId('Microsoft.ContainerRegistry/registries/importPipelines', parameters('registryName'), parameters('importPipelineName')), '2019-12-01-preview', 'Full').identity.principalId)]",
132+
"objectId": "[if(not(empty(parameters('userAssignedIdentity'))), reference(parameters('userAssignedIdentity'), '2023-01-31').principalId, reference(resourceId('Microsoft.ContainerRegistry/registries/importPipelines', parameters('registryName'), parameters('importPipelineName')), '2025-06-01-preview', 'Full').identity.principalId)]",
120133
"permissions": {
121134
"secrets": "[variables('keyVaultSecretsPermissions')]"
122135
}

docs/image-transfer/ImportPipelines/azuredeploy.parameters.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
"DeleteSourceBlobOnSuccess",
2424
"ContinueOnErrors"
2525
]
26+
},
27+
"storageAccessMode": {
28+
"value": "SasToken"
2629
}
2730
}
28-
}
31+
}

docs/image-transfer/PipelineRun/PipelineRun-Export/azuredeploy.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
2+
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
33
"contentVersion": "1.0.0.0",
44
"parameters": {
55
"location": {
@@ -75,7 +75,7 @@
7575
"type": "Microsoft.ContainerRegistry/registries/pipelineRuns/",
7676
"name": "[concat(parameters('registryName'), '/', parameters('pipelineRunName'))]",
7777
"location": "[parameters('location')]",
78-
"apiVersion": "2019-12-01-preview",
78+
"apiVersion": "2025-06-01-preview",
7979
"properties": {
8080
"request": {
8181
"pipelineResourceId": "[parameters('pipelineResourceId')]",

docs/image-transfer/PipelineRun/PipelineRun-Import/azuredeploy.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
2+
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
33
"contentVersion": "1.0.0.0",
44
"parameters": {
55
"location": {
@@ -75,7 +75,7 @@
7575
"type": "Microsoft.ContainerRegistry/registries/pipelineRuns/",
7676
"name": "[concat(parameters('registryName'), '/', parameters('pipelineRunName'))]",
7777
"location": "[parameters('location')]",
78-
"apiVersion": "2019-12-01-preview",
78+
"apiVersion": "2025-06-01-preview",
7979
"properties": {
8080
"request": {
8181
"pipelineResourceId": "[parameters('pipelineResourceId')]",

docs/image-transfer/README.md

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,35 @@
1-
See public docs: https://aka.ms/acr/transfer.
1+
# ACR Transfer - Sample ARM Templates
2+
3+
This directory contains Azure Resource Manager (ARM) templates for ACR Transfer, a feature for transferring container images and OCI artifacts between Azure Container Registries in disconnected environments.
4+
5+
## Templates
6+
7+
| Directory | Description |
8+
|-----------|-------------|
9+
| [ExportPipelines](./ExportPipelines) | Creates an ExportPipeline resource for exporting artifacts from a container registry to a storage account blob container. |
10+
| [ImportPipelines](./ImportPipelines) | Creates an ImportPipeline resource for importing artifacts from a storage account blob container into a container registry. |
11+
| [PipelineRun/PipelineRun-Export](./PipelineRun/PipelineRun-Export) | Creates a PipelineRun resource to trigger an export pipeline. |
12+
| [PipelineRun/PipelineRun-Import](./PipelineRun/PipelineRun-Import) | Creates a PipelineRun resource to trigger an import pipeline. |
13+
14+
## Documentation
15+
16+
For complete documentation including prerequisites, setup instructions, and usage examples, see:
17+
18+
**[ACR Transfer Documentation](https://aka.ms/acr/transfer)**
19+
20+
The documentation covers:
21+
22+
- What is ACR Transfer and how it works
23+
- Storage access modes (SAS Token vs Managed Identity)
24+
- Prerequisites and setup
25+
- Step-by-step guides for Azure CLI and ARM templates
26+
- Troubleshooting
27+
28+
## Quick Start
29+
30+
These templates require:
31+
32+
- Azure Container Registry Premium tier
33+
- Storage accounts with blob containers
34+
- API version `2025-06-01-preview` or later
35+
- For detailed prerequisites and instructions, refer to the [official documentation](https://aka.ms/acr/transfer)

0 commit comments

Comments
 (0)