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
36 changes: 36 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
## Summary

<!-- What does this PR do? One paragraph max. -->

## Related Issue

Closes #<!-- issue number -->

## Type of Change

- [ ] Bug fix
- [ ] New feature / enhancement
- [ ] Documentation update
- [ ] Infrastructure / CI change
- [ ] Refactor (no functional change)
- [ ] Other:

## Testing Done

<!-- How did you test this? What environment, configuration, and scenarios? -->

## Checklist

- [ ] I have tested this in a non-production environment
- [ ] I have updated the README or `docs/` if usage changed
- [ ] 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
72 changes: 72 additions & 0 deletions .github/workflows/validate-config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# =============================================================================
# validate-config.yml — Validate config files against schema
# =============================================================================
# Triggered on PRs and pushes that touch config/ or this workflow.
# Validates YAML syntax and JSON Schema compliance.
# =============================================================================

name: Validate Configuration

on:
push:
branches: [main]
paths:
- 'config/**'
- '.github/workflows/validate-config.yml'
pull_request:
branches: [main]
paths:
- 'config/**'
workflow_dispatch:

permissions:
contents: read

jobs:
validate:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Install dependencies
run: pip install pyyaml jsonschema

- name: Validate infrastructure.yml against schema
run: |
python3 -c "
import yaml, json, sys
from jsonschema import validate, ValidationError

with open('config/infrastructure.yml') as f:
data = yaml.safe_load(f)

with open('config/schema/variables.schema.json') as f:
schema = json.load(f)

try:
validate(instance=data, schema=schema)
print('✅ config/infrastructure.yml passes schema validation')
except ValidationError as e:
print(f'❌ Schema validation failed: {e.message}')
print(f' Path: {\" > \".join(str(p) for p in e.absolute_path)}')
sys.exit(1)
"

- name: Validate variables.example.yml syntax
run: |
python3 -c "
import yaml, sys
with open('config/variables.example.yml') as f:
data = yaml.safe_load(f)
if data is None:
print('❌ variables.example.yml is empty')
sys.exit(1)
print('✅ config/variables.example.yml is valid YAML')
"
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"
Comment on lines +50 to +59
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)"
Comment on lines +73 to +74
exit 1
fi
echo "Variable reference doc found"
else
echo "No config/ directory — skipping variable reference check"
fi
7 changes: 4 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ ansible/.vault_pass
!.env.example

# Central config (actual values — never commit)
configs/infrastructure-*.yml
!configs/infrastructure.yml
configs/credentials/
config/infrastructure-*.yml
!config/infrastructure.yml
config/variables.yml
config/credentials/

# Log files (keep the directory via .gitkeep)
logs/**
Expand Down
10 changes: 10 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,16 @@ Examples:
- Test against a real Azure Local environment before submitting
- Describe your test environment and results in the PR

## 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
- [Scripting Standards](https://azurelocal.cloud/standards/scripting/scripting-standards) — PowerShell conventions
- [Documentation Standards](https://azurelocal.cloud/standards/documentation/documentation-standards) — Writing and formatting
- [Variable Management](https://azurelocal.cloud/docs/implementation/04-variable-management-standard) — Config file patterns
- [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.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Platform automation toolkit for **Azure Local** — deployment scripts, validati
| Directory | Description |
|-----------|-------------|
| **[scripts/](https://github.com/AzureLocal/azurelocal-toolkit/tree/main/scripts)** | 200+ PowerShell scripts organized by deployment stage (02–08), plus common modules, validation, handover, lifecycle, and tools |
| **[configs/](https://github.com/AzureLocal/azurelocal-toolkit/tree/main/configs)** | Master infrastructure config template, ARM templates, and variable registry |
| **[config/](https://github.com/AzureLocal/azurelocal-toolkit/tree/main/configs)** | Master infrastructure config template, ARM templates, and variable registry |
| **[tools/](https://github.com/AzureLocal/azurelocal-toolkit/tree/main/tools)** | Planning utilities (S2D capacity calculator) |
| **[tests/](https://github.com/AzureLocal/azurelocal-toolkit/tree/main/tests)** | Test infrastructure (future Pester suites) |

Expand All @@ -34,8 +34,8 @@ The toolkit follows a structured deployment lifecycle:

The toolkit uses a config-driven approach:

- **`configs/infrastructure.yml`** — Master configuration template with 14 sections covering Azure tenant, networking, compute, storage, security, and more
- **`configs/variables.template.yml`** — Azure Local-specific variables for deployment
- **`config/infrastructure.yml`** — Master configuration template with 14 sections covering Azure tenant, networking, compute, storage, security, and more
- **`config/variables.example.yml`** — Azure Local-specific variables for deployment

## Related Repositories

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
- storageNetworkList (from network_intents with storage_networks)

.PARAMETER ConfigPath
Path to the infrastructure YAML file. Defaults to configs/infrastructure.yml
Path to the infrastructure YAML file. Defaults to config/infrastructure.yml
relative to the repository root.

.PARAMETER AuthType
Expand All @@ -35,11 +35,11 @@
Show what would be generated without writing the file.

.EXAMPLE
.\Generate-AzureLocal-Parameters.ps1 -ConfigPath "configs/infrastructure-azl-demo.yml" -AuthType AD
.\Generate-AzureLocal-Parameters.ps1 -ConfigPath "config/infrastructure-azl-demo.yml" -AuthType AD
Generates AD parameters file from the azl-demo config.

.EXAMPLE
.\Generate-AzureLocal-Parameters.ps1 -ConfigPath "configs/infrastructure-azl-lab.yml" -AuthType LocalIdentity -WhatIf
.\Generate-AzureLocal-Parameters.ps1 -ConfigPath "config/infrastructure-azl-lab.yml" -AuthType LocalIdentity -WhatIf
Shows what would be generated for local identity without writing a file.
#>

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ Use the config-driven generation script to populate parameters from `infrastruct

```powershell
# Generate AD parameter file
.\configs\Generate-AzureLocal-Parameters.ps1 -ConfigPath "configs/infrastructure.yml" -AuthType AD
.\configs\Generate-AzureLocal-Parameters.ps1 -ConfigPath "config/infrastructure.yml" -AuthType AD

# Generate Local Identity parameter file
.\configs\Generate-AzureLocal-Parameters.ps1 -ConfigPath "configs/infrastructure.yml" -AuthType LocalIdentity
.\configs\Generate-AzureLocal-Parameters.ps1 -ConfigPath "config/infrastructure.yml" -AuthType LocalIdentity
```

The script reads all 54 parameters from `infrastructure.yml`, resolves Key Vault references, and writes a deployment-ready JSON file. See `configs/Generate-AzureLocal-Parameters.ps1` for full documentation.
The script reads all 54 parameters from `infrastructure.yml`, resolves Key Vault references, and writes a deployment-ready JSON file. See `config/Generate-AzureLocal-Parameters.ps1` for full documentation.

### Option 2: Manual Placeholder Replacement

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ Use the generation script to populate all 54 parameters from `infrastructure.yml

```powershell
# AD auth
.\configs\Generate-AzureLocal-Parameters.ps1 -ConfigPath "configs/infrastructure.yml" -AuthType AD
.\configs\Generate-AzureLocal-Parameters.ps1 -ConfigPath "config/infrastructure.yml" -AuthType AD

# Local Identity auth
.\configs\Generate-AzureLocal-Parameters.ps1 -ConfigPath "configs/infrastructure.yml" -AuthType LocalIdentity
.\configs\Generate-AzureLocal-Parameters.ps1 -ConfigPath "config/infrastructure.yml" -AuthType LocalIdentity
```

The script reads the YAML config, maps all values, and writes a deployment-ready JSON. See `configs/Generate-AzureLocal-Parameters.ps1` for full documentation.
The script reads the YAML config, maps all values, and writes a deployment-ready JSON. See `config/Generate-AzureLocal-Parameters.ps1` for full documentation.

### Option B: Manual Replacement

Expand Down Expand Up @@ -101,10 +101,10 @@ Key differences:
Instead of manually filling placeholders, use the generation script:

```powershell
.\configs\Generate-AzureLocal-Parameters.ps1 -ConfigPath "configs/infrastructure.yml" -AuthType AD
.\configs\Generate-AzureLocal-Parameters.ps1 -ConfigPath "config/infrastructure.yml" -AuthType AD
```

See `configs/Generate-AzureLocal-Parameters.ps1` for full documentation.
See `config/Generate-AzureLocal-Parameters.ps1` for full documentation.

## Validated Examples

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Master Variable Registry - Azure Local Cloudnology Cloud Management Platform
# =============================================================================
# Version: 4.0.0
# Schema: infrastructure.schema.json (v4.0.0)
# Schema: variables.schema.json (v4.0.0)
# Last Updated: 2026-03-05
#
# This file defines ALL variable names, types, and descriptions used across
Expand Down Expand Up @@ -83,7 +83,7 @@ _metadata:
change: "Added B2B, GitLab, Arc Resource Bridge, cluster networking, monitoring extended"
reason: "Variable audit from 157 PowerShell scripts"
cross_references:
- source: "infrastructure.schema.json"
- source: "variables.schema.json"
relationship: "validates infrastructure files against these definitions"
- source: "registry-reference.mdx"
relationship: "human-readable documentation of this registry"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://github.com/Azure Local Cloud/azl-env/schemas/infrastructure.schema.json",
"$id": "https://github.com/Azure Local Cloud/azl-env/schemas/variables.schema.json",
"title": "Azure Local Infrastructure Configuration (v4.0.0)",
"description": "JSON Schema for validating Azure Local environment infrastructure.yml files. Aligned with master-registry.yaml v4.0.0 — 13-section hierarchy. NOTE: This schema is currently hand-maintained and MUST be kept in sync with master-registry.yaml (the canonical source). TODO: Auto-generate this schema from master-registry.yaml to prevent drift.",
"type": "object",
Expand Down
25 changes: 15 additions & 10 deletions configs/variables.template.yml → config/variables.example.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
################################################################################
# Azure Local Toolkit - Variables Template
# =============================================================================
# variables.example.yml
# Central configuration — single source of truth for all deployment phases.
#
# Copy this file to your own variables.yml and fill in your environment values.
# This template contains the minimum required variables for a deployment.
# Copy this file to variables.yml and fill in your values:
# cp config/variables.example.yml config/variables.yml
#
# For the full variable reference, see:
# - configs/infrastructure.yml (complete 14-section schema)
# - configs/variables/assets/master-registry.yaml (variable definitions)
# DO NOT commit variables.yml — it is excluded by .gitignore.
#
# Key Vault References:
# Secrets use keyvault:// URIs and are resolved at runtime.
# Format: keyvault://<vault-name>/<secret-name>
# NEVER put actual passwords or secrets in this file.
#
# All secrets should be stored in Azure Key Vault and referenced as:
# keyvault://<vault-name>/<secret-name>
################################################################################
# For the full variable reference, see:
# - config/infrastructure.yml (complete 14-section schema)
# - config/schema/master-registry.yaml (variable definitions)
# =============================================================================

# =============================================================================
# SITE
Expand Down
File renamed without changes.
Loading
Loading