# ADR-003: Azure resource naming

Date: 2026-08-31
Status: Accepted (standard approved by the author the same day)

## In plain words

This page sets how every cloud resource is named: type first, project second, in capitals wherever Azure allows, for example RG-THEYARD-SS for the resource group. A fixed suffix (uniqueString) is added only where a name must be unique across all of Azure, and no name carries a region.

What that is worth: a developer can tell what a resource is from its name, and the organization can move to another region without renaming anything, which matters because Azure resources cannot be renamed, only recreated.

## The pattern

TYPE-WORKLOAD-OWNER(-SUFFIX), uppercase. Rendered for this project:

| Resource            | Name                          |
|---------------------|-------------------------------|
| Resource group      | RG-THEYARD-SS                 |
| App Service plan    | PLAN-THEYARD-SS               |
| Web app             | APP-THEYARD-SS-(SUFFIX)       |
| Front Door profile  | FD-THEYARD-SS                 |
| Container registry  | crtheyardss(suffix)           |
| Front Door endpoint | fde-theyard-ss-(suffix)       |
| Container Apps env  | cae-theyard-ss                |
| Container App       | ca-theyard-ss-(suffix)        |

## The rules

1. Type prefixes in the Cloud Adoption Framework style: RG, PLAN, APP, CR, FD,
   FDE, CAE, CA.
2. Uppercase with hyphens wherever Azure allows it. Platform-forced exceptions
   go lowercase and are limited to two classes: the container registry
   (alphanumeric only, DNS-bound) and hostname-bearing names (Front Door
   endpoints, Container Apps resources), because DNS lowercases them anyway.
3. The workload token (THEYARD) sits second; the owner tag (SS) third.
4. A deterministic uniqueString(resourceGroup().id) suffix appears ONLY on
   names that need global uniqueness. Internal names stay clean.
5. No region and no environment token today. One environment exists, and
   region-free names are what allowed same-day region fallbacks without a
   single rename; that was exercised repeatedly on day one. When a second
   environment appears, an environment token slots in before the suffix.

## Consequences

Azure resources cannot be renamed, only recreated, so this standard applies
from creation; anything born before it gets recreated, which the one-command
teardown makes cheap. Browser-visible hostnames render lowercase regardless of
the resource name casing.

## Where it sits

Neither the onion nor SOLID reaches this record, which is a naming standard for Azure resources written into the Bicep template and the pipeline.

## Files

- [`infra/main.bicep`](https://github.com/SteveStout/TheYard/blob/main/infra/main.bicep): the pattern as code, `upperTag` for the
  uppercase names and `acrName` for the registry's forced-lowercase
  exception, shown live below.
- [`infra/aci-theyard.yaml`](https://github.com/SteveStout/TheYard/blob/main/infra/aci-theyard.yaml): the names in use today, `aci-theyard-ss`,
  `id-theyard-ss`, the registry and the DNS label.
- [`.github/workflows/deploy.yml`](https://github.com/SteveStout/TheYard/blob/main/.github/workflows/deploy.yml): the same names as workflow
  variables (`REGISTRY_NAME`, `RG`), so the pipeline and the template agree.

```bicep
// Steve's naming rule in three lines: UPPERCASE for the things people read in
// the portal, lowercase for the ones Azure requires to be (a registry name must
// be lowercase alphanumeric), and a deterministic suffix from the resource
// group id so a name is unique without being random (ADR-003).
var suffix = uniqueString(resourceGroup().id)
var upperTag = toUpper('${baseName}-${ownerTag}')
var acrName = toLower('cr${baseName}${ownerTag}${suffix}')
```
*Live from [`infra/main.bicep`](https://github.com/SteveStout/TheYard/blob/1d6b50b/infra/main.bicep#L67-L73), region `naming`, read from this build at 1d6b50b.*
