# Provisioning Library Generation

> 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.

- Skill: `azure-azure-sdk-for-net/provisioning-library-generation` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add azure-azure-sdk-for-net/provisioning-library-generation`
- Raw SKILL.md: https://api.skillmd.com/api/skills/azure-azure-sdk-for-net/provisioning-library-generation/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: Azure (https://skillmd.com/u/azure-azure-sdk-for-net)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/azure-azure-sdk-for-net/provisioning-library-generation

---


# 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

