Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,11 @@ Closes #<!-- issue number -->
- [ ] I have added an entry to `CHANGELOG.md` under `[Unreleased]`
- [ ] My code follows the project's style guidelines in `CONTRIBUTING.md`
- [ ] My commit messages follow [Conventional Commits](https://www.conventionalcommits.org/)

## Standards Compliance

- [ ] Follows [repo structure standard](https://azurelocal.cloud/standards/repo-structure) (required files present)
- [ ] Follows [naming conventions](https://azurelocal.cloud/standards/documentation/naming-conventions) (files, variables, resources)
- [ ] Uses [IIC fictional company](https://azurelocal.cloud/standards/fictional-company-policy) in all examples (never Contoso)
- [ ] Config changes validated against JSON Schema (if applicable)
- [ ] No hardcoded IPs, names, secrets, or environment-specific values in committed code
80 changes: 80 additions & 0 deletions .github/workflows/validate-repo-structure.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
name: Validate Repo Structure
on:
pull_request:
branches: [main]

jobs:
check-structure:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Check required root files
run: |
missing=0
for f in README.md CONTRIBUTING.md LICENSE CHANGELOG.md .gitignore; do
if [ ! -f "$f" ]; then
echo "::error::Missing required file: $f"
missing=$((missing + 1))
fi
done
if [ $missing -gt 0 ]; then
echo "::error::$missing required root file(s) missing"
exit 1
fi
echo "All required root files present"

- name: Check required directories
run: |
missing=0
for d in docs .github; do
if [ ! -d "$d" ]; then
echo "::error::Missing required directory: $d/"
missing=$((missing + 1))
fi
done
if [ $missing -gt 0 ]; then
echo "::error::$missing required directory(s) missing"
exit 1
fi
echo "All required directories present"

- name: Check PR template
run: |
if [ ! -f ".github/PULL_REQUEST_TEMPLATE.md" ]; then
echo "::error::Missing .github/PULL_REQUEST_TEMPLATE.md"
exit 1
fi
echo "PR template found"

- name: Check config structure (if config dir exists)
run: |
if [ -d "config" ]; then
missing=0
if [ ! -f "config/variables.example.yml" ]; then
echo "::error::Missing config/variables.example.yml"
missing=$((missing + 1))
fi
if [ ! -f "config/schema/variables.schema.json" ]; then
echo "::error::Missing config/schema/variables.schema.json"
missing=$((missing + 1))
fi
if [ $missing -gt 0 ]; then
exit 1
fi
echo "Config structure valid"
else
echo "No config/ directory — skipping config checks"
fi

- name: Check variable reference doc (if config dir exists)
run: |
if [ -d "config" ]; then
if [ ! -f "docs/reference/variables.md" ]; then
echo "::error::Missing docs/reference/variables.md (required when config/ exists)"
exit 1
fi
echo "Variable reference doc found"
else
echo "No config/ directory — skipping variable reference check"
fi
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ yarn-error.log*
# References
/product-azure-local-anywhere
/prodtech-docs-azl-toolkit
/project_management
9 changes: 9 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,15 @@ This starts a local development server at `http://localhost:3000/`.
- Place in `blog/YYYY-MM-DD-slug/` directory
- Include `authors` and `tags` frontmatter referencing `blog/authors.yml` and `blog/tags.yml`

## Standards

This project follows the **org-wide AzureLocal standards** documented at [azurelocal.cloud/standards](https://azurelocal.cloud/standards/). Key references:

- [Repository Structure](https://azurelocal.cloud/standards/repo-structure) — Required files, directories, labels, branch naming
- [Documentation Standards](https://azurelocal.cloud/standards/documentation/documentation-standards) — Writing and formatting
- [Naming Conventions](https://azurelocal.cloud/standards/documentation/naming-conventions) — Files, variables, resources
- [Fictional Company Policy](https://azurelocal.cloud/standards/fictional-company-policy) — Use IIC, never Contoso

## Code of Conduct

Be respectful and constructive. Keep discussions on-topic and collaborative.
8 changes: 6 additions & 2 deletions docs/implementation/03-key-inputs-and-variables.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -735,15 +735,19 @@ After gathering all required inputs and creating your infrastructure.yml:

---

*For questions about configuration variables or validation, refer to the Configuration Management Standard or contact the Azure Local Cloud documentation team.*
*For questions about configuration variables or validation, refer to the [Variable Management Standard](./04-variable-management-standard.mdx) or contact the Azure Local Cloud documentation team.*

:::tip Cross-Repository Standard
The **[Variable Management Standard](./04-variable-management-standard.mdx)** documents the org-wide pattern for `config/variables.example.yml`, JSON Schema validation, and `docs/reference/variables.md` across all five solution repositories.
:::

---

## Navigation

| Previous | Up | Next |
|----------|-----|------|
| [How to Use This Runbook](./02-how-to-use-this-runbook.mdx) | [Implementation Guide](./index.mdx) | [Prerequisites and Assumptions](./04-prerequisites-and-assumptions.mdx) |
| [How to Use This Runbook](./02-how-to-use-this-runbook.mdx) | [Implementation Guide](./index.mdx) | [Variable Management Standard](./04-variable-management-standard.mdx) |

---

Expand Down
2 changes: 1 addition & 1 deletion docs/implementation/04-prerequisites-and-assumptions.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "Prerequisites and Assumptions"
sidebar_label: "Prerequisites and Assumptions"
sidebar_position: 4
sidebar_position: 5
description: "Requirements and assumptions for Azure Local deployment."
category: "RUNBOOK"
scope: "Pre-deployment requirements"
Expand Down
201 changes: 201 additions & 0 deletions docs/implementation/04-variable-management-standard.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
---
title: "Variable Management Standard"
sidebar_label: "Variable Management Standard"
sidebar_position: 4
description: "Organization-wide variable naming, structure, and management standard for all AzureLocal solution repositories."
category: "STANDARD"
scope: "All AzureLocal solution repositories"
purpose: "Define the canonical variable management pattern used across the org"
author: "Azure Local Cloudnology Team"
created: 2026-03-17
updated: 2026-03-17
version: "1.0.0"
tags:
- azure-local
- configuration
- variables
- standards
keywords:
- variable management
- naming conventions
- variables.yml
- variables.example.yml
- schema validation
status: "approved"
---

# Variable Management Standard

[![Standard](https://img.shields.io/badge/Type-Standard-green?style=flat-square)](./index.mdx)
[![Azure](https://img.shields.io/badge/Platform-Azure_Local-0078D4?style=flat-square&logo=microsoftazure)](https://learn.microsoft.com/en-us/azure/azure-local/)

> **DOCUMENT CATEGORY**: Standard
> **SCOPE**: All AzureLocal solution repositories
> **PURPOSE**: Canonical variable naming, structure, and management pattern

**Status**: Active

---

## Overview

Every AzureLocal solution repository follows a **single, standardized pattern** for managing deployment variables. This ensures consistency, validation, and automation compatibility across all solutions.

**Core principle:** One config file, one schema, one reference doc — per repo.

| Artifact | Location | Purpose |
|----------|----------|---------|
| Example config | `config/variables.example.yml` | Template with placeholder values — copy to `variables.yml` |
| Active config | `config/variables.yml` | Environment-specific values (**never committed**) |
| JSON Schema | `config/schema/variables.schema.json` | Validation rules enforced by CI |
| Reference doc | `docs/reference/variables.md` | Human-readable variable catalog |

---

## Repository Matrix

| Repository | Config | Schema | Reference Doc | CI Workflow |
|-----------|--------|--------|---------------|------------|
| [azurelocal-toolkit](https://github.com/AzureLocal/azurelocal-toolkit) | [variables.example.yml](https://github.com/AzureLocal/azurelocal-toolkit/blob/main/config/variables.example.yml) | [schema](https://github.com/AzureLocal/azurelocal-toolkit/blob/main/config/schema/variables.schema.json) | [reference](https://github.com/AzureLocal/azurelocal-toolkit/blob/main/docs/reference/variables.md) | `validate-config.yml` |
| [azurelocal-sofs-fslogix](https://github.com/AzureLocal/azurelocal-sofs-fslogix) | [variables.example.yml](https://github.com/AzureLocal/azurelocal-sofs-fslogix/blob/main/config/variables.example.yml) | [schema](https://github.com/AzureLocal/azurelocal-sofs-fslogix/blob/main/config/schema/variables.schema.json) | [reference](https://github.com/AzureLocal/azurelocal-sofs-fslogix/blob/main/docs/reference/variables.md) | `validate-config.yml` |
| [aurelocal-avd](https://github.com/AzureLocal/aurelocal-avd) | [variables.example.yml](https://github.com/AzureLocal/aurelocal-avd/blob/main/config/variables.example.yml) | [schema](https://github.com/AzureLocal/aurelocal-avd/blob/main/config/schema/variables.schema.json) | [reference](https://github.com/AzureLocal/aurelocal-avd/blob/main/docs/reference/variables.md) | `validate-config.yml` |
| [azurelocal-loadtools](https://github.com/AzureLocal/azurelocal-loadtools) | [variables.example.yml](https://github.com/AzureLocal/azurelocal-loadtools/blob/main/config/variables.example.yml) | [schema](https://github.com/AzureLocal/azurelocal-loadtools/blob/main/config/schema/variables.schema.json) | [reference](https://github.com/AzureLocal/azurelocal-loadtools/blob/main/docs/reference/variables.md) | `validate-config.yml` |
| [azurelocal-vm-conversion-toolkit](https://github.com/AzureLocal/azurelocal-vm-conversion-toolkit) | [variables.example.yml](https://github.com/AzureLocal/azurelocal-vm-conversion-toolkit/blob/main/config/variables.example.yml) | [schema](https://github.com/AzureLocal/azurelocal-vm-conversion-toolkit/blob/main/config/schema/variables.schema.json) | [reference](https://github.com/AzureLocal/azurelocal-vm-conversion-toolkit/blob/main/docs/reference/variables.md) | `validate-config.yml` |

---

## Directory Structure

Every repository follows this layout:

```
repo-root/
├── config/
│ ├── variables.example.yml # Committed — template
│ ├── variables.yml # .gitignored — your values
│ └── schema/
│ └── variables.schema.json # JSON Schema for CI validation
├── docs/
│ └── reference/
│ └── variables.md # Human-readable variable catalog
└── .github/
└── workflows/
└── validate-config.yml # CI: validates example against schema
```

---

## Naming Conventions

### File Naming

| File | Name | Notes |
|------|------|-------|
| Example config | `variables.example.yml` | Always `.example.yml`, never `.template.yml` |
| Active config | `variables.yml` | Never committed |
| Schema | `variables.schema.json` | Draft 2020-12 JSON Schema |
| Reference doc | `variables.md` | Always at `docs/reference/variables.md` |

### Variable Naming

| Scope | Convention | Example |
|-------|-----------|---------|
| Top-level sections | `snake_case` | `azure_local`, `session_hosts` |
| Keys within sections | `snake_case` | `subscription_id`, `cluster_name` |
| Booleans | Descriptive name | `enable_real_time: true` |
| Secrets | `keyvault://` URI | `keyvault://kv-name/secret-name` |
| Azure resource IDs | Full ARM path | `/subscriptions/.../providers/...` |
| Enum values | `snake_case` | `auth_method: "managed_identity"` |

### Section Organization

Each `variables.example.yml` is organized into **logical sections** separated by comment headers:

```yaml
# =============================================================================
# Section Name
# =============================================================================
section_name:
key: "value"
```

Common sections across repos include:
- **azure** — Subscription, tenant, resource group, location
- **keyvault** — Key Vault name and auth method
- **azure_local** — Cluster-specific configuration
- **tags** — Resource tagging (present in every repo)

Solution-specific sections are documented in each repo's `docs/reference/variables.md`.

---

## Secret Management

Secrets are **never** stored in plaintext in `variables.yml`. All sensitive values use the `keyvault://` URI format:

```yaml
credentials:
admin_password: "keyvault://kv-mysite/admin-password"
```

**Resolution flow:**

1. Tool parses the URI → vault name + secret name
2. Tool calls `az keyvault secret show` (or SDK equivalent)
3. Secret value is passed directly — never written to disk

Repos that use Key Vault references: **toolkit**, **sofs-fslogix**, **avd**, **loadtools**

---

## Schema Validation

Every repo includes a JSON Schema that validates the structure of `variables.example.yml`. The CI workflow runs on every PR and push to `config/**`:

```yaml
# .github/workflows/validate-config.yml
name: Validate Config
on:
push:
paths: ['config/**']
pull_request:
paths: ['config/**']

jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- run: pip install pyyaml jsonschema
- run: |
python -c "
import yaml, jsonschema, sys
schema = yaml.safe_load(open('config/schema/variables.schema.json'))
data = yaml.safe_load(open('config/variables.example.yml'))
jsonschema.validate(data, schema)
print('Validation PASSED')
"
```

---

## Getting Started with a New Repo

When adding a new solution repository to the org:

1. **Create** `config/variables.example.yml` with solution-specific sections
2. **Create** `config/schema/variables.schema.json` with Draft 2020-12 JSON Schema
3. **Create** `docs/reference/variables.md` documenting every variable with type, required, description, and default
4. **Add** `.github/workflows/validate-config.yml` (copy from any existing repo)
5. **Add** `config/variables.yml` to `.gitignore`
6. **Update this page** with a link in the Repository Matrix table

---

## Related Documentation

- **[Key Inputs and Variables](./03-key-inputs-and-variables.mdx)** — How the toolkit uses `infrastructure.yml` and `master-registry.yaml`
- **[Naming Standards](../planning/01-naming-standards.mdx)** — Azure resource naming conventions
2 changes: 1 addition & 1 deletion docs/implementation/05-authentication.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "Authentication Methods"
sidebar_label: "Authentication"
sidebar_position: 5
sidebar_position: 6
description: "Authentication options for Azure Local deployment — Azure PowerShell and Azure CLI session setup."
category: "RUNBOOK"
scope: "Azure authentication for deployment scripts"
Expand Down
Loading
Loading