Loading...

New features added in the Azure Container Registry PowerShell module

New features added in the Azure Container Registry PowerShell module

While Azure Container Registry (ACR) is prevalent as an Azure service, the corresponding Az.ContainerRegistry Azure PowerShell module wasn’t fully featured. Sometimes, PowerShell users had to take advantage of the Az CLI. We want to allow PowerShell user to be able to fully manage container images. Starting with Az.ContainerRegistry version 2.2.1, we will gradually be rolling out new cmdlets and new parameters. In this release, you can now fully manage (Get-, Remove-, Update-) repositories, manifests, and tags with increased performance.

 

ACR overview

The graph below shows resources and the structure under an Azure container registry. We’ll dive into more details later in this article.

YaboHu_0-1617936659735.png

 

Authentication

 
 

After login into your Azure account in Azure-PowerShell with

 

PS:> Connect-AzAccount

 

You can now simply run

 

PS:> Connect-AzContainerRegistry -Name $RegistryName

 

Alternatively, you can also use service principal authentication

 

PS:> Connect-AzContainerRegistry -Name $RegistryName -UserName $ApplicationId -Password $ClientSecret

 

If you happened to have the registry admin user enabled

 

PS:> $secret = Get-AzContainerRegistryCredential -ResourceGroupName $RGName -Name $RegistryName PS:> Connect-AzContainerRegistry -Name $RegistryName -UserName $secret.UserName -Password $secret.Password

 

 

Repositories

A repository is a collection of container images or other artifacts in a registry that have the same name, but different tags. For example, the following three images are in the acr-helloworld repository:

  • acr-helloworld:latest
  • acr-helloworld:v1
  • acr-helloworld:v2

 

A JSON format repository could look like the following

 

{ "registry": "xxx.azurecr.io", "imageName": "test/busybox", "createdTime": "2021-02-02T04:11:14.4504049Z", "lastUpdateTime": "2021-02-02T05:02:14.2671834Z", "manifestCount": 1, "tagCount": 150, "changeableAttributes": { "deleteEnabled": true, "writeEnabled": true, "readEnabled": true, "listEnabled": true }

 

To get repositories via Az.ContainerRegistry

 

PS:> $repository = Get-AzContainerRegistryRepository -RegistryName xxx -Name test/busybox PS:> $repository Registry : xxx.azurecr.io ImageName : test/busybox CreatedTime : 2021-02-02T04:11:14.4504049Z LastUpdateTime : 2021-02-02T05:02:14.2671834Z ManifestCount : 1 TagCount : 150 ChangeableAttributes : Microsoft.Azure.Commands.ContainerRegistry.Models.PSChangeableAttribute PS:> $repository.ChangeableAttributes | ft DeleteEnabled WriteEnabled ListEnabled ReadEnabled ------------- ------------ ----------- ----------- True True True True

 

You can also list all repository names under your registry

 

PS:> Get-AzContainerRegistryRepository -RegistryName xxx alpine test/busybox test/busybox1 test/busybox10 test/busybox11 test/busybox12

 

To delete an existing repository

 

PS:> Update-AzContainerRegistryRepository -RegistryName xxx -Name test/busybox -DeleteEnabled $true PS:> Remove- AzContainerRegistryRepository -RegistryName xxx -Name test/busybox

 

 

Images

Grouped in a repository, each image or artifact is a read-only multi-layer snapshot of a Docker-compatible container.

An artifact can be represented as either one of

  • manifest
  • $repository_name:$tag

Manifest

Each image or other artifact pushed to a registry is associated with a JSON format manifest. The manifest, generated by the registry when the content is pushed, uniquely identifies the artifact.

 

"manifests": [ { "digest": "sha256:31a54a0cf86d7354788a8265f60ae6acb4b348a67efbcf7c1007dd3cf7af05ab", "imageSize": 764633, "createdTime": "2020-12-11T09:17:20.4959715Z", "lastUpdateTime": "2020-12-11T09:17:20.4959715Z", "architecture": "amd64", "os": "linux", "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "configMediaType": "application/vnd.docker.container.image.v1+json", "tags": [ "latest" ], "changeableAttributes": { "deleteEnabled": false, "writeEnabled": true, "readEnabled": true, "listEnabled": true } }

 

Manifests are identified by a unique SHA-256 hash, manifest digest. Each image or artifact, whether tagged or not, is identified by its digest. The digest value is unique even if the artifact's layer data is identical to that of another artifact. This mechanism is what allows you to repeatedly push identically tagged images to a registry. For example, you can repeatedly push “myimage:latest” to your registry without error because each image is identified by its unique digest.

 

Similarly, to get, list, update, or remove a manifest under a repository

 

PS:> Get-AzContainerRegistryManifest -RegistryName xxx -RepositoryName test/busybox50 -Name sha256:31a54a0cf86d7354788a8265f60ae6acb4b348a67efbcf7c1007dd3cf7af05ab Registry : xxx.azurecr.io ImageName : test/busybox50 Attributes : Microsoft.Azure.Commands.ContainerRegistry.Models.PSManifestAttributeBase PS:> Get-AzContainerRegistryManifest -RegistryName xxx -RepositoryName test/busybox50 PS:> Update-AzContainerRegistryManifest -RegistryName xxx -RepositoryName test/busybox50 -Manifest sha256:31a54a0cf86d7354788a8265f60ae6acb4b348a67efbcf7c1007dd3cf7af05ab -DeleteEnabled $true PS:> Remove-AzContainerRegistryManifest -RegistryName xxx -RepositoryName test/busybox50 -Manifest sha256:31a54a0cf86d7354788a8265f60ae6acb4b348a67efbcf7c1007dd3cf7af05ab

 

Please be aware that to delete a repository, all manifests under it should have

 

"deleteEnabled": true

 

 

Tag

Tags for an image or other artifact specifies its version. A single artifact within a repository can be assigned one or many tags, this artifact may also be "untagged." That is, you can delete all tags from an image, while the image's data (its layers) remain in the registry.

 

"tag": { "name": "latest", "digest": "sha256:31a54a0cf86d7354788a8265f60ae6acb4b348a67efbcf7c1007dd3cf7af05ab", "createdTime": "2020-12-11T09:17:20.6865195Z", "lastUpdateTime": "2020-12-11T09:17:20.6865195Z", "signed": false, "changeableAttributes": { "deleteEnabled": true, "writeEnabled": true, "readEnabled": true, "listEnabled": true } }

 

The repository plus a tag defines an image name. You can push and pull an image by specifying its name in the push or pull operation. The tag latest is used by default if you don't provide one in your Docker commands. As you can see in the ACR Overview section, “repository3:latest” and “repository3:v2” both represent the same image “artifact3”.

 

Similarly, to get, list, update,  or remove a tag for one artifact

 

PS:> Get-AzContainerRegistryTag -RegistryName xxx -RepositoryName test/busybox50 -Name latest Registry : xxx.azurecr.io ImageName : test/busybox50 Attributes : Microsoft.Azure.Commands.ContainerRegistry.Models.PSTagAttributeBase PS:> Get-AzContainerRegistryTag -RegistryName xxx -RepositoryName test/busybox50 PS:> Update-AzContainerRegistryTag -RegistryName xxx -RepositoryName test/busybox50 -Name latest -DeleteEnabled $true

 

Notice that after

 

PS:> Remove-AzContainerRegistryTag -RegistryName xxx -RepositoryName test/busybox50 -Name latest

 

The tag “latest” was removed (untagged), means you cannot find

“test/busybox50:latest”. In this repository anymore, but the corresponding artifact remained (get manifest)

 

PS:> $digest = (Get-AzContainerRegistryTag -RegistryName xxx -RepositoryName test/busybox50 -Name latest). Attributes.Digest PS:> Get-AzContainerRegistryManifest -RegistryName xxx -RepositoryName test/busybox50 -Name $digest Registry : xxx.azurecr.io ImageName : test/busybox50 Attributes : Microsoft.Azure.Commands.ContainerRegistry.Models.PSManifestAttributeBase

 

 

It’s also possible to update or delete a manifest by tag, it’s easier since it’s more recognizable to use a meaningful tag than series SHA256 hash code

 

PS:> Update-AzContainerRegistryManifest -RegistryName xxx -RepositoryName test/busybox50 -Tag latest -DeleteEnabled $true PS:> Remove-AzContainerRegistryManifest -RegistryName xxx -RepositoryName test/busybox50 -Tag latest

 

In this way, not only the tag, but the artifact itself would also be deleted.

 

Performance

We found there are performance issues in each repository, manifest, and tag manipulating operation. They were all relatively slow because ACR categorized each operation with different scopes.

A typical scope is in below format:

 

“$resource_type:$resource_name:$permission”

 

For example, to list all tags under repository “alpine”, the scope for this operation would be

 

“repository:alpine:metadata_read”

 

The specific token required for this request is assigned based on the exact scope.

 

For these kinds of operations, there will be 2 more extra HTTP requests sent out for token exchange before your actual operation.

 

HTTP Method: POST Absolute Uri: https://xxx.azurecr.io/oauth2/token HTTP Method: POST Absolute Uri: https://xxx.azurecr.io/oauth2/Exchange

 

To reduce these costly requests, we implemented a token cache in your current PowerShell session, it will cache all ACR tokens. For operations that used existing tokens (operations with same scope), the previously referenced token exchange won’t happen until tokens in the cache expire. For repetitive operations, the total number of requests is now only one instead of three.

 

You can clear this token cache in your current PowerShell session by running

 

PS:> Clear-AzContext

 

This cmdlet also terminates the login state for Azure. Remember to re-connect.

 

PS:> Connect-AzAccount

 

 

Conclusion & Feedback

With these features added, Az.ContainerRegistry is now much more usable. It's highly recommended to download the latest module at

https://www.powershellgallery.com/packages?q=az.containerregistry

and give a shot.

 

We also look forward to your feedback. Report issues at:

https://github.com/Azure/azure-powershell/issues

 

Yabo Hu
 Software Engineer
 Azure-PowerShell Team

Published on:

Learn more
Azure Tools Blog articles
Azure Tools Blog articles

Azure Tools Blog articles

Share post:

Related posts

Azure Developer CLI (azd) – November 2024

This post announces the November release of the Azure Developer CLI (`azd`). The post Azure Developer CLI (azd) – November 2024 appeared...

1 day ago

Microsoft Purview | Information Protection: Auto-labeling for Microsoft Azure Storage and Azure SQL

Microsoft Purview | Information Protection will soon offer Auto-labeling for Microsoft Azure Storage and Azure SQL, providing automatic l...

2 days ago

5 Proven Benefits of Moving Legacy Platforms to Azure Databricks

With evolving data demands, many organizations are finding that legacy platforms like Teradata, Hadoop, and Exadata no longer meet their needs...

3 days ago

November Patches for Azure DevOps Server

Today we are releasing patches that impact our self-hosted product, Azure DevOps Server. We strongly encourage and recommend that all customer...

3 days ago

Elevate Your Skills with Azure Cosmos DB: Must-Attend Sessions at Ignite 2024

Calling all Azure Cosmos DB enthusiasts: Join us at Microsoft Ignite 2024 to learn all about how we’re empowering the next wave of AI innovati...

3 days ago

Getting Started with Bicep: Simplifying Infrastructure as Code on Azure

Bicep is an Infrastructure as Code (IaC) language that allows you to declaratively define Azure resources, enabling automated and repeatable d...

5 days ago

How Azure AI Search powers RAG in ChatGPT and global scale apps

Millions of people use Azure AI Search every day without knowing it. You can enable your apps with the same search that enables retrieval-augm...

9 days ago
Stay up to date with latest Microsoft Dynamics 365 and Power Platform news!
* Yes, I agree to the privacy policy