Skill v1.0.0
currentTrusted Publisher100/100version: "1.0.0" name: resource-designer description: Research SDK contracts, design Terraform schema approach, and compose a GitHub issue for a new resource, data source, ephemeral resource, or enhancement to an existing resource. USE FOR: analyzing SDK DTOs, determining design patterns (polymorphic flattening, immutability, enum filtering), and creating well-structured GitHub issues. INVOKES: GitHub MCP tools for issue creation, sdk-contract-navigator skill for SDK analysis.
Skill: Resource Designer
Research SDK contracts, design the Terraform schema approach, and compose a GitHub issue for a new resource, data source, ephemeral resource, or enhancement to an existing resource.
Prerequisites
- The user has described what they want to add or change
- Ideally,
#skill:sdk-contract-navigatorhas already been run to identify SDK availability - If the caller (resource-designer agent or user) has not provided a milestone name, this skill should prompt for one, then resolve it to a numeric milestone ID via the GitHub API
Step 1 — Resolve Milestone Name to Number
If a milestone name was provided (e.g. "2026-04"), resolve it to its numeric ID:
- Query the GitHub REST API:
`` GET /repos/microsoft/terraform-provider-fabric/milestones?state=all&per_page=100 ``
- Parse the response and find the milestone object where
titlematches the user's input (case-insensitive)
- Extract the
numberfield from that milestone object
- If no match is found, report an error with the list of available milestones and ask the user to retry
If no milestone was specified, set milestone: null and proceed.
Step 2 — Determine Issue Type
Choose the correct issue template based on what is being requested.
| Scenario | Title Prefix | Label | Template File | |
|---|---|---|---|---|
| New resource (Fabric Item or non-item) | [RS] | tf/resource | tfprovider_resource_request.yml | |
| New data source | [DS] | tf/data-source | tfprovider_data_source_request.yml | |
| New ephemeral resource | [EPH] | tf/ephemeral | tfprovider_ephemeral_resource_request.yml | |
| Enhancement to existing resource | [FEAT] | feature | feature_request.yml |
When to Use Each
- `[RS]` / `[DS]` — A completely new Terraform resource or data source that doesn't exist yet. Applies to both Fabric Items (Lakehouse, Eventhouse, etc.) and non-item resources (Connection, Shortcut, Gateway, Workspace Role Assignment, etc.)
- `[EPH]` — A new ephemeral resource (short-lived, not stored in state)
- `[FEAT]` — Adding new attributes to an existing resource, changing behavior, adding support for a new API feature on an existing resource, or any other enhancement that modifies existing code
If both a resource and data source are needed for the same Fabric resource, create two separate issues.
Step 3 — Extract Resource Details
From the user's description and SDK analysis, gather:
| Detail | How to Determine | |
|---|---|---|
| Resource name | fabric_<snake_case> — e.g. fabric_lakehouse, fabric_connection, fabric_shortcut | |
| Display name | PascalCase with spaces — e.g. "Lakehouse", "Connection", "Shortcut" | |
| API doc links | Browse learn.microsoft.com/rest/api/fabric/ for API pages | |
| SDK availability | Check if the SDK package/client exists (from #skill:sdk-contract-navigator) | |
| Resource category | Fabric Item (~60%) or non-item (~40%) — see below | |
| Item archetype | For Fabric Items only: basic, definition, properties, definition-properties, config-properties, config-definition-properties | |
| Complexity | easy (basic/definition), moderate (properties/non-item), hard (config-\*/complex non-item) | |
| Definition paths | For Fabric Items with definitions: fetch the definition article to list supported definition parts — see below | |
| Related resources | Existing resources that interact with this one | |
| Preview status | Check if the Fabric API is marked as preview | |
| SPN support | Check if the API supports service principal authentication |
Resource Category Identification
Fabric Items — Standard items managed in workspaces (Lakehouse, Eventhouse, SQL Database, Data Pipeline, Notebook, etc.). These use the fabricitem generic abstraction and have ItemType constants in the core SDK.
Non-item resources — Specialized resources with bespoke CRUD logic. Each belongs to an implementation pattern (A–H) that determines canonical reference, lifecycle semantics, and test structure:
| Pattern | Characteristic | SDK Client | Canonical Reference | |
|---|---|---|---|---|
| A | Workspace policy singleton (no ID, delete=reset) | fabcore.WorkspacesClient | internal/services/workspacencp/ | |
| B | Workspace settings (dedicated client, validators) | fabspark.* | internal/services/sparkwssettings/ | |
| C | Role assignment (parent+principal+role, ImportState) | Various *Client | internal/services/workspacera/ | |
| D | Batch assignment (immutable set, no update) | fabadmin.DomainsClient | internal/services/domainra/ | |
| E | Standalone entity, standard CRUD | Various dedicated clients | internal/services/workspace/ | |
| E | Standalone entity, polymorphic types | fabcore.GatewaysClient | internal/services/gateway/ | |
| E | Standalone entity, tenant-scoped | fabadmin.DomainsClient | internal/services/domain/ | |
| E | Standalone entity, connect/disconnect lifecycle | fabcore.GitClient | internal/services/workspacegit/ | |
| F | Item-scoped (workspace_id+item_id, 3+ path params) | fabcore.OneLakeShortcutsClient | internal/services/shortcut/ | |
| F | Item-scoped (ModifyPlan, conditional validation) | fabcore.JobSchedulerClient | internal/services/itemjobscheduler/ | |
| F | Item-scoped (simple CRUD, no Update) | fabcore.ExternalDataSharesClient | internal/services/externaldatashare/ | |
| G | Tenant-level, custom identity/delete semantics | fabadmin.TenantsClient | internal/services/tenantsetting/ | |
| H | Complex: dual clients, write-only secrets, KV refs | fabcore.ConnectionsClient | internal/services/connection/ |
Pattern classification decision tree:
Is it a workspace policy/settings with no real entity ID?├── YES → Uses WorkspacesClient sub-endpoint, delete=reset? → Pattern A│ Uses dedicated Spark/Environment client, ConfigValidators? → Pattern B│├── NO → Is it an assignment of principals/items to a parent?│ ├── Single-item assignment with updatable role, ImportState? → Pattern C│ └── Batch set assignment, fully immutable, no Import? → Pattern D│├── NO → Is it scoped to a specific item (workspace_id + item_id)?│ └── YES → Pattern F│├── NO → Is it a tenant-level admin resource with non-UUID identity or custom delete?│ └── YES → Pattern G│├── NO → Does it have write-only secrets, dual clients, KV references?│ └── YES → Pattern H│└── NO → Standalone entity with dedicated client → Pattern E
When composing the issue, include the pattern letter in the "Details / References" section so downstream agents can immediately route to the correct implementation reference.
Item Definition Paths
For Fabric Items that support definitions (archetypes: definition, definition-properties, config-definition-properties), fetch the item definition article to discover the supported definition parts/paths:
https://learn.microsoft.com/rest/api/fabric/articles/item-management/definitions/<item-kebab-case>-definition
For example:
- Notebook →
https://learn.microsoft.com/rest/api/fabric/articles/item-management/definitions/notebook-definition - Report →
https://learn.microsoft.com/rest/api/fabric/articles/item-management/definitions/report-definition - Spark Job Definition →
https://learn.microsoft.com/rest/api/fabric/articles/item-management/definitions/spark-job-definition-definition
Use the fetch_webpage tool to read the article and extract the list of definition paths (e.g. notebook-content.py, definition.pbir/report.json). Each definition part has a path and format. Record all supported definition paths for inclusion in the issue.
If the article does not exist or returns a 404, the item likely does not support definitions — adjust the archetype accordingly.
API Documentation URL Pattern
Fabric REST API docs follow this pattern (never include en-us locale):
https://learn.microsoft.com/rest/api/fabric/<service>/items
For non-item resources, the API path varies:
https://learn.microsoft.com/rest/api/fabric/core/connectionshttps://learn.microsoft.com/rest/api/fabric/core/shortcutshttps://learn.microsoft.com/rest/api/fabric/core/gatewayshttps://learn.microsoft.com/rest/api/fabric/core/workspaces
Step 3.5 — Terraform Design Analysis
After gathering SDK details (Step 3), analyze the DTOs to determine which design patterns apply to this resource. This produces the "🎨 Terraform Design Notes" section in the issue body, giving the implementor explicit guidance.
Analysis Checks
Perform each check by comparing the SDK DTOs discovered in Step 3:
| # | Check | How to Detect | Output | |
|---|---|---|---|---|
| 1 | Immutable fields | Fields present in Create<Resource>Request but absent from Update<Resource>Request (or no Update method exists) | List fields → RequiresReplace | |
| 2 | Computed-only fields | Fields in response DTO absent from all request DTOs | List fields → Computed: true + UseStateForUnknown | |
| 3 | Polymorphic flattening | Response/request DTO has an interface type, or a struct with a Type/Kind discriminator and variant-specific fields | Describe variants → separate optional nested blocks + ExactlyOneOf | |
| 4 | Write-only secrets | Request DTO has *Password/*Secret/*Token/*Key/*Credential fields absent from response DTO | List fields → WriteOnly: true + *_reference alternative | |
| 5 | Conditional fields | Properties that only apply when a type discriminator has a specific value (variant-specific fields) | List field→type mappings → NullIfAttributeIsOneOf/RequireIfAttributeIsOneOf | |
| 6 | Enum filtering | Possible*Values() contains values representing system-managed/read-only states that cannot be set via Create/Update | List values to exclude from OneOf validator | |
| 7 | Composite ID for import | Sub-resource with 3+ path parameters (e.g., workspace_id + item_id + name) | Describe import ID format |
Skip Conditions
- For basic Fabric Items (archetype
basicordefinitionwith no properties), checks 3–6 typically don't apply — skip them. - For enhancements (
[FEAT]), only run checks relevant to the new fields being added.
Step 4 — Compose Issue Title
| Type | Format | |
|---|---|---|
| New resource | [RS] fabric_<snake_case_name> | |
| New data source | [DS] fabric_<snake_case_name> | |
| New ephemeral | [EPH] fabric_<snake_case_name> | |
| Enhancement | [FEAT] <short description of enhancement> |
Step 5 — Compose Issue Body
For New Resources ([RS]) and Data Sources ([DS])
📝 Description
Use Job Story format:
When managing Microsoft Fabric infrastructure as code,I want to create/manage <ResourceName> resources via Terraform,so I can automate provisioning and maintain consistent <ResourceName> configurations across environments.
🔬 Details / References
For Fabric Items:
Important: Do NOT include SDK CRUD method signatures (e.g.Get,Create,Update,Delete,List,GetDefinition,UpdateDefinition) in the issue body. Fabric Items follow standardized method patterns determined by the archetype — listing them adds noise without value. Only include the SDK package, archetype, DTO fields (Properties/CreationPayload), enum types, and definition paths.
-Resource Name: `fabric_<snake_case_name>`-API documentation:-https://learn.microsoft.com/rest/api/fabric/<itemtype>/items/create-<item>-https://learn.microsoft.com/rest/api/fabric/<itemtype>/items/get-<item>-https://learn.microsoft.com/rest/api/fabric/<itemtype>/items/list-<items>-Definition article: https://learn.microsoft.com/rest/api/fabric/articles/item-management/definitions/<item-kebab-case>-definition-SDK Package: `github.com/microsoft/fabric-sdk-go/fabric/<package>`-Item Archetype: `<archetype>`-Definition Paths (if applicable):-`<path>` (format: `<format>`)-`<path>` (format: `<format>`)-Estimated complexity/effort: <easy|moderate|hard>-Preview: <yes|no>-SPN Supported: <yes|no>-Related resources/data-sources:-`fabric_workspace` (required parent)
For non-item resources:
-Resource Name: `fabric_<snake_case_name>`-API documentation:-https://learn.microsoft.com/rest/api/fabric/core/<service>/create-<resource>-https://learn.microsoft.com/rest/api/fabric/core/<service>/get-<resource>-https://learn.microsoft.com/rest/api/fabric/core/<service>/list-<resources>-SDK Client: `fabcore.<Resource>Client`-Resource Category: non-item (bespoke CRUD)-Implementation Pattern: <A|B|C|D|E|F|G|H> — <pattern description>-Estimated complexity/effort: <easy|moderate|hard>-Preview: <yes|no>-SPN Supported: <yes|no>-Related resources/data-sources:-<related resources>
Pattern key: A=Workspace policy singleton, B=Workspace settings (Spark), C=Role assignment, D=Batch assignment, E=Standalone entity, F=Item-scoped, G=Tenant-level custom, H=Connection (complex credentials)
🌳 DTO Nesting Depth Map (complex resources only)
Include this section only for `[RS]` and `[DS]` issues where the SDK DTOs have 3+ nesting levels (slices containing structs with nested slices/pointers to other structs). Skip for flat resources (Workspace, Domain, role assignments, basic Fabric Items without properties).
Render a tree showing the SDK DTO hierarchy with type annotations. This helps implementors plan model structs, set() methods, and SetNull(ctx) placement.
Format — use indented tree with type annotations at leaf/branch nodes:
<RootDTO>├── Field1 (string)├── Field2 (enum)├── NestedSlice []ChildDTO ← Level 1│ ├── ScalarField (string)│ ├── DeepSlice []GrandchildDTO ← Level 2│ │ ├── LeafSlice []string ← Level 3│ │ └── LeafField (enum)│ └── OptionalNested *AnotherDTO ← Level 2│ └── Items []ItemDTO ← Level 3└── OptionalTop *TopDTO ← Level 1└── Children []ChildDTO ← Level 2
Rules:
- Annotate slices as
[]Type, optional nested as*Type, scalars as(type) - Mark nesting levels with
← Level Ncomments on lines introducing a new struct depth - Only show fields that map to Terraform schema attributes (skip internal/wire-only fields)
- Maximum depth shown: 5 levels (truncate deeper with
...)
🎨 Terraform Design Notes
Include this section for all `[RS]` and `[DS]` issues. Populate from the analysis in Step 3.5. Only include applicable items — omit checks that returned no findings.
Format:
**Immutable fields** (→ `RequiresReplace`):-`<field_name>` — only in Create request, not updatable**Computed-only fields** (→ `Computed: true`):-`<field_name>` — response-only, server-generated**Polymorphic type** (→ separate optional blocks + `ExactlyOneOf`):-SDK type `<InterfaceName>` has variants: `<Variant1>`, `<Variant2>`, ...-Model as: `<variant_1> {}`, `<variant_2> {}` optional nested blocks**Write-only secrets** (→ `WriteOnly: true` + `*_reference` alternative):-`<field_name>` — credential/secret in request, absent from response**Conditional fields** (→ `NullIfAttributeIsOneOf` / `RequireIfAttributeIsOneOf`):-`<field_name>` only applies when `type == "<value>"`**Enum filtering** (→ exclude from `OneOf` validator):-`<EnumType>`: exclude `<Value1>`, `<Value2>` (system-managed/non-creatable)**Import ID format**:-`<workspace_id>/<item_id>/<name>` (composite)
🚧 Potential Terraform Configuration
Generate sample HCL based on SDK properties discovered and informed by the design notes above (use optional blocks for polymorphic types, add comments for immutable/computed fields):
resource "fabric_<snake_case_name>" "example" {display_name = "example"description = "Example resource"workspace_id = fabric_workspace.example.id# Item-specific attributes}
☑️ Acceptance Criteria
-[ ] Can create a new <ResourceName> with required attributes-[ ] Can read <ResourceName> by ID-[ ] Can update <ResourceName> mutable attributes-[ ] Can delete <ResourceName>-[ ] Can import existing <ResourceName>-[ ] Properties are correctly mapped from SDK response
✅ Definition of Done
For Resource:
-[ ] Data Transfer Objects (DTOs)-[ ] Resource Implementation-[ ] Resource Added to Provider-[ ] Unit Tests for Happy path-[ ] Unit Tests for Error path-[ ] Acceptance Tests-[ ] Example in the ./examples folder-[ ] Schema documentation in code-[ ] Updated auto-generated provider docs with `task docs`
For Data Source:
-[ ] Data Transfer Objects (DTOs)-[ ] Data-Source Implementation-[ ] Data-Source Added to Provider-[ ] Unit Tests for Happy path-[ ] Unit Tests for Error path-[ ] Acceptance Tests-[ ] Example in the ./examples folder-[ ] Schema documentation in code-[ ] Updated auto-generated provider docs with `task docs`
For Enhancements ([FEAT])
Use the feature_request.yml template structure.
🚀 Feature description
Job Story format describing the enhancement:
When using the existing `fabric_<resource>` resource,I want to <what is missing or needs to change>,so I can <expected outcome>.
🔈 Motivation
Explain why the enhancement is needed — e.g. new API capability, missing attribute, user request.
🛰 Alternatives
Describe workarounds or alternative approaches considered.
🔬 SDK Diff (from #skill:sdk-contract-navigator)
Compare the current SDK DTOs against the existing implementation to identify what's new. Include this section in the issue body so the implementor agent has a clear change list:
For Fabric Item enhancements:
### SDK DiffResource: `fabric_<snake_case_name>`Category: Fabric Item (`<archetype>`)Service package: `internal/services/<package>/`| Change | SDK Field | Go Type | Current Status || --------- | ----------------------------- | ------------------------ | --------------------------------- || + New | `Properties.<FieldName>` | `*string` | Not in `<item>PropertiesModel` || + New | `Properties.<NestedField>` | `*<NestedDTO>` | New sub-model needed || + New | `CreationPayload.<FieldName>` | `*bool` | Not in `<item>ConfigurationModel` || ~ Changed | `Properties.<FieldName>` | `*int32` (was `*string`) | Type change in model |
For non-item enhancements:
### SDK DiffResource: `fabric_<snake_case_name>`Category: non-item (bespoke CRUD)Service package: `internal/services/<package>/`SDK Client: `fabcore.<Resource>Client`| Change | SDK Field | Go Type | Current Status || ------------ | --------------------------- | --------- | --------------------------------------- || + New | `<ResponseDTO>.<FieldName>` | `*string` | Not in `base<Resource>Model` || + New | `<RequestDTO>.<FieldName>` | `*bool` | Not in `request<Action><Resource>Model` || + New method | `client.<NewMethod>(...)` | — | No CRUD handler |
🚧 Potential Configuration / Desired Solution
Show HCL demonstrating the desired new behavior:
resource "fabric_<existing_resource>" "example" {# existing attributes...# NEW: proposed enhancementnew_attribute = "value"}
☑️ Acceptance Criteria
-[ ] New attribute `<name>` is added to the schema-[ ] SDK mapping is correct for new fields-[ ] `set()` methods updated for new fields-[ ] Fakes updated with new field test data-[ ] Existing tests still pass-[ ] New test assertions for added attributes-[ ] Documentation updated
Step 6 — Create the Issue
Use the GitHub MCP server create_issue tool:
owner: microsoftrepo: terraform-provider-fabrictitle: <composed title from Step 4>body: <composed body from Step 5>labels: [<appropriate label>]milestone: <resolved milestone number from Step 1, or null if not specified>
Label mapping:
[RS]→["tf/resource"][DS]→["tf/data-source"][EPH]→["tf/ephemeral"][FEAT]→["feature"]
Step 7 — Report Back
After creating the issue, report:
- Issue number and URL
- Summary of what was filed
- Resource category (Fabric Item vs non-item) and archetype (if applicable)
- Any gaps or unknowns that need follow-up (e.g. API not yet public, SDK package missing)