- name
- provisioning-library-generation
- description
- Generate new Azure.Provisioning.* libraries OR regenerate existing ones. Use when introducing a brand-new provisioning library, adding new resource types, enum values, or API versions.
# Provisioning Library Generation
This skill covers two related generation workflows for `Azure.Provisioning.*` libraries:
- **Onboarding** — introducing a brand new `Azure.Provisioning.{Service}` package.
- **Regeneration** — updating an existing package to add new resources, enum values, or API versions.
> **Start here:** Use **Workflow Selection** below to choose the correct process before doing anything else.
---
## Workflow Selection
### Is this onboarding or regeneration?
- If `sdk/{service}/Azure.Provisioning.{Service}/` already exists → **Regeneration**. Jump to [Regeneration Workflow](#regeneration-workflow).
- If it does NOT exist → **Onboarding**. Read and follow `ONBOARDING.md` in this skill directory. New provisioning libraries are onboarded through the TypeSpec provisioning emitter.
---
## Regeneration Workflow
(For existing packages — adding new resources, enum values, or API versions.)
## Step 1: Determine If Management Library Version Update Is Needed
**Key principle**: Only update the management library version if explicitly requested or if the feature doesn't exist in the current version. Prefer not updating to reduce the amount of changes.
1. **If the requirement explicitly says "update the version"** → Update the version (proceed to Step 2A)
2. **If the requirement does NOT explicitly request a version update**:
- Check if the feature already exists in the current management library:
```shell
# Search for the resource/feature in the management library
grep -r "NetworkSecurityPerimeterResource" sdk/{service}/Azure.ResourceManager.{Service}/
```
- If the feature exists → Skip version update, proceed to Step 2B
- If the feature doesn't exist → You'll need to update the version (proceed to Step 2A)
## Step 2A: Update Management Library Version (If Needed)
Edit `eng/centralpackagemanagement/Directory.Packages.props` to update the management library version:
```xml
<PackageVersion Include="Azure.ResourceManager.{ServiceName}" Version="{NewVersion}" />
```
## Step 2B: Check for Resource Whitelist (If Applicable)
Some specifications (like Network) use a whitelist to limit which resources are generated. Check the specification file:
```shell
cat sdk/provisioning/Generator/src/Specifications/{Service}Specification.cs
```
If you see a `_generatedResources` HashSet, add the new resource types to it:
```csharp
private readonly HashSet<Type> _generatedResources = new()
{
// ... existing resources ...
typeof(NetworkSecurityPerimeterResource),
typeof(NetworkSecurityPerimeterAccessRuleResource),
// ... add all related resource types ...
};
```
## Step 3: Run the Provisioning Generator
Navigate to the generator directory and run:
```shell
cd sdk/provisioning/Generator/src
dotnet run --framework net10.0 -- --filter {ServiceName}
```
**Important:** The generator reads from NuGet packages, NOT local source code. The version in `eng/centralpackagemanagement/Directory.Packages.props` determines which package version is used.
### Verify Only Target Library Changed
After running the generator, verify that only the target provisioning library was modified:
```shell
git status --short -- sdk/provisioning/
```
The generator may regenerate other libraries (e.g., `Azure.Provisioning`) due to shared dependencies. **Revert any changes to libraries other than the target:**
```shell
# Example: If you're adding features to Azure.Provisioning.Network, revert changes to Azure.Provisioning
git checkout main -- sdk/provisioning/Azure.Provisioning/
```
Only keep changes to `Azure.Provisioning.{TargetService}/`.
### Generator Errors
If the generator fails with errors:
1. **Capture the full error output** including stack traces and error messages
2. **Report the error to the user** with enough context to understand what went wrong
3. **Stop and let the user decide** how to proceed — generator errors often require code changes to the generator itself or the specification files, which may need human judgment
Do NOT attempt to automatically fix generator errors without user guidance.
> Schema and Bicep-reference validation is handled by the dedicated provisioning PR review workflow. Do not duplicate that validation in this generation workflow.
## Step 4: Handle Breaking Changes (Version Updates Only)
When updating management library versions, compare the generated code with the previous version. Common breaking changes include:
### Type Removed
If a type is removed from the management library:
- Create a backward-compatible stub in `sdk/provisioning/Azure.Provisioning.{Service}/src/BackwardCompatible/Models/`
- Mark it with `[EditorBrowsable(EditorBrowsableState.Never)]` and `[Obsolete]`
### Property Type Changed
If a property type changes:
1. In the specification file, use `CustomizeProperty` to rename the new property:
```csharp
CustomizeProperty("ResourceName", "PropertyName", p => p.Name = "NewPropertyName");
```
2. Use `CustomizeResource` with `GeneratePartialPropertyDefinition = true`:
```csharp
CustomizeResource("ResourceName", r => r.GeneratePartialPropertyDefinition = true);
```
3. Create a partial class in `BackwardCompatible/` that implements `DefineAdditionalProperties()` to add the old property name
### Enum Ordinal Shift
If enum member ordering changes (affecting implicit numeric values):
- Use `OrderEnum<T>()` in the specification file to preserve the original ordering:
```csharp
OrderEnum<PostgreSqlFlexibleServerVersion>("Ver15", "Ver14", "Ver13", "Ver12", "Ver11", "Sixteen");
```
### DataMember Attribute Removed
If `[DataMember]` attributes are removed from enums, ApiCompat will report `CP0014` errors.
For provisioning packages, add the suppression to `eng/apicompatbaselines/Azure.Provisioning.{Service}.xml`:
```xml
<Suppression>
<DiagnosticId>CP0014</DiagnosticId>
<Target>F:Azure.Provisioning.{Service}.{EnumType}.{Member}:[T:System.Runtime.Serialization.DataMemberAttribute]</Target>
</Suppression>
```
> Note: This centralized suppression approach is specifically supported for provisioning packages and is the only option for suppressing these particular ApiCompat errors.
## Step 5: Fix Spell Check Issues
If CI fails with "Unknown word" errors, add the words to `sdk/provisioning/cspell.yaml`:
```yaml
- filename: '**/sdk/provisioning/Azure.Provisioning.{Service}/**/*.cs'
words:
- newword1
- newword2
```
**Important:** Use `sdk/provisioning/cspell.yaml`, NOT `.vscode/cspell.json`.
## Step 6: Run Pre-Commit Checks
Before committing, invoke the `pre-commit-checks` skill with the service directory set to `provisioning`. This will handle code formatting, API export, and snippet updates.
## Step 7: Update CHANGELOG and Commit
1. Update the CHANGELOG at `sdk/provisioning/Azure.Provisioning.{Service}/CHANGELOG.md`:
```markdown
## X.X.X-beta.X (Unreleased)
### Features Added
- Added support for `{NewResource}` resources and related types.
```
2. Stage all changes and commit:
```shell
git add -A
git commit -m "Add {Feature} to Azure.Provisioning.{Service}"
```
## Example A: PostgreSQL Server Versions 17 and 18 (Version Update Required)
The requirement was to add PostgreSQL versions 17 and 18, which required updating the management library.
1. **Updated `eng/centralpackagemanagement/Directory.Packages.props`**: Changed `Azure.ResourceManager.PostgreSql` from 1.3.1 to 1.4.1
2. **Ran generator**: `dotnet run --framework net10.0 -- --filter PostgreSql`
3. **Handled breaking changes**: Property renames, obsolete stubs, enum ordering, ApiCompatBaseline
4. **Fixed CI issues**: Added spell check words to `cspell.yaml`
5. **Ran pre-commit checks**: `pwsh eng\scripts\CodeChecks.ps1 -ServiceDirectory provisioning`
## Example B: NetworkSecurityPerimeter Resources (No Version Update Needed)
The requirement was to add NetworkSecurityPerimeter support. The resources already existed in the current management library but weren't being generated due to a whitelist.
1. **Checked management library**: Resources already existed in `Azure.ResourceManager.Network`
2. **Updated `NetworkSpecification.cs`**: Added 7 resource types to `_generatedResources`:
```csharp
typeof(NetworkSecurityPerimeterResource),
typeof(NetworkSecurityPerimeterAccessRuleResource),
typeof(NetworkSecurityPerimeterAssociationResource),
typeof(NetworkSecurityPerimeterLinkResource),
typeof(NetworkSecurityPerimeterLinkReferenceResource),
typeof(NetworkSecurityPerimeterLoggingConfigurationResource),
typeof(NetworkSecurityPerimeterProfileResource),
```
3. **Ran generator**: `dotnet run --framework net10.0 -- --filter Network`
4. **Ran pre-commit checks**: No breaking changes (new resources only)
5. **Updated CHANGELOG**: Documented new NetworkSecurityPerimeter support
## Key Files
| File | Purpose |
|------|---------|
| `eng/centralpackagemanagement/Directory.Packages.props` | Management library version |
| `sdk/provisioning/Generator/src/Specifications/{Service}Specification.cs` | Generator customizations and resource whitelist |
| `sdk/provisioning/Generator/src/Model/Specification.Customize.cs` | Customization API (`OrderEnum`, `CustomizeResource`, etc.) |
| `sdk/provisioning/Azure.Provisioning.{Service}/src/BackwardCompatible/` | Backward-compatible customizations |
| `eng/apicompatbaselines/Azure.Provisioning.{Service}.xml` | API compatibility suppressions (provisioning only) |
| `sdk/provisioning/cspell.yaml` | Spell check configuration for provisioning |
## Troubleshooting
### Resources not being generated
- Check if the specification uses a whitelist (`_generatedResources`)
- Verify the resource types are added to the whitelist
- Ensure the management library version is correct
### Generator fails to find types
- Ensure the management library version in `eng/centralpackagemanagement/Directory.Packages.props` is correct and published
- Try running `dotnet restore` before the generator
### API compatibility errors
- Use customization code to maintain backward compatibility (preferred approach):
- Create backward-compatible stubs in `BackwardCompatible/Models/`
- Use `CustomizeProperty` and `CustomizeResource` in specification files
- Add partial classes with `DefineAdditionalProperties()` for property renames
- Only `[DataMember]` attribute removal errors can be suppressed via the centralized XML suppression file
### Enum values in wrong order
- Use `OrderEnum<T>()` in the specification file to control ordering
### Build fails after regeneration
- Check for missing using statements
- Check for type name conflicts
- Review the specification customizations
Voir sur GitHub