Authoring a new template variant¶
Adding a new variant to templates/ is an ADR-level change. This page covers when to do it, the mechanical steps, and the contract the new variant must satisfy.
When to add a variant¶
| Signal | Add a variant? |
|---|---|
| One repo has a slightly different shape | No — handle in that repo |
| Two repos share a new shape not covered by existing variants | Probably yes — write an ADR |
| Future planned repos will share this shape | Yes |
| The shape exists but variant would duplicate an existing one | No — extend the existing variant |
Two-consumer rule (per ADR-0003 philosophy): a variant is worth centralising only when at least two distinct consumers need it.
ADR-first¶
- File an issue describing the proposed variant.
- Draft an ADR in
decisions/covering:- What the variant is for (consumer shape).
- What required files it adds beyond
_common. - What tokens it uses (new ones, if any).
- Which reusable workflows it expects.
- What's explicitly out of scope.
- Name at least one near-term consumer that will adopt it on day one.
- Land the ADR; then ship the variant.
Mechanical steps¶
1. Create the variant directory¶
templates/<new-variant-name>/
├── .github/workflows/
│ └── deploy-docs.yml # almost always present
├── ... variant-specific files ...
├── mkdocs.yml
└── README.md
Name convention: kebab-case, descriptive — e.g., ai-service, aks-workload.
2. Author token-substituted files¶
Use existing tokens where possible:
{{REPO_NAME}},{{MODULE_NAME}},{{DESCRIPTION}},{{REPO_TYPE}},{{YEAR}},{{AUDIT_DATE}},{{MODULE_GUID}},{{ID_PREFIX}},{{MAPROOM}},{{WORKFLOWS_ADOPTED}}
Only introduce a new token if existing ones don't cover the need. A new token is a breaking change to New-AzureLocalRepo.ps1 — requires the ADR to mention it.
3. Update New-AzureLocalRepo.ps1¶
Add the new variant to the -Type ValidateSet:
[ValidateSet('ps-module', 'ts-web-app', 'iac-solution', 'migration-runbook', 'training-site', 'new-variant-name')]
[string]$Type
If the variant introduces new token resolution logic (e.g., variant-specific default for {{WORKFLOWS_ADOPTED}}), add it in the resolver block.
4. Add docs¶
- New file:
docs/templates/<new-variant-name>.md— follow the pattern of existing variant pages (ps-module is a good reference) - Update
docs/templates/index.mdvariant table - Update
docs/templates/overview.mdcomparison table - Update
mkdocs.ymlnav
5. Add a test case¶
Run New-AzureLocalRepo.ps1 -Type <new-variant> -Name azurelocal-testvariant -Description "test" -DryRun and confirm:
- Temp scaffold has the expected file tree
- Tokens are fully substituted (no
{{X}}remaining in any file) - Filename tokens are renamed
6. Open PR¶
Commit message:
ADR lands in the same PR (or one immediately prior).
What the variant must satisfy¶
- All 5 canonical required files (
CHANGELOG.md,mkdocs.yml,deploy-docs.yml,drift-check.yml,.azurelocal-platform.yml) present in the merged output - At least the 4
_commonworkflows (add-to-project, drift-check, release-please, validate-repo-structure) — merged automatically, don't duplicate README.mdwith the AzureLocal Platform badgeSTANDARDS.mdstub — merged from_common
Test-RepoConformance will verify these on every new repo scaffolded with the variant.
What the variant must NOT do¶
- Introduce a new required workflow without updating
drift-checkto know about it (drift-check's list of required files is authoritative; additions belong there in the same PR). - Ship files that duplicate
_commoncontent with drift — that defeats the override model. - Add platform-repo-scoped helpers (those go in
modules/powershell/orrepo-management/org-scripts/).
Long-term maintenance¶
Once a variant exists, its file set is part of the public contract. Changes follow normal versioning:
- Add a new file → minor bump
- Remove or rename a file → major bump (existing scaffolded repos don't re-scaffold, but
Sync-CommonFiles.ps1behaviour may change) - Change token semantics → major bump
Example — adding aks-workload¶
- ADR in
decisions/NNNN-aks-workload-variant.md. - Create
templates/aks-workload/withci-aks.yml(new reusable workflow),mkdocs.yml,README.md, possibly ahelm/folder. - Define
{{WORKFLOWS_ADOPTED}}default:"ci-aks, drift-check, release-please". - Update
New-AzureLocalRepo.ps1-Typeenum. - Docs:
docs/templates/aks-workload.md, update index and overview. - Consumer adoption:
azurelocal-akspicks it up in the same release.