Skip to content

Conversation

@stack72
Copy link
Contributor

@stack72 stack72 commented Nov 28, 2025

This PR introduces a comprehensive framework for defining manually-managed assets in Clover's code generation pipeline. Previously, Clover only supported auto-generated CloudFormation resources from AWS schemas. This enhancement allows developers to define custom resources with complete control over their schemas, functions, and behavior.

Motivation

Some AWS resources don't map cleanly to CloudFormation's CRUD model:

  • Query resources that lookup existing infrastructure (e.g., AMI lookups)
  • Validation resources that check prerequisites without creating resources
  • Custom integrations that wrap multiple AWS APIs
  • Resources with special behaviors that need custom qualification or attribute logic

Rather than forcing these into the auto-generation pipeline or maintaining separate codebases, this PR enables defining them inline with provider-specific configuration.

Architecture

Core Components

1. Generic Pipeline Integration (src/pipelines/generic/loadExtraAssets.ts)

A new pipeline step that:

  • Loads manually-managed asset schemas from provider configuration
  • Transforms them into ExpandedPkgSpec using the same pipeline as auto-generated assets
  • Applies custom functions (actions, qualifications, attributes, code generation, management)
  • Merges them with auto-generated specs for unified processing

Key Features:

  • Custom function override: When custom functions are defined, they completely replace provider defaults
  • Flexible bindings: Attribute functions can specify custom argument bindings via attributeBindings callback
  • Property attachment: attachAttributeFunctions callback allows programmatic attachment of attribute functions to specific properties
  • Metadata customization: Override display names, colors, categories, and descriptions per resource

2. Provider Configuration Extension (src/pipelines/types.ts)

Added extraAssets configuration to ProviderConfig:

extraAssets?: {
  // Function to load extra asset schemas
  loadSchemas: () => Promise<SuperSchema[]> | SuperSchema[];

  // Optional: Custom property classification for manually-managed assets
  classifyProperties?: (schema: SuperSchema) => OnlyProperties;

  // Optional: Map of resource type names to their custom configurations
  customFuncs?: Record<string, {
    // Metadata overrides
    metadata?: {
      displayName?: string;
      category?: string;
      color?: string;
      description?: string;
    };

    // Custom function definitions
    actions?: Record<string, FuncSpecInfo & { actionKind: ActionFuncSpecKind }>;
    codeGeneration?: Record<string, FuncSpecInfo>;
    management?: Record<string, FuncSpecInfo & { handlers: CfHandlerKind[] }>;
    qualification?: Record<string, FuncSpecInfo>;
    attribute?: Record<string, FuncSpecInfo>;

    // Simplified attribute function configuration
    // Just specify which property to attach to and which properties to use as inputs
    attributeFunctions?: (variant: ExpandedSchemaVariantSpec) => Record<string, {
      attachTo: string;   // Property name to attach the function to
      inputs: string[];   // Domain property names to pass as inputs
    }>;
  }>;
}

3. Function Factory Enhancement (src/pipelines/generic/funcFactories.ts)

Added createAttributeFuncs() to support attribute function generation with flexible binding strategies:

  • Uniform bindings: Same bindings for all functions
  • Per-function bindings: Custom bindings per function name
  • Dynamic bindings: Generator function for complex binding logic

4. Property Path Utilities (src/pipelines/generic/index.ts)

New helper functions for constructing SI property paths:

export const PROP_PATH_SEPARATOR = "\x0B"; // Vertical tab character

export function buildPropPath(parts: string[]): string {
  return parts.join(PROP_PATH_SEPARATOR);
}

export function createPropFinder(
  variant: ExpandedSchemaVariantSpec,
  schemaName?: string
): (name: string) => PropSpec;

Benefits:

  • Single source of truth for the separator character
  • Type-safe path construction
  • More readable than string template literals
  • Easy to find properties with better error messages

AWS Provider Implementation

5. AWS Extra Assets Registry (src/pipelines/aws/extraAssets.ts)

Central registry for all AWS manually-managed assets:

export const AWS_MANUALLY_MANAGED_ASSETS = {
  "AWS::EC2::AMI": ec2Ami,
  // Future assets can be added here
};

export function loadAwsExtraAssets(): SuperSchema[];
export function getAwsExtraAssetFuncs(): Record<string, any>;

6. AWS Provider Configuration (src/pipelines/aws/provider.ts)

Integrated extra assets into AWS provider config:

export const AWS_PROVIDER_CONFIG: ProviderConfig = {
  // ... existing config
  extraAssets: {
    loadSchemas: loadAwsExtraAssets,
    customFuncs: getAwsExtraAssetFuncs(),
  },
};

7. AWS Pipeline Integration (src/pipelines/aws/pipeline.ts)

Added loadExtraAssets() step in the pipeline:

  • Runs after standard CloudFormation transformations
  • Runs before provider-specific overrides
  • Runs before asset func generation

This ensures manually-managed assets are included in all downstream processing.

Example Implementation: AWS::EC2::AMI

The first manually-managed asset demonstrates the full capabilities of the framework.

Directory Structure

src/pipelines/aws/manually-managed-assets/AWS::EC2::AMI/
├── schema.ts                                    # Complete resource definition
├── attributes/
│   └── awsEc2AmiQueryImageId.ts                # Queries AMI ID from AWS
└── qualifications/
    └── qualificationAmiExists.ts               # Validates AMI exists

Schema Definition (schema.ts)

export const schema: CfSchema = {
  typeName: "AWS::EC2::AMI",
  description: "Amazon Machine Image (AMI) query and validation resource",
  properties: {
    // Query parameters (domain properties)
    ExecutableUsers: { type: "string", ... },
    Owners: { type: "string", ... },
    UseMostRecent: { type: "boolean", default: true },
    Filters: { type: "array", ... },
    ImageId: { type: "string", ... },
    region: { type: "string", ... },
    credential: { type: "string", ... },
  },
  primaryIdentifier: ["/properties/ImageId"],
};

export const config = {
  metadata: {
    displayName: "AMI Query",
    category: "AWS::EC2",
    color: "#FF9900",
  },

  qualification: {
    "Validate AMI Query": {
      id: "e8b9a8a41fd88e1a...",
      path: "./qualifications/qualificationAmiExists.ts",
      backendKind: "jsAttribute",
      responseType: "qualification",
    },
  },

  attribute: {
    "Query AMI ID": {
      id: "6e74c3c417eb8fd0...",
      path: "./attributes/awsEc2AmiQueryImageId.ts",
      backendKind: "jsAttribute",
      responseType: "string",
    },
  },

  // Attribute function configuration - simple and declarative!
  attributeFunctions: (_variant: ExpandedSchemaVariantSpec) => {
    return {
      "Query AMI ID": {
        attachTo: "ImageId",  // Property to attach the function to
        inputs: ["region", "UseMostRecent", "Owners", "Filters", "ExecutableUsers"],
      },
      // Easy to add more attribute functions!
      // "Calculate Timeout": {
      //   attachTo: "TotalTimeout",
      //   inputs: ["Config.Timeout", "Config.MaxRetries"],  // Supports nested paths!
      // },
    };
  },
};

Key Implementation Details

  1. Simplified Attribute Configuration: The new attributeFunctions callback is dramatically simpler:

    • Before: ~90 lines of repetitive boilerplate with attributeBindings and attachAttributeFunctions
    • After: 7 lines of clear, declarative configuration
    • Just specify which property to attach to and which properties to use as inputs
    • The system automatically creates function bindings, attaches the function, and sets up property inputs
  2. No Duplication: Previously, you had to list the same properties twice:

    • Once in attributeBindings (for function arguments)
    • Again in attachAttributeFunctions (for property inputs)
    • Now you list them once in attributeFunctions.inputs
  3. Automatic Property Resolution: The system automatically:

    • Looks up property definitions to get types and uniqueIds
    • Creates FuncArgumentSpec bindings with correct types
    • Builds property paths with the correct separator (\x0B)
    • Attaches functions to properties with the correct function ID
    • Sets up property inputs with all required metadata
  4. Nested Property Support: Use dot notation to reference nested properties:

    • Simple properties: "region", "ImageId"
    • Nested objects: "Config.MaxRetries", "Settings.Timeout.Seconds"
    • Array elements: "Tags.Key", "Filters.Name"
    • The system automatically traverses object hierarchies and arrays
  5. Multiple Functions: Add as many attribute functions as needed - just add entries to the returned object

  6. Qualification Inputs: Manually-managed assets get ["domain", "secrets"] as qualification inputs (vs. default ["domain", "code"]), allowing access to AWS credentials

Secret Handling Enhancements

This PR also introduces significant improvements to how secrets are handled in manually-managed assets:

1. Explicit Secret Kind Declaration (src/pipelines/aws/schema.ts)

Added secretKinds field to CfSchema interface:

export interface CfSchema extends SuperSchema {
  // ... existing fields

  /**
   * Explicit mapping of property names to their secret kinds.
   * Properties listed here will be treated as secrets.
   *
   * Example:
   * secretKinds: {
   *   credential: "AWS Credential",
   *   apiKey: "API Key",
   * }
   */
  secretKinds?: Record<string, string>;
}

Why this approach?

  • Explicit over implicit: No guessing - you declare exactly what's a secret
  • Type-safe: Properties not in secretKinds stay in domain
  • Flexible: Different properties can have different secret kinds
  • No breaking changes: writeOnlyProperties can still be used for non-secret write-only props

2. Automatic Secret Configuration (src/pipelines/generic/loadExtraAssets.ts)

When properties are listed in secretKinds:

  • Automatically moved to the secrets section
  • widgetKind set to "Secret"
  • widgetOptions configured with the specified secret kind
  • No manual configureProperties code needed
// In schema.ts - just declare it
secretKinds: {
  credential: "AWS Credential",
}

// The pipeline automatically:
// - Moves credential to secrets section
// - Sets widgetKind: "Secret"
// - Sets widgetOptions: [{ label: "secretKind", value: "AWS Credential" }]

3. Secret Kind Extraction in Code Generation (src/pipelines/generic/generateAssetFuncs.ts)

Fixed generateSecretPropBuilderString to extract the actual secret kind from widgetOptions:

function generateSecretPropBuilderString(prop: ExpandedPropSpec, indent_level: number): string {
  // Extract the secretKind from the widget options
  const secretKindOption = prop.data?.widgetOptions?.find(
    (opt) => opt.label === "secretKind"
  );
  const secretKind = secretKindOption?.value ?? prop.name;

  return (
    `new SecretPropBuilder()\n` +
    `${indent(indent_level)}.setName("${prop.name}")\n` +
    `${indent(indent_level)}.setSecretKind("${secretKind}")\n` +
    `${indent(indent_level)}.build()`
  );
}

Before: Always used prop.name as secretKind (incorrect)
After: Extracts from widgetOptions (correct)

Schema Customization Features

1. Default Values (src/spec/props.ts)

Schema default values are now properly extracted and applied:

// In schema
UseMostRecent: {
  type: "boolean",
  default: true,  // ← This is now extracted
}

// Generated code
const UseMostRecentProp = new PropBuilder()
  .setDefaultValue(true)  // ← Automatically included
  .build();

2. Custom Documentation Links (src/spec/props.ts)

Support for custom docLink field in schema properties:

// In schema
ExecutableUsers: {
  type: "string",
  description: "...",
  docLink: "https://docs.aws.amazon.com/AWSEC2/latest/APIReference/...",
} as any,

// Generated code uses the custom link instead of provider default

Why needed? The AWS provider defaults to CloudFormation URLs, but manually-managed assets may reference different APIs (EC2, IAM, etc.)

3. Custom Array Item Names (src/spec/props.ts)

Support for custom itemName field to prevent breaking changes:

// In schema
Filters: {
  type: "array",
  itemName: "Filter",  // ← Override default "FiltersItem"
  items: { ... }
} as any,

// Generated code
.setEntry(
  new PropBuilder()
    .setName("Filter")  // ← Uses custom name
    // ...
)

Why critical? Changing array item names breaks existing user configurations. This allows preserving backward compatibility.

Migration Path

Existing auto-generated resources are completely unaffected:

  • No changes to CloudFormation resource generation
  • Default functions remain the same
  • Pipeline order ensures compatibility

To add a new manually-managed asset:

  1. Create directory: src/pipelines/{provider}/manually-managed-assets/{ResourceType}/
  2. Define schema.ts with schema and config (including secretKinds if needed)
  3. Implement function files
  4. Register in extraAssets.ts
  5. No changes to pipeline or provider config needed!

Breaking Change Prevention

The itemName feature prevents breaking changes for existing users:

  • Array item names (like "Filter" vs "FiltersItem") are now controllable
  • Existing configurations using "Filter" will continue to work
  • Without this, changing from "Filter" to "FiltersItem" would break all user data

@github-actions
Copy link

github-actions bot commented Nov 28, 2025

Dependency Review

✅ No vulnerabilities or OpenSSF Scorecard issues found.

Scanned Files

None

@stack72 stack72 requested a review from sprutton1 November 28, 2025 02:58
… pipeline

This PR introduces a comprehensive framework for defining manually-managed assets in Clover's code generation pipeline. Previously, Clover only supported auto-generated CloudFormation resources from AWS schemas. This enhancement allows developers to define custom resources with complete control over their schemas, functions, and behavior.

## Motivation

Some AWS resources don't map cleanly to CloudFormation's CRUD model:
- **Query resources** that lookup existing infrastructure (e.g., AMI lookups)
- **Validation resources** that check prerequisites without creating resources
- **Custom integrations** that wrap multiple AWS APIs
- **Resources with special behaviors** that need custom qualification or attribute logic

Rather than forcing these into the auto-generation pipeline or maintaining separate codebases, this PR enables defining them inline with provider-specific configuration.

## Architecture

### Core Components

#### 1. **Generic Pipeline Integration** (`src/pipelines/generic/loadExtraAssets.ts`)

A new pipeline step that:
- Loads manually-managed asset schemas from provider configuration
- Transforms them into `ExpandedPkgSpec` using the same pipeline as auto-generated assets
- Applies custom functions (actions, qualifications, attributes, code generation, management)
- Merges them with auto-generated specs for unified processing

**Key Features:**
- **Custom function override**: When custom functions are defined, they completely replace provider defaults
- **Flexible bindings**: Attribute functions can specify custom argument bindings via `attributeBindings` callback
- **Property attachment**: `attachAttributeFunctions` callback allows programmatic attachment of attribute functions to specific properties
- **Metadata customization**: Override display names, colors, categories, and descriptions per resource

#### 2. **Provider Configuration Extension** (`src/pipelines/types.ts`)

Added `extraAssets` configuration to `ProviderConfig`:

```typescript
extraAssets?: {
  // Function to load extra asset schemas
  loadSchemas: () => Promise<SuperSchema[]> | SuperSchema[];

  // Optional: Custom property classification for manually-managed assets
  classifyProperties?: (schema: SuperSchema) => OnlyProperties;

  // Optional: Map of resource type names to their custom configurations
  customFuncs?: Record<string, {
    // Metadata overrides
    metadata?: {
      displayName?: string;
      category?: string;
      color?: string;
      description?: string;
    };

    // Custom function definitions
    actions?: Record<string, FuncSpecInfo & { actionKind: ActionFuncSpecKind }>;
    codeGeneration?: Record<string, FuncSpecInfo>;
    management?: Record<string, FuncSpecInfo & { handlers: CfHandlerKind[] }>;
    qualification?: Record<string, FuncSpecInfo>;
    attribute?: Record<string, FuncSpecInfo>;

    // Simplified attribute function configuration
    // Just specify which property to attach to and which properties to use as inputs
    attributeFunctions?: (variant: ExpandedSchemaVariantSpec) => Record<string, {
      attachTo: string;   // Property name to attach the function to
      inputs: string[];   // Domain property names to pass as inputs
    }>;
  }>;
}
```

#### 3. **Function Factory Enhancement** (`src/pipelines/generic/funcFactories.ts`)

Added `createAttributeFuncs()` to support attribute function generation with flexible binding strategies:
- **Uniform bindings**: Same bindings for all functions
- **Per-function bindings**: Custom bindings per function name
- **Dynamic bindings**: Generator function for complex binding logic

#### 4. **Property Path Utilities** (`src/pipelines/generic/index.ts`)

New helper functions for constructing SI property paths:

```typescript
export const PROP_PATH_SEPARATOR = "\x0B"; // Vertical tab character

export function buildPropPath(parts: string[]): string {
  return parts.join(PROP_PATH_SEPARATOR);
}

export function createPropFinder(
  variant: ExpandedSchemaVariantSpec,
  schemaName?: string
): (name: string) => PropSpec;
```

**Benefits:**
- Single source of truth for the separator character
- Type-safe path construction
- More readable than string template literals
- Easy to find properties with better error messages

### AWS Provider Implementation

#### 5. **AWS Extra Assets Registry** (`src/pipelines/aws/extraAssets.ts`)

Central registry for all AWS manually-managed assets:

```typescript
export const AWS_MANUALLY_MANAGED_ASSETS = {
  "AWS::EC2::AMI": ec2Ami,
  // Future assets can be added here
};

export function loadAwsExtraAssets(): SuperSchema[];
export function getAwsExtraAssetFuncs(): Record<string, any>;
```

#### 6. **AWS Provider Configuration** (`src/pipelines/aws/provider.ts`)

Integrated extra assets into AWS provider config:

```typescript
export const AWS_PROVIDER_CONFIG: ProviderConfig = {
  // ... existing config
  extraAssets: {
    loadSchemas: loadAwsExtraAssets,
    customFuncs: getAwsExtraAssetFuncs(),
  },
};
```

#### 7. **AWS Pipeline Integration** (`src/pipelines/aws/pipeline.ts`)

Added `loadExtraAssets()` step in the pipeline:
- Runs **after** standard CloudFormation transformations
- Runs **before** provider-specific overrides
- Runs **before** asset func generation

This ensures manually-managed assets are included in all downstream processing.

## Example Implementation: AWS::EC2::AMI

The first manually-managed asset demonstrates the full capabilities of the framework.

### Directory Structure

```
src/pipelines/aws/manually-managed-assets/AWS::EC2::AMI/
├── schema.ts                                    # Complete resource definition
├── attributes/
│   └── awsEc2AmiQueryImageId.ts                # Queries AMI ID from AWS
└── qualifications/
    └── qualificationAmiExists.ts               # Validates AMI exists
```

### Schema Definition (`schema.ts`)

```typescript
export const schema: CfSchema = {
  typeName: "AWS::EC2::AMI",
  description: "Amazon Machine Image (AMI) query and validation resource",
  properties: {
    // Query parameters (domain properties)
    ExecutableUsers: { type: "string", ... },
    Owners: { type: "string", ... },
    UseMostRecent: { type: "boolean", default: true },
    Filters: { type: "array", ... },
    ImageId: { type: "string", ... },
    region: { type: "string", ... },
    credential: { type: "string", ... },
  },
  primaryIdentifier: ["/properties/ImageId"],
};

export const config = {
  metadata: {
    displayName: "AMI Query",
    category: "AWS::EC2",
    color: "#FF9900",
  },

  qualification: {
    "Validate AMI Query": {
      id: "e8b9a8a41fd88e1a...",
      path: "./qualifications/qualificationAmiExists.ts",
      backendKind: "jsAttribute",
      responseType: "qualification",
    },
  },

  attribute: {
    "Query AMI ID": {
      id: "6e74c3c417eb8fd0...",
      path: "./attributes/awsEc2AmiQueryImageId.ts",
      backendKind: "jsAttribute",
      responseType: "string",
    },
  },

  // Attribute function configuration - simple and declarative!
  attributeFunctions: (_variant: ExpandedSchemaVariantSpec) => {
    return {
      "Query AMI ID": {
        attachTo: "ImageId",  // Property to attach the function to
        inputs: ["region", "UseMostRecent", "Owners", "Filters", "ExecutableUsers"],
      },
      // Easy to add more attribute functions!
      // "Calculate Timeout": {
      //   attachTo: "TotalTimeout",
      //   inputs: ["Config.Timeout", "Config.MaxRetries"],  // Supports nested paths!
      // },
    };
  },
};
```

### Key Implementation Details

1. **Simplified Attribute Configuration**: The new `attributeFunctions` callback is dramatically simpler:
   - **Before**: ~90 lines of repetitive boilerplate with `attributeBindings` and `attachAttributeFunctions`
   - **After**: 7 lines of clear, declarative configuration
   - Just specify which property to attach to and which properties to use as inputs
   - The system automatically creates function bindings, attaches the function, and sets up property inputs

2. **No Duplication**: Previously, you had to list the same properties twice:
   - Once in `attributeBindings` (for function arguments)
   - Again in `attachAttributeFunctions` (for property inputs)
   - Now you list them once in `attributeFunctions.inputs`

3. **Automatic Property Resolution**: The system automatically:
   - Looks up property definitions to get types and uniqueIds
   - Creates `FuncArgumentSpec` bindings with correct types
   - Builds property paths with the correct separator (`\x0B`)
   - Attaches functions to properties with the correct function ID
   - Sets up property inputs with all required metadata

4. **Nested Property Support**: Use dot notation to reference nested properties:
   - Simple properties: `"region"`, `"ImageId"`
   - Nested objects: `"Config.MaxRetries"`, `"Settings.Timeout.Seconds"`
   - Array elements: `"Tags.Key"`, `"Filters.Name"`
   - The system automatically traverses object hierarchies and arrays

5. **Multiple Functions**: Add as many attribute functions as needed - just add entries to the returned object

6. **Qualification Inputs**: Manually-managed assets get `["domain", "secrets"]` as qualification inputs (vs. default `["domain", "code"]`), allowing access to AWS credentials

## Secret Handling Enhancements

This PR also introduces significant improvements to how secrets are handled in manually-managed assets:

### 1. **Explicit Secret Kind Declaration** (`src/pipelines/aws/schema.ts`)

Added `secretKinds` field to `CfSchema` interface:

```typescript
export interface CfSchema extends SuperSchema {
  // ... existing fields

  /**
   * Explicit mapping of property names to their secret kinds.
   * Properties listed here will be treated as secrets.
   *
   * Example:
   * secretKinds: {
   *   credential: "AWS Credential",
   *   apiKey: "API Key",
   * }
   */
  secretKinds?: Record<string, string>;
}
```

**Why this approach?**
- **Explicit over implicit**: No guessing - you declare exactly what's a secret
- **Type-safe**: Properties not in secretKinds stay in domain
- **Flexible**: Different properties can have different secret kinds
- **No breaking changes**: writeOnlyProperties can still be used for non-secret write-only props

### 2. **Automatic Secret Configuration** (`src/pipelines/generic/loadExtraAssets.ts`)

When properties are listed in `secretKinds`:
- Automatically moved to the secrets section
- `widgetKind` set to "Secret"
- `widgetOptions` configured with the specified secret kind
- No manual `configureProperties` code needed

```typescript
// In schema.ts - just declare it
secretKinds: {
  credential: "AWS Credential",
}

// The pipeline automatically:
// - Moves credential to secrets section
// - Sets widgetKind: "Secret"
// - Sets widgetOptions: [{ label: "secretKind", value: "AWS Credential" }]
```

### 3. **Secret Kind Extraction in Code Generation** (`src/pipelines/generic/generateAssetFuncs.ts`)

Fixed `generateSecretPropBuilderString` to extract the actual secret kind from widgetOptions:

```typescript
function generateSecretPropBuilderString(prop: ExpandedPropSpec, indent_level: number): string {
  // Extract the secretKind from the widget options
  const secretKindOption = prop.data?.widgetOptions?.find(
    (opt) => opt.label === "secretKind"
  );
  const secretKind = secretKindOption?.value ?? prop.name;

  return (
    `new SecretPropBuilder()\n` +
    `${indent(indent_level)}.setName("${prop.name}")\n` +
    `${indent(indent_level)}.setSecretKind("${secretKind}")\n` +
    `${indent(indent_level)}.build()`
  );
}
```

**Before**: Always used `prop.name` as secretKind (incorrect)
**After**: Extracts from widgetOptions (correct)

## Schema Customization Features

### 1. **Default Values** (`src/spec/props.ts`)

Schema `default` values are now properly extracted and applied:

```typescript
// In schema
UseMostRecent: {
  type: "boolean",
  default: true,  // ← This is now extracted
}

// Generated code
const UseMostRecentProp = new PropBuilder()
  .setDefaultValue(true)  // ← Automatically included
  .build();
```

### 2. **Custom Documentation Links** (`src/spec/props.ts`)

Support for custom `docLink` field in schema properties:

```typescript
// In schema
ExecutableUsers: {
  type: "string",
  description: "...",
  docLink: "https://docs.aws.amazon.com/AWSEC2/latest/APIReference/...",
} as any,

// Generated code uses the custom link instead of provider default
```

**Why needed?** The AWS provider defaults to CloudFormation URLs, but manually-managed assets may reference different APIs (EC2, IAM, etc.)

### 3. **Custom Array Item Names** (`src/spec/props.ts`)

Support for custom `itemName` field to prevent breaking changes:

```typescript
// In schema
Filters: {
  type: "array",
  itemName: "Filter",  // ← Override default "FiltersItem"
  items: { ... }
} as any,

// Generated code
.setEntry(
  new PropBuilder()
    .setName("Filter")  // ← Uses custom name
    // ...
)
```

**Why critical?** Changing array item names breaks existing user configurations. This allows preserving backward compatibility.

## Migration Path

Existing auto-generated resources are **completely unaffected**:
- No changes to CloudFormation resource generation
- Default functions remain the same
- Pipeline order ensures compatibility

To add a new manually-managed asset:

1. Create directory: `src/pipelines/{provider}/manually-managed-assets/{ResourceType}/`
2. Define `schema.ts` with schema and config (including `secretKinds` if needed)
3. Implement function files
4. Register in `extraAssets.ts`
5. No changes to pipeline or provider config needed!

## Breaking Change Prevention

The `itemName` feature prevents breaking changes for existing users:
- Array item names (like "Filter" vs "FiltersItem") are now controllable
- Existing configurations using "Filter" will continue to work
- Without this, changing from "Filter" to "FiltersItem" would break all user data
@stack72 stack72 force-pushed the manually-managed-assets branch from 67a9c98 to d91cfb4 Compare November 28, 2025 03:56
@systeminit systeminit deleted a comment from github-actions bot Nov 28, 2025
@github-actions
Copy link

Working with Module Index at: https://module-index.systeminit.com
Total: 1 new asset(s), 458 changed asset(s)

AWS - 1 new, 122 changed asset(s)
[AWS::EC2::AMI]: new module
[AWS::ACMPCA::CertificateAuthority]: props 🔀9, other schema contents 🔀3
[AWS::ACMPCA::Certificate]: props 🔀9, other schema contents 🔀2
[AWS::APS::AnomalyDetector]: props 🔀3, other schema contents 🔀3
[AWS::ApiGateway::ApiKey]: props 🔀1, other schema contents 🔀3
[AWS::ApiGateway::DomainNameV2]: props 🔀1, other schema contents 🔀3
[AWS::ApiGateway::DomainName]: props 🔀1, other schema contents 🔀3
[AWS::ApiGateway::Method]: props 🔀1, other schema contents 🔀2
[AWS::ApiGatewayV2::DomainName]: props 🔀1, other schema contents 🔀3
[AWS::AppIntegrations::Application]: props 🔀1, other schema contents 🔀3
[AWS::ApplicationSignals::ServiceLevelObjective]: props 🔀2, other schema contents 🔀3
[AWS::Batch::ComputeEnvironment]: props 🔀6, other schema contents 🔀3
[AWS::Batch::JobDefinition]: props 🔀1, other schema contents 🔀3
[AWS::Bedrock::Agent]: props 🔀3, other schema contents 🔀3
[AWS::Bedrock::AutomatedReasoningPolicy]: props 🔀1, other schema contents 🔀3
[AWS::BedrockAgentCore::BrowserCustom]: props 🔀3, other schema contents 🔀3
[AWS::BedrockAgentCore::CodeInterpreterCustom]: props 🔀1, other schema contents 🔀3
[AWS::BedrockAgentCore::Gateway]: props 🔀1, other schema contents 🔀3
[AWS::CUR::ReportDefinition]: props 🔀2, other schema contents 🔀3
[AWS::Cassandra::Keyspace]: props 🔀1, other schema contents 🔀3
[AWS::Cassandra::Table]: props 🔀13, other schema contents 🔀3
[AWS::Chatbot::MicrosoftTeamsChannelConfiguration]: props 🔀2, other schema contents 🔀3
[AWS::Chatbot::SlackChannelConfiguration]: props 🔀2, other schema contents 🔀3
[AWS::CloudFormation::GuardHook]: props 🔀3, other schema contents 🔀3
[AWS::CloudFormation::HookTypeConfig]: props 🔀1, other schema contents 🔀3
[AWS::CloudFormation::LambdaHook]: props 🔀2, other schema contents 🔀3
[AWS::CloudFront::ConnectionFunction]: props 🔀1, other schema contents 🔀3
[AWS::CloudFront::Distribution]: props 🔀29, other schema contents 🔀3
[AWS::CloudFront::VpcOrigin]: props 🔀4, other schema contents 🔀3
[AWS::CloudWatch::Alarm]: props 🔀1, other schema contents 🔀3
[AWS::CodePipeline::Pipeline]: props 🔀1, other schema contents 🔀3
[AWS::Connect::EvaluationForm]: props 🔀1, other schema contents 🔀3
[AWS::DMS::DataProvider]: props 🔀1, other schema contents 🔀3
[AWS::DMS::InstanceProfile]: props 🔀1, other schema contents 🔀3
[AWS::DataSync::LocationAzureBlob]: props 🔀3, other schema contents 🔀3
[AWS::DataSync::LocationHDFS]: props 🔀3, other schema contents 🔀3
[AWS::DataSync::LocationNFS]: props 🔀1, other schema contents 🔀3
[AWS::DataSync::LocationS3]: props 🔀1, other schema contents 🔀3
[AWS::DataSync::LocationSMB]: props 🔀1, other schema contents 🔀3
[AWS::Deadline::Farm]: props 🔀1, other schema contents 🔀3
[AWS::Deadline::Fleet]: props 🔀6, other schema contents 🔀3
[AWS::Deadline::Limit]: props 🔀1, other schema contents 🔀3
[AWS::Deadline::Queue]: props 🔀2, other schema contents 🔀3
[AWS::Detective::Graph]: props 🔀1, other schema contents 🔀3
[AWS::Detective::MemberInvitation]: props 🔀1, other schema contents 🔀3
[AWS::EC2::CustomerGateway]: props 🔀1, other schema contents 🔀3
[AWS::EC2::Instance]: props 🔀2, other schema contents 🔀3
[AWS::EC2::KeyPair]: props 🔀2, other schema contents 🔀3
[AWS::EC2::NetworkInterfaceAttachment]: props 🔀1, other schema contents 🔀3
[AWS::EC2::SpotFleet]: props 🔀1, other schema contents 🔀3
[AWS::EC2::VPNConnection]: props 🔀1, other schema contents 🔀3
[AWS::ECS::ExpressGatewayService]: props 🔀11, other schema contents 🔀2
[AWS::ECS::Service]: props 🔀2, other schema contents 🔀3
[AWS::ECS::TaskDefinition]: props 🔀1, other schema contents 🔀3
[AWS::EKS::Cluster]: props 🔀1, other schema contents 🔀3
[AWS::EKS::Nodegroup]: props 🔀1, other schema contents 🔀3
[AWS::EMRServerless::Application]: props 🔀6, other schema contents 🔀3
[AWS::ElasticLoadBalancingV2::LoadBalancer]: props 🔀1, other schema contents 🔀3
[AWS::EventSchemas::Discoverer]: props 🔀1, other schema contents 🔀3
[AWS::Events::Connection]: props 🔀6, other schema contents 🔀3
[AWS::GlobalAccelerator::Accelerator]: props 🔀2, other schema contents 🔀3
[AWS::GlobalAccelerator::EndpointGroup]: props 🔀7, other schema contents 🔀3
[AWS::GlobalAccelerator::Listener]: props 🔀2, other schema contents 🔀3
[AWS::HealthLake::FHIRDatastore]: props 🔀2, other schema contents 🔀3
[AWS::IVS::Channel]: props 🔀8, other schema contents 🔀3
[AWS::IVS::EncoderConfiguration]: props 🔀4, other schema contents 🔀3
[AWS::IVS::IngestConfiguration]: props 🔀5, other schema contents 🔀3
[AWS::IVS::PlaybackRestrictionPolicy]: props 🔀3, other schema contents 🔀3
[AWS::IVS::RecordingConfiguration]: props 🔀4, other schema contents 🔀3
[AWS::IVS::Stage]: props 🔀6, other schema contents 🔀3
[AWS::IVSChat::Room]: props 🔀3, other schema contents 🔀3
[AWS::IoT::RoleAlias]: props 🔀1, other schema contents 🔀3
[AWS::IoTEvents::AlarmModel]: props 🔀2, other schema contents 🔀3
[AWS::IoTFleetWise::Campaign]: props 🔀7, other schema contents 🔀3
[AWS::IoTFleetWise::DecoderManifest]: props 🔀1, other schema contents 🔀3
[AWS::IoTFleetWise::ModelManifest]: props 🔀1, other schema contents 🔀3
[AWS::KMS::Key]: props 🔀7, other schema contents 🔀3
[AWS::Kinesis::Stream]: props 🔀1, other schema contents 🔀3
[AWS::KinesisVideo::Stream]: props 🔀1, other schema contents 🔀3
[AWS::Lambda::CodeSigningConfig]: props 🔀1, other schema contents 🔀3
[AWS::Logs::LogGroup]: props 🔀1, other schema contents 🔀3
[AWS::Logs::QueryDefinition]: props 🔀1, other schema contents 🔀3
[AWS::Macie::Session]: props 🔀2, other schema contents 🔀3
[AWS::MediaConnect::FlowEntitlement]: props 🔀2, other schema contents 🔀3
[AWS::MediaConnect::FlowOutput]: props 🔀1, other schema contents 🔀3
[AWS::MediaConnect::FlowSource]: props 🔀1, other schema contents 🔀3
[AWS::MediaLive::CloudWatchAlarmTemplate]: props 🔀4, other schema contents 🔀3
[AWS::MediaLive::SignalMap]: props 🔀2, other schema contents 🔀3
[AWS::Neptune::DBCluster]: props 🔀2, other schema contents 🔀3
[AWS::Neptune::EventSubscription]: props 🔀1, other schema contents 🔀3
[AWS::NetworkManager::VpcAttachment]: props 🔀4, other schema contents 🔀3
[AWS::Organizations::Account]: props 🔀1, other schema contents 🔀3
[AWS::Organizations::Organization]: props 🔀1, other schema contents 🔀3
[AWS::PCS::Cluster]: props 🔀3, other schema contents 🔀3
[AWS::PaymentCryptography::Key]: props 🔀9, other schema contents 🔀3
[AWS::Pipes::Pipe]: props 🔀7, other schema contents 🔀3
[AWS::RDS::CustomDBEngineVersion]: props 🔀1, other schema contents 🔀3
[AWS::RDS::DBCluster]: props 🔀1, other schema contents 🔀3
[AWS::RDS::DBInstance]: other schema contents 🔀3
[AWS::RDS::EventSubscription]: props 🔀1, other schema contents 🔀3
[AWS::RedshiftServerless::Workgroup]: props 🔀2, other schema contents 🔀3
[AWS::S3::Bucket]: props 🔀2, other schema contents 🔀3
[AWS::S3Outposts::Endpoint]: props 🔀1, other schema contents 🔀3
[AWS::S3Tables::TableBucket]: props 🔀1, other schema contents 🔀3
[AWS::S3Vectors::VectorBucket]: props 🔀1, other schema contents 🔀3
[AWS::SSM::Document]: props 🔀2, other schema contents 🔀3
[AWS::SSM::PatchBaseline]: props 🔀6, other schema contents 🔀3
[AWS::SSMIncidents::ReplicationSet]: props 🔀2, other schema contents 🔀3
[AWS::SSMIncidents::ResponsePlan]: props 🔀7, other schema contents 🔀3
[AWS::SSO::PermissionSet]: props 🔀2, other schema contents 🔀3
[AWS::SageMaker::Cluster]: props 🔀1, other schema contents 🔀3
[AWS::SageMaker::ModelCard]: props 🔀8, other schema contents 🔀3
[AWS::Scheduler::Schedule]: props 🔀1, other schema contents 🔀3
[AWS::SecretsManager::Secret]: other schema contents 🔀3
[AWS::Timestream::InfluxDBInstance]: props 🔀1, other schema contents 🔀3
[AWS::Transfer::Connector]: props 🔀1, other schema contents 🔀3
[AWS::VerifiedPermissions::IdentitySource]: props 🔀2, other schema contents 🔀3
[AWS::VerifiedPermissions::PolicyStore]: props 🔀1, other schema contents 🔀3
[AWS::VpcLattice::Rule]: props 🔀2, other schema contents 🔀3
[AWS::VpcLattice::ServiceNetwork]: props 🔀1, other schema contents 🔀3
[AWS::VpcLattice::Service]: props 🔀1, other schema contents 🔀3
[AWS::VpcLattice::TargetGroup]: props 🔀3, other schema contents 🔀3
[AWS::Wisdom::AIGuardrail]: props 🔀1, other schema contents 🔀3
Hetzner - 0 new, 11 changed asset(s)
[Hetzner::Cloud::Certificates]: props 🔀1, other schema contents 🔀2
[Hetzner::Cloud::Firewalls]: other schema contents 🔀2
[Hetzner::Cloud::FloatingIps]: other schema contents 🔀2
[Hetzner::Cloud::LoadBalancers]: props 🔀6, other schema contents 🔀2
[Hetzner::Cloud::Networks]: other schema contents 🔀2
[Hetzner::Cloud::PlacementGroups]: other schema contents 🔀2
[Hetzner::Cloud::PrimaryIps]: props 🔀2, other schema contents 🔀2
[Hetzner::Cloud::Servers]: props 🔀3, other schema contents 🔀2
[Hetzner::Cloud::SshKeys]: other schema contents 🔀2
[Hetzner::Cloud::Volumes]: other schema contents 🔀2
[Hetzner::Cloud::Zones]: props 🔀4, other schema contents 🔀2
Microsoft - 0 new, 325 changed asset(s)
[Microsoft.AAD/domainServices]: props 🔀26, other schema contents 🔀2
[Microsoft.AVS/privateClouds]: props 🔀2, other schema contents 🔀2
[Microsoft.AlertsManagement/actionRules]: props 🔀2, other schema contents 🔀2
[Microsoft.AlertsManagement/smartDetectorAlertRules]: props 🔀2, other schema contents 🔀2
[Microsoft.AnalysisServices/servers]: props 🔀10, other schema contents 🔀2
[Microsoft.ApiManagement/service/backends]: props 🔀4, other schema contents 🔀1
[Microsoft.ApiManagement/service/policies]: props 🔀2, other schema contents 🔀1
[Microsoft.ApiManagement/service/policyFragments]: props 🔀2, other schema contents 🔀1
[Microsoft.ApiManagement/service/policyRestrictions]: props 🔀2, other schema contents 🔀1
[Microsoft.ApiManagement/service/portalconfigs]: props 🔀12, other schema contents 🔀1
[Microsoft.ApiManagement/service/users]: props 🔀2, other schema contents 🔀1
[Microsoft.ApiManagement/service]: props 🔀20, other schema contents 🔀2
[Microsoft.App/connectedEnvironments/daprComponents]: props 🔀2, other schema contents 🔀1
[Microsoft.App/containerApps]: props 🔀18, other schema contents 🔀2
[Microsoft.App/jobs]: props 🔀8, other schema contents 🔀2
[Microsoft.App/managedEnvironments/daprComponents]: props 🔀2, other schema contents 🔀1
[Microsoft.App/managedEnvironments/daprSubscriptions]: props 🔀2, other schema contents 🔀1
[Microsoft.App/sessionPools]: props 🔀2, other schema contents 🔀2
[Microsoft.AppConfiguration/configurationStores]: props 🔀6, other schema contents 🔀2
[Microsoft.AppPlatform/Spring/DevToolPortals]: props 🔀6, other schema contents 🔀1
[Microsoft.AppPlatform/Spring/apiPortals]: props 🔀10, other schema contents 🔀1
[Microsoft.AppPlatform/Spring/applicationAccelerators]: props 🔀4, other schema contents 🔀1
[Microsoft.AppPlatform/Spring/apps]: props 🔀12, other schema contents 🔀1
[Microsoft.AppPlatform/Spring/certificates]: props 🔀6, other schema contents 🔀1
[Microsoft.AppPlatform/Spring/configurationServices]: props 🔀2, other schema contents 🔀1
[Microsoft.AppPlatform/Spring/containerRegistries]: props 🔀6, other schema contents 🔀1
[Microsoft.AppPlatform/Spring/gateways]: props 🔀14, other schema contents 🔀1
[Microsoft.AppPlatform/Spring/jobs]: props 🔀10, other schema contents 🔀1
[Microsoft.AppPlatform/Spring]: props 🔀10, other schema contents 🔀2
[Microsoft.Attestation/attestationProviders]: props 🔀4, other schema contents 🔀2
[Microsoft.Automation/automationAccounts/schedules]: props 🔀1, other schema contents 🔀1
[Microsoft.Automation/automationAccounts/softwareUpdateConfigurations]: props 🔀2, other schema contents 🔀1
[Microsoft.Automation/automationAccounts/webhooks]: props 🔀1, other schema contents 🔀1
[Microsoft.AwsConnector/cloudFrontDistributions]: props 🔀18, other schema contents 🔀2
[Microsoft.AwsConnector/cloudWatchAlarms]: props 🔀2, other schema contents 🔀2
[Microsoft.AwsConnector/ec2KeyPairs]: props 🔀4, other schema contents 🔀2
[Microsoft.AwsConnector/ecsServices]: props 🔀2, other schema contents 🔀2
[Microsoft.AwsConnector/iamRoles]: props 🔀2, other schema contents 🔀2
[Microsoft.AwsConnector/kmsKeys]: props 🔀8, other schema contents 🔀2
[Microsoft.AwsConnector/logsLogGroups]: props 🔀2, other schema contents 🔀2
[Microsoft.AwsConnector/organizationsAccounts]: props 🔀2, other schema contents 🔀2
[Microsoft.AwsConnector/organizationsOrganizations]: props 🔀2, other schema contents 🔀2
[Microsoft.AwsConnector/rdsDBClusters]: props 🔀6, other schema contents 🔀2
[Microsoft.AwsConnector/rdsDBInstances]: props 🔀4, other schema contents 🔀2
[Microsoft.AwsConnector/rdsEventSubscriptions]: props 🔀2, other schema contents 🔀2
[Microsoft.AwsConnector/s3Buckets]: props 🔀4, other schema contents 🔀2
[Microsoft.AzureArcData/dataControllers/activeDirectoryConnectors]: props 🔀6, other schema contents 🔀1
[Microsoft.AzureArcData/dataControllers]: props 🔀2, other schema contents 🔀2
[Microsoft.AzureArcData/postgresInstances]: props 🔀4, other schema contents 🔀2
[Microsoft.AzureArcData/sqlManagedInstances]: props 🔀6, other schema contents 🔀2
[Microsoft.AzureDataTransfer/pipelines/flowProfiles]: props 🔀6, other schema contents 🔀1
[Microsoft.AzurePlaywrightService/accounts]: props 🔀8, other schema contents 🔀2
[Microsoft.AzureStackHCI/clusters/deploymentSettings]: props 🔀6, other schema contents 🔀1
[Microsoft.AzureStackHCI/clusters/securitySettings]: props 🔀6, other schema contents 🔀1
[Microsoft.AzureStackHCI/clusters]: props 🔀1, other schema contents 🔀2
[Microsoft.AzureStackHCI/loadBalancers]: props 🔀4, other schema contents 🔀2
[Microsoft.AzureStackHCI/virtualMachines]: props 🔀6, other schema contents 🔀2
[Microsoft.Batch/batchAccounts/pools]: props 🔀10, other schema contents 🔀1
[Microsoft.Batch/batchAccounts]: props 🔀4, other schema contents 🔀2
[Microsoft.BillingBenefits/maccs]: props 🔀2, other schema contents 🔀2
[Microsoft.BotService/botServices/channels]: props 🔀18, other schema contents 🔀1
[Microsoft.BotService/botServices/connections]: props 🔀2, other schema contents 🔀1
[Microsoft.BotService/botServices]: props 🔀8, other schema contents 🔀2
[Microsoft.Cache/redisEnterprise/databases]: props 🔀2, other schema contents 🔀1
[Microsoft.Cache/redis]: props 🔀4, other schema contents 🔀2
[Microsoft.Cdn/profiles/endpoints]: props 🔀8, other schema contents 🔀1
[Microsoft.CertificateRegistration/certificateOrders]: props 🔀6, other schema contents 🔀2
[Microsoft.CloudHealth/healthmodels/entities]: props 🔀6, other schema contents 🔀1
[Microsoft.CloudHealth/healthmodels/signaldefinitions]: props 🔀2, other schema contents 🔀1
[Microsoft.CodeSigning/codeSigningAccounts/certificateProfiles]: props 🔀10, other schema contents 🔀1
[Microsoft.CognitiveServices/accounts/encryptionScopes]: props 🔀2, other schema contents 🔀1
[Microsoft.CognitiveServices/accounts]: props 🔀2, other schema contents 🔀2
[Microsoft.Community/communityTrainings]: props 🔀2, other schema contents 🔀2
[Microsoft.ContainerInstance/containerGroupProfiles]: props 🔀2, other schema contents 🔀2
[Microsoft.ContainerInstance/containerGroups]: props 🔀2, other schema contents 🔀2
[Microsoft.ContainerInstance/ngroups]: props 🔀2, other schema contents 🔀2
[Microsoft.ContainerRegistry/registries/connectedRegistries]: props 🔀4, other schema contents 🔀1
[Microsoft.ContainerRegistry/registries/exportPipelines]: props 🔀2, other schema contents 🔀1
[Microsoft.ContainerRegistry/registries/importPipelines]: props 🔀6, other schema contents 🔀1
[Microsoft.ContainerRegistry/registries/pipelineRuns]: props 🔀7, other schema contents 🔀1
[Microsoft.ContainerRegistry/registries/replications]: props 🔀4, other schema contents 🔀1
[Microsoft.ContainerRegistry/registries/taskRuns]: props 🔀41, other schema contents 🔀1
[Microsoft.ContainerRegistry/registries/tasks]: props 🔀18, other schema contents 🔀1
[Microsoft.ContainerRegistry/registries]: props 🔀34, other schema contents 🔀2
[Microsoft.ContainerService/containerServices]: props 🔀6, other schema contents 🔀2
[Microsoft.ContainerService/managedClusters/agentPools]: props 🔀16, other schema contents 🔀1
[Microsoft.ContainerService/managedClusters/maintenanceConfigurations]: props 🔀2, other schema contents 🔀1
[Microsoft.ContainerService/managedClusters/managedNamespaces]: props 🔀4, other schema contents 🔀1
[Microsoft.ContainerService/managedClusters/namespaces]: props 🔀4, other schema contents 🔀1
[Microsoft.ContainerService/managedClusters]: props 🔀32, other schema contents 🔀2
[Microsoft.ContainerService/managedclustersnapshots]: props 🔀2, other schema contents 🔀2
[Microsoft.ContainerService/openShiftManagedClusters]: props 🔀6, other schema contents 🔀2
[Microsoft.ContainerService/snapshots]: props 🔀3, other schema contents 🔀2
[Microsoft.ContainerStorage/pools]: props 🔀4, other schema contents 🔀2
[Microsoft.DBforMySQL/flexibleServers]: props 🔀10, other schema contents 🔀2
[Microsoft.DBforPostgreSQL/flexibleServers]: props 🔀24, other schema contents 🔀2
[Microsoft.Dashboard/grafana]: props 🔀10, other schema contents 🔀2
[Microsoft.DataLakeAnalytics/accounts/storageAccounts]: props 🔀1, other schema contents 🔀1
[Microsoft.DataLakeAnalytics/accounts]: props 🔀11, other schema contents 🔀2
[Microsoft.DatabaseWatcher/watchers/targets]: props 🔀8, other schema contents 🔀1
[Microsoft.Databricks/workspaces]: props 🔀4, other schema contents 🔀2
[Microsoft.Datadog/monitors]: props 🔀2, other schema contents 🔀2
[Microsoft.DesktopVirtualization/scalingPlans/personalSchedules]: props 🔀8, other schema contents 🔀1
[Microsoft.DesktopVirtualization/scalingPlans]: props 🔀2, other schema contents 🔀2
[Microsoft.DevOpsInfrastructure/pools]: props 🔀6, other schema contents 🔀2
[Microsoft.DevTestLab/labs/formulas]: props 🔀10, other schema contents 🔀1
[Microsoft.DevTestLab/labs/schedules]: props 🔀4, other schema contents 🔀1
[Microsoft.DevTestLab/labs/virtualmachines]: props 🔀14, other schema contents 🔀1
[Microsoft.DevTestLab/labs]: props 🔀2, other schema contents 🔀2
[Microsoft.DevTestLab/schedules]: props 🔀4, other schema contents 🔀2
[Microsoft.DeviceRegistry/assetEndpointProfiles]: props 🔀2, other schema contents 🔀2
[Microsoft.DeviceRegistry/assets]: props 🔀6, other schema contents 🔀2
[Microsoft.DeviceRegistry/discoveredAssets]: props 🔀6, other schema contents 🔀2
[Microsoft.DeviceRegistry/namespaces/assets]: props 🔀14, other schema contents 🔀1
[Microsoft.DeviceRegistry/namespaces/devices]: props 🔀4, other schema contents 🔀1
[Microsoft.DeviceRegistry/namespaces/discoveredAssets]: props 🔀14, other schema contents 🔀1
[Microsoft.DeviceUpdate/accounts]: props 🔀5, other schema contents 🔀2
[Microsoft.Devices/IotHubs]: props 🔀4, other schema contents 🔀2
[Microsoft.DigitalTwins/digitalTwinsInstances/timeSeriesDatabaseConnections]: props 🔀6, other schema contents 🔀1
[Microsoft.DocumentDB/databaseAccounts/gremlinDatabases]: props 🔀2, other schema contents 🔀1
[Microsoft.DocumentDB/databaseAccounts/mongodbDatabases]: props 🔀2, other schema contents 🔀1
[Microsoft.DocumentDB/databaseAccounts/sqlDatabases]: props 🔀2, other schema contents 🔀1
[Microsoft.DocumentDB/databaseAccounts/tables]: props 🔀2, other schema contents 🔀1
[Microsoft.DocumentDB/databaseAccounts]: props 🔀4, other schema contents 🔀2
[Microsoft.DomainRegistration/domains]: props 🔀2, other schema contents 🔀2
[Microsoft.EdgeOrder/orderItems]: props 🔀9, other schema contents 🔀2
[Microsoft.ElasticSan/elasticSans/volumegroups]: props 🔀2, other schema contents 🔀1
[Microsoft.EventGrid/domains/eventSubscriptions]: props 🔀48, other schema contents 🔀1
[Microsoft.EventGrid/domains]: props 🔀10, other schema contents 🔀2
[Microsoft.EventGrid/namespaces/clients]: props 🔀2, other schema contents 🔀1
[Microsoft.EventGrid/namespaces/topics]: props 🔀2, other schema contents 🔀1
[Microsoft.EventGrid/namespaces]: props 🔀2, other schema contents 🔀2
[Microsoft.EventGrid/partnerNamespaces/eventChannels]: props 🔀2, other schema contents 🔀1
[Microsoft.EventGrid/partnerNamespaces]: props 🔀6, other schema contents 🔀2
[Microsoft.EventGrid/partnerTopics/eventSubscriptions]: props 🔀48, other schema contents 🔀1
[Microsoft.EventGrid/systemTopics/eventSubscriptions]: props 🔀48, other schema contents 🔀1
[Microsoft.EventGrid/topics/eventSubscriptions]: props 🔀48, other schema contents 🔀1
[Microsoft.EventGrid/topics]: props 🔀6, other schema contents 🔀2
[Microsoft.EventHub/namespaces]: props 🔀4, other schema contents 🔀2
[Microsoft.HDInsight/clusters/applications]: props 🔀2, other schema contents 🔀1
[Microsoft.HDInsight/clusters]: props 🔀9, other schema contents 🔀2
[Microsoft.HybridCompute/machines/runCommands]: props 🔀2, other schema contents 🔀1
[Microsoft.HybridCompute/privateLinkScopes]: props 🔀2, other schema contents 🔀2
[Microsoft.HybridConnectivity/publicCloudConnectors]: props 🔀2, other schema contents 🔀2
[Microsoft.HybridContainerService/provisionedClusters/agentPools]: props 🔀6, other schema contents 🔀1
[Microsoft.HybridContainerService/provisionedClusters]: props 🔀20, other schema contents 🔀2
[Microsoft.HybridNetwork/siteNetworkServices]: props 🔀2, other schema contents 🔀2
[Microsoft.ImportExport/jobs]: props 🔀11, other schema contents 🔀2
[Microsoft.Insights/actionGroups]: props 🔀16, other schema contents 🔀2
[Microsoft.Insights/activityLogAlerts]: props 🔀4, other schema contents 🔀2
[Microsoft.Insights/autoscalesettings]: props 🔀6, other schema contents 🔀2
[Microsoft.Insights/components]: props 🔀12, other schema contents 🔀2
[Microsoft.Insights/scheduledQueryRules]: props 🔀2, other schema contents 🔀2
[Microsoft.Insights/webtests]: props 🔀8, other schema contents 🔀2
[Microsoft.IoTOperations/instances/akriConnectorTemplates]: props 🔀5, other schema contents 🔀1
[Microsoft.IoTOperations/instances/brokers]: props 🔀33, other schema contents 🔀1
[Microsoft.IoTOperations/instances/dataflowEndpoints]: props 🔀49, other schema contents 🔀1
[Microsoft.IoTOperations/instances/dataflowProfiles]: props 🔀7, other schema contents 🔀1
[Microsoft.IoTOperations/instances/registryEndpoints]: props 🔀1, other schema contents 🔀1
[Microsoft.IoTOperations/instances]: props 🔀1, other schema contents 🔀2
[Microsoft.IoTOperationsMQ/mq/broker]: props 🔀44, other schema contents 🔀1
[Microsoft.IoTOperationsMQ/mq/dataLakeConnector]: props 🔀8, other schema contents 🔀1
[Microsoft.IoTOperationsMQ/mq/diagnosticService]: props 🔀12, other schema contents 🔀1
[Microsoft.IoTOperationsMQ/mq/kafkaConnector]: props 🔀10, other schema contents 🔀1
[Microsoft.IoTOperationsMQ/mq/mqttBridgeConnector]: props 🔀10, other schema contents 🔀1
[Microsoft.KeyVault/managedHSMs/keys]: props 🔀2, other schema contents 🔀1
[Microsoft.KeyVault/managedHSMs]: props 🔀8, other schema contents 🔀2
[Microsoft.KeyVault/vaults/keys]: props 🔀4, other schema contents 🔀1
[Microsoft.KeyVault/vaults]: props 🔀14, other schema contents 🔀2
[Microsoft.Kubernetes/connectedClusters]: props 🔀8, other schema contents 🔀2
[Microsoft.KubernetesConfiguration/privateLinkScopes]: props 🔀2, other schema contents 🔀2
[Microsoft.Kusto/clusters]: props 🔀20, other schema contents 🔀2
[Microsoft.LabServices/labPlans/images]: props 🔀2, other schema contents 🔀1
[Microsoft.LabServices/labPlans]: props 🔀14, other schema contents 🔀2
[Microsoft.LabServices/labs]: props 🔀18, other schema contents 🔀2
[Microsoft.LoadTestService/playwrightWorkspaces]: props 🔀4, other schema contents 🔀2
[Microsoft.MachineLearning/webServices]: props 🔀10, other schema contents 🔀2
[Microsoft.MachineLearningServices/registries/codes]: props 🔀2, other schema contents 🔀1
[Microsoft.MachineLearningServices/registries/components]: props 🔀2, other schema contents 🔀1
[Microsoft.MachineLearningServices/registries/data]: props 🔀2, other schema contents 🔀1
[Microsoft.MachineLearningServices/registries/environments]: props 🔀2, other schema contents 🔀1
[Microsoft.MachineLearningServices/registries/models]: props 🔀2, other schema contents 🔀1
[Microsoft.MachineLearningServices/workspaces/capabilityHosts]: props 🔀2, other schema contents 🔀1
[Microsoft.MachineLearningServices/workspaces/codes]: props 🔀2, other schema contents 🔀1
[Microsoft.MachineLearningServices/workspaces/components]: props 🔀2, other schema contents 🔀1
[Microsoft.MachineLearningServices/workspaces/data]: props 🔀2, other schema contents 🔀1
[Microsoft.MachineLearningServices/workspaces/datasets]: props 🔀2, other schema contents 🔀1
[Microsoft.MachineLearningServices/workspaces/datastores]: props 🔀10, other schema contents 🔀1
[Microsoft.MachineLearningServices/workspaces/environments]: props 🔀2, other schema contents 🔀1
[Microsoft.MachineLearningServices/workspaces/featuresets]: props 🔀2, other schema contents 🔀1
[Microsoft.MachineLearningServices/workspaces/featurestoreEntities]: props 🔀2, other schema contents 🔀1
[Microsoft.MachineLearningServices/workspaces/inferencePools]: props 🔀2, other schema contents 🔀1
[Microsoft.MachineLearningServices/workspaces/jobs]: props 🔀260, other schema contents 🔀1
[Microsoft.MachineLearningServices/workspaces/managedNetworks]: props 🔀2, other schema contents 🔀1
[Microsoft.MachineLearningServices/workspaces/models]: props 🔀2, other schema contents 🔀1
[Microsoft.MachineLearningServices/workspaces/onlineEndpoints]: props 🔀2, other schema contents 🔀1
[Microsoft.MachineLearningServices/workspaces/schedules]: props 🔀266, other schema contents 🔀1
[Microsoft.MachineLearningServices/workspaces]: props 🔀10, other schema contents 🔀2
[Microsoft.Maintenance/maintenanceConfigurations]: props 🔀2, other schema contents 🔀2
[Microsoft.ManagedNetworkFabric/accessControlLists]: props 🔀2, other schema contents 🔀2
[Microsoft.ManagedNetworkFabric/l2IsolationDomains]: props 🔀2, other schema contents 🔀2
[Microsoft.ManagedNetworkFabric/l3IsolationDomains/externalNetworks]: props 🔀7, other schema contents 🔀1
[Microsoft.ManagedNetworkFabric/l3IsolationDomains/internalNetworks]: props 🔀20, other schema contents 🔀1
[Microsoft.ManagedNetworkFabric/l3IsolationDomains]: props 🔀4, other schema contents 🔀2
[Microsoft.ManagedNetworkFabric/networkFabricControllers]: props 🔀9, other schema contents 🔀2
[Microsoft.ManagedNetworkFabric/networkFabrics/networkToNetworkInterconnects]: props 🔀11, other schema contents 🔀1
[Microsoft.ManagedNetworkFabric/networkFabrics]: props 🔀14, other schema contents 🔀2
[Microsoft.ManagedNetworkFabric/networkMonitors]: props 🔀12, other schema contents 🔀2
[Microsoft.ManagedNetworkFabric/networkTapRules]: props 🔀4, other schema contents 🔀2
[Microsoft.ManagedNetworkFabric/networkTaps]: props 🔀2, other schema contents 🔀2
[Microsoft.ManagedNetworkFabric/routePolicies]: props 🔀6, other schema contents 🔀2
[Microsoft.ManufacturingPlatform/manufacturingDataServices]: props 🔀2, other schema contents 🔀2
[Microsoft.Maps/accounts]: props 🔀4, other schema contents 🔀2
[Microsoft.Migrate/assessmentProjects/businessCases]: props 🔀22, other schema contents 🔀1
[Microsoft.Mission/communities]: props 🔀8, other schema contents 🔀2
[Microsoft.Mission/virtualEnclaves]: props 🔀12, other schema contents 🔀2
[Microsoft.MobileNetwork/mobileNetworks/services]: props 🔀10, other schema contents 🔀1
[Microsoft.MobileNetwork/mobileNetworks/simPolicies]: props 🔀4, other schema contents 🔀1
[Microsoft.MobileNetwork/packetCoreControlPlanes/packetCaptures]: props 🔀6, other schema contents 🔀1
[Microsoft.MobileNetwork/packetCoreControlPlanes]: props 🔀8, other schema contents 🔀2
[Microsoft.Monitor/pipelineGroups]: props 🔀6, other schema contents 🔀2
[Microsoft.NetApp/netAppAccounts/capacityPools]: props 🔀10, other schema contents 🔀1
[Microsoft.NetApp/netAppAccounts/volumeGroups]: props 🔀2, other schema contents 🔀1
[Microsoft.NetApp/netAppAccounts]: props 🔀4, other schema contents 🔀2
[Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies]: props 🔀5, other schema contents 🔀2
[Microsoft.Network/IpAllocations]: props 🔀2, other schema contents 🔀2
[Microsoft.Network/applicationGateways/privateEndpointConnections]: props 🔀4, other schema contents 🔀1
[Microsoft.Network/applicationGateways]: props 🔀4, other schema contents 🔀2
[Microsoft.Network/bastionHosts]: props 🔀18, other schema contents 🔀2
[Microsoft.Network/dnsForwardingRulesets/forwardingRules]: props 🔀2, other schema contents 🔀1
[Microsoft.Network/dnsResolvers/inboundEndpoints]: props 🔀2, other schema contents 🔀1
[Microsoft.Network/dnsZones]: props 🔀2, other schema contents 🔀1
[Microsoft.Network/dscpConfigurations]: props 🔀1, other schema contents 🔀2
[Microsoft.Network/frontDoors]: props 🔀4, other schema contents 🔀2
[Microsoft.Network/loadBalancers/backendAddressPools]: props 🔀1, other schema contents 🔀1
[Microsoft.Network/loadBalancers/inboundNatRules]: props 🔀8, other schema contents 🔀1
[Microsoft.Network/loadBalancers]: props 🔀5, other schema contents 🔀2
[Microsoft.Network/networkInterfaces/tapConfigurations]: props 🔀8, other schema contents 🔀1
[Microsoft.Network/networkInterfaces]: props 🔀16, other schema contents 🔀2
[Microsoft.Network/networkManagers/connectivityConfigurations]: props 🔀6, other schema contents 🔀1
[Microsoft.Network/networkManagers/routingConfigurations]: props 🔀2, other schema contents 🔀1
[Microsoft.Network/networkProfiles]: props 🔀2, other schema contents 🔀2
[Microsoft.Network/networkSecurityGroups]: props 🔀3, other schema contents 🔀2
[Microsoft.Network/networkWatchers/connectionMonitors]: props 🔀4, other schema contents 🔀1
[Microsoft.Network/networkWatchers/flowLogs]: props 🔀6, other schema contents 🔀1
[Microsoft.Network/networkWatchers/packetCaptures]: props 🔀14, other schema contents 🔀1
[Microsoft.Network/privateEndpoints]: props 🔀9, other schema contents 🔀2
[Microsoft.Network/privateLinkServices/privateEndpointConnections]: props 🔀4, other schema contents 🔀1
[Microsoft.Network/privateLinkServices]: props 🔀6, other schema contents 🔀2
[Microsoft.Network/publicIPAddresses]: props 🔀4, other schema contents 🔀2
[Microsoft.Network/routeTables]: props 🔀1, other schema contents 🔀2
[Microsoft.Network/serviceEndpointPolicies]: props 🔀1, other schema contents 🔀1
[Microsoft.Network/virtualHubs/ipConfigurations]: props 🔀10, other schema contents 🔀1
[Microsoft.Network/virtualNetworkTaps]: props 🔀14, other schema contents 🔀2
[Microsoft.Network/virtualNetworks/subnets]: props 🔀8, other schema contents 🔀1
[Microsoft.Network/virtualNetworks]: props 🔀7, other schema contents 🔀2
[Microsoft.NetworkCloud/cloudServicesNetworks]: props 🔀4, other schema contents 🔀2
[Microsoft.NetworkCloud/clusters]: props 🔀8, other schema contents 🔀2
[Microsoft.NetworkCloud/kubernetesClusters/agentPools]: props 🔀8, other schema contents 🔀1
[Microsoft.NetworkCloud/kubernetesClusters]: props 🔀18, other schema contents 🔀2
[Microsoft.NetworkCloud/l2Networks]: props 🔀2, other schema contents 🔀2
[Microsoft.NetworkCloud/l3Networks]: props 🔀6, other schema contents 🔀2
[Microsoft.NetworkCloud/trunkedNetworks]: props 🔀2, other schema contents 🔀2
[Microsoft.NetworkCloud/virtualMachines]: props 🔀12, other schema contents 🔀2
[Microsoft.NotificationHubs/namespaces]: props 🔀4, other schema contents 🔀2
[Microsoft.OperationalInsights/workspaces]: props 🔀4, other schema contents 🔀2
[Microsoft.Orbital/geoCatalogs]: props 🔀4, other schema contents 🔀2
[Microsoft.Purview/accounts/kafkaConfigurations]: props 🔀4, other schema contents 🔀1
[Microsoft.Purview/accounts]: props 🔀6, other schema contents 🔀2
[Microsoft.RecoveryServices/vaults/replicationFabrics]: props 🔀26, other schema contents 🔀1
[Microsoft.RecoveryServices/vaults/replicationPolicies]: props 🔀26, other schema contents 🔀1
[Microsoft.RecoveryServices/vaults/replicationProtectionIntents]: props 🔀26, other schema contents 🔀1
[Microsoft.Relay/namespaces]: props 🔀2, other schema contents 🔀2
[Microsoft.ResourceConnector/appliances]: props 🔀2, other schema contents 🔀2
[Microsoft.Resources/deploymentScripts]: props 🔀8, other schema contents 🔀2
[Microsoft.Resources/deploymentStacks]: props 🔀1, other schema contents 🔀2
[Microsoft.Scom/managedInstances]: props 🔀3, other schema contents 🔀2
[Microsoft.Search/searchServices/privateEndpointConnections]: props 🔀2, other schema contents 🔀1
[Microsoft.Search/searchServices]: props 🔀9, other schema contents 🔀2
[Microsoft.Security/iotSecuritySolutions]: props 🔀8, other schema contents 🔀2
[Microsoft.ServiceBus/namespaces]: props 🔀4, other schema contents 🔀2
[Microsoft.ServiceFabric/clusters/applications]: props 🔀28, other schema contents 🔀1
[Microsoft.ServiceFabric/clusters]: props 🔀10, other schema contents 🔀2
[Microsoft.ServiceFabric/managedClusters]: props 🔀4, other schema contents 🔀2
[Microsoft.SignalRService/signalR/replicas]: props 🔀4, other schema contents 🔀1
[Microsoft.SignalRService/signalR]: props 🔀16, other schema contents 🔀2
[Microsoft.SignalRService/webPubSub/hubs]: props 🔀4, other schema contents 🔀1
[Microsoft.SignalRService/webPubSub/replicas]: props 🔀4, other schema contents 🔀1
[Microsoft.SignalRService/webPubSub]: props 🔀14, other schema contents 🔀2
[Microsoft.Sql/managedInstances/dnsAliases]: props 🔀1, other schema contents 🔀1
[Microsoft.Sql/managedInstances/startStopSchedules]: props 🔀4, other schema contents 🔀1
[Microsoft.Sql/managedInstances/vulnerabilityAssessments]: props 🔀2, other schema contents 🔀1
[Microsoft.Sql/servers/vulnerabilityAssessments]: props 🔀2, other schema contents 🔀1
[Microsoft.SqlVirtualMachine/sqlVirtualMachines]: props 🔀9, other schema contents 🔀2
[Microsoft.Storage/storageAccounts]: props 🔀14, other schema contents 🔀2
[Microsoft.StorageCache/amlFilesystems/autoExportJobs]: props 🔀2, other schema contents 🔀1
[Microsoft.StorageCache/amlFilesystems/autoImportJobs]: props 🔀6, other schema contents 🔀1
[Microsoft.StorageCache/amlFilesystems/importJobs]: props 🔀6, other schema contents 🔀1
[Microsoft.StorageCache/amlFilesystems]: props 🔀2, other schema contents 🔀2
[Microsoft.StorageCache/caches/storageTargets]: props 🔀2, other schema contents 🔀1
[Microsoft.StorageCache/caches]: props 🔀12, other schema contents 🔀2
[Microsoft.StorageDiscovery/storageDiscoveryWorkspaces]: props 🔀2, other schema contents 🔀2
[Microsoft.StorageMover/storageMovers/agents]: props 🔀2, other schema contents 🔀1
[Microsoft.StreamAnalytics/streamingjobs/inputs]: props 🔀62, other schema contents 🔀1
[Microsoft.StreamAnalytics/streamingjobs/outputs]: props 🔀16, other schema contents 🔀1
[Microsoft.StreamAnalytics/streamingjobs/transformations]: props 🔀2, other schema contents 🔀1
[Microsoft.StreamAnalytics/streamingjobs]: props 🔀6, other schema contents 🔀2
[Microsoft.Synapse/workspaces/kustoPools]: props 🔀4, other schema contents 🔀1
[Microsoft.Synapse/workspaces/sqlPools]: props 🔀4, other schema contents 🔀1
[Microsoft.Synapse/workspaces/vulnerabilityAssessments]: props 🔀2, other schema contents 🔀1
[Microsoft.Synapse/workspaces]: props 🔀4, other schema contents 🔀2
[Microsoft.TestBase/testBaseAccounts/customImages]: props 🔀2, other schema contents 🔀1
[Microsoft.TestBase/testBaseAccounts/draftPackages]: props 🔀10, other schema contents 🔀1
[Microsoft.TestBase/testBaseAccounts/packages]: props 🔀3, other schema contents 🔀1
[Microsoft.VideoIndexer/accounts]: props 🔀2, other schema contents 🔀2
[Microsoft.VirtualMachineImages/imageTemplates]: props 🔀50, other schema contents 🔀2
[Microsoft.VoiceServices/communicationsGateways]: props 🔀12, other schema contents 🔀2
[Microsoft.Web/containerApps]: props 🔀4, other schema contents 🔀2
[Microsoft.Web/hostingEnvironments]: props 🔀2, other schema contents 🔀2
[Microsoft.Web/serverfarms]: props 🔀10, other schema contents 🔀2
[Microsoft.Web/sites/slots]: props 🔀18, other schema contents 🔀1
[Microsoft.Web/sites]: props 🔀18, other schema contents 🔀2
[Microsoft.Web/staticSites/customDomains]: props 🔀1, other schema contents 🔀1
[Microsoft.WindowsESU/multipleActivationKeys]: props 🔀2, other schema contents 🔀2
[Microsoft.Workloads/sapVirtualInstances]: props 🔀8, other schema contents 🔀2

@stack72
Copy link
Contributor Author

stack72 commented Nov 28, 2025

/diff Hetzner::Cloud::Certificates

@github-actions
Copy link

Working with Module Index at: https://module-index.systeminit.com

Diffed Hetzner::Cloud::Certificates with the module index:

Replaced value within contents of prop /root/domain/type at data/defaultValue:

"uploaded"

@aaron-dernley
Copy link
Contributor

A wonderful PR!

Comment on lines +61 to +64
// Load extra assets BEFORE generating asset funcs so they're included
// Extra assets skip AWS-specific transformations since they're manually defined
specs = await loadExtraAssets(specs, AWS_PROVIDER_CONFIG);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit torn on this. If you did this right after parse schema, you would get a lot more for free (credential, region, intrinsics, suggestions), but then you would have to override the funcs instead of blatting them out here.

Comment on lines +70 to +72

// Generate asset funcs (schemaVariantDefinition) for ALL assets
// This must happen after loadExtraAssets so extra assets are included
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure that a lot of these comments add much value. Claude tends to do this after you chastise it for being silly.

if ("createOnlyProperties" in schema && "readOnlyProperties" in schema) {
const cfSchema = schema as CfSchema;
return {
createOnly: normalizeOnlyProperties(cfSchema.createOnlyProperties),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am confused why this is here. I don't see how it's used. Maybe I'm missing something?

* SI's property path separator - vertical tab character.
* Used to construct hierarchical property paths like "root\x0Bdomain\x0BpropertyName"
*/
export const PROP_PATH_SEPARATOR = "\x0B";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This already exists in spec/sockets.ts. We can move it out of there.

Comment on lines +67 to +69
export function buildPropPath(parts: string[]): string {
return parts.join(PROP_PATH_SEPARATOR);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same with this.

* const filterName = findProp("Filters.Name"); // Array element property
* ```
*/
export function createPropFinder(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is interesting, but I wonder if findObjectProp() does almost the same thing?

* @param providerConfig - The provider configuration
* @returns Combined array of auto-generated and manually-managed asset specs
*/
export async function loadExtraAssets(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a lot of what's here almost feels like it should run as a separate pipeline. There's a lot of code that already exists in other parts of clover, especially around the func generation. Maybe we can reuse more of that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants