Skip to content
| Marketplace
Sign in
Azure DevOps>Azure Pipelines>Azure Naming Convention
Azure Naming Convention

Azure Naming Convention

JinThakur

|
1 install
| (1) | Free
Generates, validates, and registers Azure resource names against a governed naming standard, right inside Azure DevOps.
Get it free

Azure Naming Convention — Azure DevOps Extension

An Azure DevOps hub extension that implements an Azure Resource Naming Convention document as a working tool inside Azure DevOps: users fill in a form, click Generate, and get a name that's validated against the standard, checked for duplicates, and optionally recorded as a work item and/or used to kick off a pipeline.

It shows up as a new "Naming Convention" entry in the project-level left nav (alongside Boards, Repos, Pipelines, etc.) in any project where it's installed.

What it does

Capability How
Generate names src/generator.ts builds the name from the Section 2 pattern (type-workload-env-region-instance), or the Section 5 concatenated pattern for restricted types (Storage Account, Container Registry, Key Vault).
Validate against the standard Same module checks length limits, allowed character sets, and required components, and flags anything the standard doesn't allow.
Check for duplicates Every generated name is checked against, and saved to, an Extension Data Service collection (generatedResourceNames) — Azure DevOps' built-in per-organization document store for extensions. No external database needed.
Store results Saved to Extension Data by default. Optionally also creates a work item (via WorkItemTrackingRestClient) so the request flows through your board, and/or commits a JSON registry file to a repo (via GitRestClient.createPush, see adoService.ts::commitRegistryFile — wire this into the UI if you want a versioned file instead of/alongside Extension Data).
Trigger pipelines Optionally queues a build (via BuildRestClient.queueBuild) after a name is saved, passing the generated name and its components as pipeline parameters.
Organization name setting An in-app "Set/Edit organization name" control lets any org using the extension label the header with their own name (e.g. "Contoso"), stored in the same shared Extension Data scope. Blank by default so it's neutral out of the box.

Project layout

vss-extension.json        Extension manifest — the hub contribution, scopes, icons
src/namingData.ts          Resource type / workload / environment / region tables
                            (kept in sync with the naming convention document)
src/generator.ts            Pure name-generation + validation logic (unit-testable, no SDK deps)
src/adoService.ts           All Azure DevOps SDK/REST integration:
                             Extension Data (storage + duplicate check), work items, git push, pipelines
src/Hub.tsx / Hub.html / Hub.css   The React form + host page
webpack.config.js / tsconfig.json  Build config
img/                        Extension + hub icons (placeholders — replace with your own branding)

Prerequisites

  • Node.js 18+ and npm
  • An Azure DevOps organization where you have permission to upload/install extensions (for a private org-only install you don't need a Marketplace publisher account, just "Manage Extensions" permission)
  • tfx-cli (included as a dev dependency; also installable globally with npm i -g tfx-cli)

Build

npm install
npm run build        # webpack → dist/Hub.js, dist/Hub.html

Package and publish (public Marketplace listing)

The manifest already has "public": true and "publisher": "JinThakur".

  1. Replace img/extension-icon.png and img/hub-icon.png with real branded icons (128×128 and roughly 32×32 respectively) — the placeholders are not publish-ready.
  2. Package it:
    npm install
    npm run build
    npx tfx extension create --manifest-globs vss-extension.json
    
    This produces JinThakur.azure-naming-convention-1.0.0.vsix.
  3. Go to https://marketplace.visualstudio.com/manage/publishers/JinThakur, select New extension → Azure DevOps, and upload the .vsix. It uploads as private by default regardless of the manifest's public flag — visible only to you until you explicitly publish it.
  4. To make it publicly listed: select the extension, choose Publish, and confirm. Microsoft runs a virus scan first; the listing goes live once that clears.
  5. Anyone can then find it on the Marketplace and click Get it free to install it into their own Azure DevOps organization — no sharing step needed once it's public.

If you'd rather keep it private to a specific org instead, skip step 4 and use Share/Unshare to grant that org access, same as before.

Required permissions

The manifest requests these scopes (vss-extension.json → scopes):

  • vso.extension.data_write — read/write the naming registry (Extension Data). Low risk: sandboxed to this extension's own storage, not flagged by Azure DevOps' install-time warning.
  • vso.work_write — create the optional tracking work item. Moderate: can create/edit work items, but can't touch source or execution.
  • vso.build_execute — queue a pipeline after saving. High privilege — Azure DevOps flags this because it can run pipelines anywhere in the org, and pipelines often hold secrets/service connections. Remove this scope and the "Queue a pipeline after saving" code path in Hub.tsx/adoService.ts if you don't need that feature; it's the single biggest thing you can cut to shrink the install warning. See "Why the pipeline permission is needed" below for the full justification.

Why the pipeline permission is needed

The "Queue a pipeline after saving" checkbox is what actually uses vso.build_execute. It exists to close the gap between naming a resource and provisioning it:

  • Without it, generating and saving a name is the end of the tool's job — someone still has to go start the deployment pipeline by hand, manually pasting the generated name into whatever "resource name" parameter that pipeline expects.
  • With it, adoService.ts::queuePipeline() calls BuildRestClient.queueBuild() immediately after a successful save, passing the generated name(s) and project name through as pipeline parameters (resourceNames, project). A Bicep/ Terraform/ARM pipeline that accepts those as inputs can provision the resource under the exact name the standard just generated, with no manual copy-paste step and no chance of the deployed name drifting from the registered one.

That capability is inherently broad: Azure DevOps has no "queue this one specific pipeline" scope, only vso.build_execute, which grants queue/read rights across every pipeline in every project the extension is installed into. That's why it's flagged as high-privilege on install — it's not a sign of unnecessary or excessive access, it's the smallest scope Azure DevOps offers for "let this extension start a build," and this extension only calls it when the checkbox is explicitly ticked and a pipeline ID is explicitly entered. It never queues anything on its own.

If your workflow doesn't chain naming directly into provisioning — e.g. someone reviews and starts deployments manually, or your pipelines are triggered by a different mechanism (a merge to a repo, a scheduled run) — this feature adds risk without adding value for you, and removing it is the right call. See "Minimizing the high privilege install warning" below for exactly what to remove.

vso.code_write is intentionally not requested by default — the only thing that would use it, commitRegistryFile() in adoService.ts, isn't called from the UI. Only add it back if you actually wire that function in; requesting a scope nothing uses just adds risk surface for no benefit.

Minimizing the "high privilege" install warning

Azure DevOps shows that warning whenever a manifest requests a broad, org-wide execute or write scope — it's standard for any extension in this category, not a sign of a problem with the code. To get rid of it entirely, remove vso.build_execute and disable pipeline-triggering (the only feature that needs it); what's left (vso.extension.data_write, vso.work_write) doesn't trigger the warning. If you want to keep pipeline-triggering, the warning is unavoidable — narrow it only by being deliberate about which orgs/projects you install into, and by keeping this README's scope table current so an installing admin can see exactly why each scope is requested rather than trusting a blanket "trust the publisher" prompt.

Keeping this in sync with the naming convention document

src/namingData.ts is a direct transcription of Sections 3, 4.1–4.3, and 5 of the Azure Resource Naming Convention document. When that document is revised (new resource type, region, or workload code), update this file to match.

Extending

  • Repo-based registry instead of/alongside Extension Data: call commitRegistryFile() from Hub.tsx after saveToRegistry() to also version the registry as a JSON file in a repo — useful if a Bicep/Terraform pipeline should read the approved name list as an input.
  • Custom work item type: createTrackingWorkItem() defaults to Task; pass a process-specific type (e.g. an "EA Intake" type) as the second argument.
  • Org-wide vs. project-scoped registry: getDataManager() currently scopes to the extension at the org (user) level via the default Extension Data behavior. If you need duplicate-checking to span multiple organizations, move the registry to an external store (e.g. Azure Table Storage) behind a small API and swap the calls in adoService.ts — generator.ts and the UI don't need to change.

Verified

npm install && npm run build was run against this exact project during creation and compiles cleanly (only non-blocking "bundle size" performance warnings from webpack, expected given the bundled Azure DevOps REST clients).

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft