Skip to content
Closed
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
60 changes: 60 additions & 0 deletions .github/workflows/validate-config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# =============================================================================
# validate-config.yml — Validate config/variables.example.yml 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 variables.example.yml against schema
run: |
python3 -c "
import yaml, json, sys
from jsonschema import validate, ValidationError

Comment on lines +42 to +46
with open('config/variables.example.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/variables.example.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)
"
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ Backups/
Temp/
Configs/

# User-specific config (actual values — never commit)
config/variables.yml

# Log and report files
*.log
*.csv
Expand Down
40 changes: 40 additions & 0 deletions config/schema/variables.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://github.com/AzureLocal/azurelocal-vm-conversion-toolkit/config/schema/variables.schema.json",
"title": "VM Conversion Toolkit Variables",
"description": "Schema for config/variables.example.yml — validates required sections and key structure.",
"type": "object",
"required": ["azure", "azure_local", "conversion", "tags"],
"properties": {
"azure": {
"type": "object",
"required": ["subscription_id", "resource_group", "location"],
"properties": {
"subscription_id": { "type": "string" },
"resource_group": { "type": "string" },
"location": { "type": "string" }
}
},
"azure_local": {
"type": "object",
"required": ["custom_location_id", "logical_network_id"],
"properties": {
"custom_location_id": { "type": "string" },
"logical_network_id": { "type": "string" }
}
},
"conversion": {
"type": "object",
"required": ["working_directory"],
"properties": {
"working_directory": { "type": "string" },
"max_parallel": { "type": "integer", "minimum": 1 }
}
},
"tags": {
"type": "object",
"additionalProperties": { "type": "string" }
}
},
"additionalProperties": false
}
48 changes: 48 additions & 0 deletions config/variables.example.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# =============================================================================
# variables.example.yml
# Central variable reference for VM Gen1-to-Gen2 conversion scripts.
#
# Copy this file to variables.yml and fill in your values:
# cp config/variables.example.yml config/variables.yml
#
# DO NOT commit variables.yml — it is excluded by .gitignore.
#
# NOTE: These scripts currently accept parameters directly on the command line.
# This file documents the common values you will need across all scripts.
# Future versions may support loading from this file directly.
# =============================================================================


# =============================================================================
# Azure
# =============================================================================
azure:
subscription_id: "00000000-0000-0000-0000-000000000000"
resource_group: "rg-azurelocal-prod"
location: "eastus"


# =============================================================================
# Azure Local
# =============================================================================
azure_local:
custom_location_id: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-azurelocal/providers/Microsoft.ExtendedLocation/customLocations/cl-azurelocal-01"
logical_network_id: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-azurelocal/providers/Microsoft.AzureStackHCI/logicalNetworks/lnet-mgmt-01"


# =============================================================================
# Conversion Settings
# =============================================================================
conversion:
working_directory: "C:\\ClusterStorage\\Volume01\\Gen2Conversion"
max_parallel: 1 # VMs to process in parallel (1 = sequential)


# =============================================================================
# Tags
# =============================================================================
tags:
project: "VM-Conversion"
environment: "production"
workload: "gen1-to-gen2"
solution: "vmconvert-azure-local"
105 changes: 105 additions & 0 deletions docs/reference/variables.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Variable Reference

All VM conversion scripts use a central configuration file: `config/variables.yml`. This file documents the common values you will need across all scripts. Future versions may support loading from this file directly.

!!! tip "Getting started"
Copy the example and fill in your values:
```powershell
cp config/variables.example.yml config/variables.yml
```
**Never commit** `variables.yml` — it is excluded by `.gitignore` because it contains environment-specific values.

!!! note "Current usage"
These scripts currently accept parameters directly on the command line.
This file documents the common values you will need and serves as the canonical parameter reference.

---

## Naming Rules

| Scope | Convention | Example |
|-------|-----------|---------|
| Top-level sections | `snake_case` | `azure_local`, `conversion` |
| Keys within sections | `snake_case` | `subscription_id`, `max_parallel` |
| Azure resource IDs | Full ARM resource ID | `/subscriptions/.../customLocations/cl-01` |

---

## Azure

```yaml
azure:
subscription_id: "00000000-0000-0000-0000-000000000000"
resource_group: "rg-azurelocal-prod"
location: "eastus"
```

| Variable | Type | Required | Description | Default |
|----------|------|:--------:|-------------|---------|
| `azure.subscription_id` | string | **Yes** | Azure subscription ID | — |
| `azure.resource_group` | string | **Yes** | Resource group containing the target VMs | — |
| `azure.location` | string | **Yes** | Azure region | `eastus` |

---

## Azure Local

```yaml
azure_local:
custom_location_id: "/subscriptions/.../customLocations/cl-azurelocal-01"
logical_network_id: "/subscriptions/.../logicalNetworks/lnet-mgmt-01"
```

| Variable | Type | Required | Description | Default |
|----------|------|:--------:|-------------|---------|
| `azure_local.custom_location_id` | string | **Yes** | Full ARM resource ID of the Azure Local custom location | — |
| `azure_local.logical_network_id` | string | **Yes** | Full ARM resource ID of the logical network for the converted VM | — |

---

## Conversion Settings

```yaml
conversion:
working_directory: "C:\\ClusterStorage\\Volume01\\Gen2Conversion"
max_parallel: 1
```

| Variable | Type | Required | Description | Default |
|----------|------|:--------:|-------------|---------|
| `conversion.working_directory` | string | **Yes** | Scratch directory for conversion work files (must have sufficient free space) | — |
| `conversion.max_parallel` | integer | No | Number of VMs to process in parallel (`1` = sequential) | `1` |

---

## Tags

```yaml
tags:
project: "VM-Conversion"
environment: "production"
workload: "gen1-to-gen2"
solution: "vmconvert-azure-local"
```

| Variable | Type | Required | Description | Default |
|----------|------|:--------:|-------------|---------|
| `tags.project` | string | No | Project tag | `VM-Conversion` |
| `tags.environment` | string | No | Environment tag | `production` |
| `tags.workload` | string | No | Workload type tag | `gen1-to-gen2` |
| `tags.solution` | string | No | Solution identifier tag | `vmconvert-azure-local` |

---

## Script Parameter Mapping

The table below maps `variables.yml` keys to the actual script parameters:

| Variable Key | Azure Local Script Param | Hyper-V Script Param |
|-------------|-------------------------|---------------------|
| `azure.subscription_id` | `-SubscriptionId` | N/A |
| `azure.resource_group` | `-ResourceGroup` | N/A |
| `azure_local.custom_location_id` | `-CustomLocationId` | N/A |
| `azure_local.logical_network_id` | `-LogicalNetworkId` | N/A |
| `conversion.working_directory` | `-WorkingDirectory` | `-WorkingDirectory` |
| `conversion.max_parallel` | `-MaxParallel` | `-MaxParallel` |
2 changes: 2 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ nav:
- Azure Local Path: runbook-azurelocal.md
- Hyper-V Path: runbook-hyperv.md
- Troubleshooting: troubleshooting.md
- Reference:
- Variable Reference: reference/variables.md
- Contributing: contributing.md

markdown_extensions:
Expand Down
Loading