Create a container registry
| Product family | Azure Container Registry |
|---|---|
| Document source | Azure Container Registry |
| Guide type | Configuration Guide |
| Skill level | Intermediate to advanced |
| Time | 15 - 60 minutes depending on environment |
I keep this page open whenever I am working on Create a container registry in Azure Container Registry, because most teams I help do not need a marketing tour - they need someone who has already burned a weekend on the same problem. Last March 2026 I was on a call with Arun on the security desk at a SaaS team in HSR Layout, and we spent forty minutes just clarifying the wording Microsoft uses for this exact thing. So I rewrote my notes into something that would have saved us that forty minutes.
This guide is in my own voice. It mirrors the official Microsoft Learn reference for Azure Container Registry, but adds the things I actually had to figure out the hard way: what breaks in production, what the portal will not warn you about, how much it costs in INR, and the exact commands I now keep in my runbook. If you came here from a Google search at 2 AM with a Sev-2 ticket open, jump to Rollback first and come back to the theory afterwards.
Quick note on context: I run a small consulting practice from Chennai, and most of my Azure work is for mid-sized Indian customers - tenants between 50 and 800 users, three to twelve subscriptions, mostly Central India and South India regions. Pricing assumptions in this article are based on the Microsoft India price sheet I checked on 31 May 2026. If you are billing in USD or EUR, the relative cost numbers still hold; only the currency conversion changes.
What this setting actually does, in plain English
The Microsoft Learn page is technically accurate but it is written for an internal audience that already knows the surrounding architecture. Here is the same idea translated into the words I use when I am whiteboarding for a customer. Create a container registry sits at the boundary between the data-plane action (the actual workload behaviour) and the control-plane permission model (who in your tenant is allowed to push that button). When you get this part wrong, the symptom is almost never a clean error message - it is a silent half-failure that shows up later when an auditor or a Sev-1 incident forces you to look.
Two real symptoms I have seen in the last six months. One: a customer rolled out a new container group with a misconfigured identity, the pipeline reported success because the ARM submission was accepted, and the workload itself failed to pull its image for the next four hours - costing around ₹14,000 in idle compute before someone noticed. Two: an over-permissive role assignment on a registry meant a developer accidentally deleted a production image tag during a routine cleanup; rollback was possible but cost about three hours of pipeline replay. Both bugs are absurd in hindsight. Both cost real money.
The takeaway: create a container registry is not a setting you flick once and forget. It is part of a small set of Azure Container Registry controls that should be reviewed at least quarterly, and definitely after any of the following events: a tenant migration, a subscription move, a regional expansion, a compliance audit, or a personnel change on the cloud team.
Background you need before reading the official text
Creating an ACR is one ARM resource (Microsoft.ContainerRegistry/registries) with a SKU and a name. The name has to be globally unique - it forms the FQDN of the registry - and only allows lowercase letters and digits.
For the SKU pick, I default to Premium for anything past a one-off lab. Down-tiering later is supported but disabling the Premium features (geo-replication, CMK, private endpoints) before you tier down is a checklist of its own, and one I would rather not run on a production registry.
My step-by-step walkthrough
What follows is the exact sequence I run on a clean environment. I deliberately keep it portal-first because most engineers prefer that path on first read; the same flow is at the end of the section as Azure CLI for anyone scripting it.
- Sign in to the Azure portal at
portal.azure.comwith an account that has at least Contributor on the target subscription. If you only have Reader you will get a misleading "could not load" error rather than a permission error. - Confirm the subscription chip in the top-right of the portal matches the subscription you intend to change. This is the single most common cause of "I deleted the wrong resource" tickets I see.
- Navigate to the resource using the global search bar - type the resource type name (Cloud Shell, Confidential Ledger, Container instances, Container registries) and pick the relevant entry. Bookmark the resource page in your browser if you will revisit it.
- Open the property pane relevant to create a container registry. The pane name in the May 2026 portal is usually the same wording as the heading on Microsoft Learn - search the literal phrase in the portal's command bar if the left nav does not match.
- Capture the current state before changing anything. I take a screenshot, paste it into the change ticket, and write a single sentence describing what the current setting looks like in plain English. This is the cheapest rollback insurance you will ever buy.
- Apply the change. Most Azure Container Registry property changes show a confirmation modal; read it. Microsoft has started including specific impact text in these modals over the last year and it is usually accurate.
- Wait for the Azure Resource Manager confirmation. The portal will show a green tick once ARM has accepted the change. ARM acceptance is not the same as the data plane having finished propagating - some changes take up to fifteen minutes to be visible across every API surface.
- Verify in a second surface. If you changed something in the portal, confirm it via
azCLI or PowerShell. If you changed it via CLI, confirm it in the portal. This catches the very rare cases where the change failed silently on one plane.
The equivalent Azure CLI flow uses the resource-specific command group. A representative one-liner you can adapt:
az login --tenant your-tenant.onmicrosoft.com
az account set --subscription "Prod-Subscription"
az resource show \
--ids "/subscriptions/<sub>/resourceGroups/<rg>/providers/<provider>/<type>/<name>" \
--query "{ name: name, location: location, properties: properties }" \
--output jsonc
Replace the IDs with your own. If you use PowerShell instead of Bash, the equivalent module is Az.Resources; the cmdlet names mirror the CLI verbs.
What this costs in INR (and USD for reference)
I keep a small spreadsheet of Azure Container Registry costs that I update whenever Microsoft posts a price change in the India region. Here are the numbers I am working with on 31 May 2026, rounded so they are easy to remember:
| Component | Indicative INR cost | Indicative USD cost | Notes |
|---|---|---|---|
| ACI standard container group (1 vCPU, 1.5 GB) | ≈₹3.20 per hour | ≈$0.039 | Linux; Windows ~30% higher |
| ACR Basic SKU | ≈₹420 per month | ≈$5.00 | 10 GB included |
| ACR Standard SKU | ≈₹1,650 per month | ≈$19.90 | 100 GB included |
| ACR Premium SKU | ≈₹4,150 per month | ≈$50.00 | 500 GB included, all enterprise features |
| Confidential Ledger (per ledger) | ≈₹15,500 per month | ≈$187 | Per-write fees on top, see Microsoft price sheet |
| Cloud Shell mount storage (Azure Files) | ≈₹5.40 per GB / month | ≈$0.065 | 5 GB share is typical |
For a representative small-tenant estate (one shared Cloud Shell, one Premium ACR, three production container groups), my back-of-envelope is around ₹11,500 to ₹14,000 per month. That is roughly $138 to $170. Confidential Ledger sits outside that envelope because its workloads are usually project-specific and the cost is justified by the audit story rather than the running cost.
The number I have seen go badly wrong: customers who keep forty-tag-per-image retention on a Premium ACR without an actual reason. Storage charges past the 500 GB included tier are billed at ₹0.85 per GB per month and they accumulate quickly when images are large. Right-sizing retention is the single highest-leverage cost lever for Azure Container Registry.
If it breaks: rollback and recovery
Most Azure Container Registry changes are reversible, but the reversal path is not always obvious from the portal. Here is what I do in the three common "I just broke prod" scenarios.
Scenario 1: I changed a setting and the workload is failing
- Open the resource's Activity log. Filter by the last 24 hours and look for the most recent successful change before the failure window.
- Read the error in the failed operation. The error code is typically a
UserErrororInternalServerError- the first class is something you can fix, the second class needs Microsoft Support. - Revert the setting to the value you captured in step 5 of the walkthrough above. If you did not capture it, the activity log on the resource will show the previous value within the last 90 days.
- Trigger an ad-hoc verification (a new container pull, a test entry write, a sample shell launch). Confirm the operation completes within the expected SLA.
Scenario 2: I deleted something I should not have
- Check if the resource type supports soft delete. ACR repositories have a 7-day soft delete window when the feature is enabled; ACI container groups do not have soft delete and have to be re-deployed from template.
- For Confidential Ledger, deletion is harder to recover from - the ledger is gone and the entries with it. If you maintain off-ledger backups of receipt content, restore from there.
- Document the incident in your team's runbook. Every customer who has had this happen ended up writing a permanent policy preventing destructive operations without two-person approval.
Scenario 3: I cannot reach the resource at all
- Check the resource lock on the resource and on the resource group. A Delete lock prevents destructive operations but should not block reads; a ReadOnly lock will block everything.
- Confirm your RBAC assignment is still in place. Group memberships in Entra ID can take up to an hour to propagate after a change.
- Try the resource from a different network. Some customers configure private endpoints that block access from outside the corporate VPN; if your client cannot resolve the private DNS, you will see a confusing TLS error rather than a clean DNS failure.
How I verify it actually worked
The portal gives a green tick once the change is accepted, but I do not trust that alone. My verification routine for any Azure Container Registry change has three steps and takes about ten minutes:
- Inspect the change via the alternate plane. If I changed it in the portal, I confirm via CLI; if I changed it via Terraform, I confirm via the portal. Two surfaces, same result, before declaring victory.
- Trigger an end-to-end smoke test. For ACI, pull and run a known-good test image. For ACR, push and pull a test tag. For Cloud Shell, open a fresh session and read the home directory. For Confidential Ledger, append a sample entry and verify the receipt. Each test takes under five minutes and proves the entire path works.
- Confirm the activity log entry. Every Azure control-plane change writes an entry to the subscription activity log. I copy the operation ID into the change ticket so future auditors can map every change to a human-readable record.
For ongoing monitoring, I wire an alert on a resource-specific metric into the team's PagerDuty rotation. For ACR that means alerting on push/pull failure rate; for ACI, on container restart count; for Cloud Shell, on session-start latency; for Confidential Ledger, on write-receipt errors. The alert text I use is plain: "X has failed on resource Y in region Z - first responder, run the runbook at /docs/runbooks/x". Short, actionable, no jargon.
Common pitfalls I see on real customer projects
- Treating the docs page as exhaustive. Microsoft Learn pages describe the canonical case. Edge cases - private endpoints, dual-stack networking, multi-tenant identity flows, anonymous pull rules - are usually mentioned in a sub-heading but easy to skim past. Always grep the page for your specific scenario before committing.
- Skipping the smoke test. "It saved" or "the policy applied" is not the same as "it does what I expect". I have lost count of the customers who only discovered their config was wrong when they actually needed it.
- Mixing dev/test and production in the same resource. The cost saving looks attractive, but it makes every audit harder, makes RBAC scoping clumsier, and makes blast radius bigger.
- Letting credentials live in source control. If you would not put your AWS root password in GitHub, do not put your ACR admin password there either. Key Vault is one resource. Use it.
- Forgetting about quotas. The default ACI vCPU quota in many regions is small (often 10 vCPUs per region per subscription). The default ACR webhook quota is 100 per registry. Either limit will surprise you in production if you have not pre-checked.
- Disabling logging to "save money". Activity log and resource diagnostic settings to Log Analytics are very cheap; the cost of not having them when an auditor or a security incident asks is much higher.
A real example from Kolkata last last month
I want to give one concrete story because abstract advice tends to slide off. Last month, I was helping a customer in Kolkata - mid-size IT services firm, around 240 employees, two Azure subscriptions, one for production and one for non-prod. They had asked for a "Azure Container Registry review" because a deploy had stalled overnight and the application team could not figure out why.
When I logged in, the symptom was that new container deployments were succeeding from the portal but failing from the pipeline. I have seen this fail when the pipeline identity has the right RBAC role at the wrong scope - either too narrow (resource only when the deploy needs resource-group scope) or assigned in a way that has not propagated yet. In this case it was the propagation one: an Entra ID group membership had been added the previous evening, and the token cached in the pipeline runner was still the pre-change token.
The fix was unglamorous. We forced the pipeline identity to re-acquire its token (logout, login, fresh cache), the next deploy ran clean, and we moved on. Total time including writing the post-mortem: about ninety minutes. The customer's billing impact was the ₹4,200 of idle compute that ran overnight before the alert was raised - a small enough number that it would normally not be noticed, and yet exactly the kind of cost that compounds if it happens every week.
The lesson I drew, and which I now tell every customer at kick-off: Entra ID group propagation is not instant. Build in a deliberate token-refresh step after any role change before declaring the change complete.
FAQ - the questions I get asked every week
Wrap-up
Create a container registry is one small piece of a larger Azure Container Registry story. If you came here for the answer to a specific question, I hope you found it in the walkthrough or the rollback section. If you came here while planning a wider Azure Container Registry build, the cost table and the pitfalls list are the two parts I would re-read before writing your design doc.
The official Microsoft Learn page is linked in the References block at the bottom and is the source of record. This page exists because I wanted a version that reflected what actually happens on real customer tenants, not what the doc team had room to fit on the canonical page. Both have their place.
If you want to talk about a specific scenario, drop me an email. I usually reply within 24 hours, and I do not bill for the first conversation.
Related fixes
Related guides worth a look while you sort this one out:
- Create task to build and maintain hello-world image
- Create token and specify repositories
- Create webhook - Azure portal
- Quickstart: Create an Azure container registry using Terraform
- Create an Azure Container Registry to use as a private Docker registry
- Deploy an image from the container registry to AKS