Skip to content

Commit 1c07f6d

Browse files
committed
chore(dev): introduce ADR-007 for resource type name migration to shorter prefix
Signed-off-by: Pavel Boldyrev <pavel@bpg.sh>
1 parent 4ffb2f1 commit 1c07f6d

File tree

4 files changed

+167
-16
lines changed

4 files changed

+167
-16
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ coverage.out
6161
*_PLAN.md
6262
*_SESSION_STATE.md
6363
*_PR_BODY.md
64+
*_COMMENT.md
6465
.dev/archive/
6566

6667
# Python cache

docs/adr/003-resource-file-organization.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,15 @@ Optional additional files:
6363

6464
### Naming Conventions
6565

66-
| Element | Convention | Example |
67-
|---------------------------|-----------------------------------------------|---------------------------------------------------------|
68-
| Package names | Lowercase, singular noun matching API domain | `zone`, `vnet`, `subnet`, multi-word: `hardwaremapping` |
69-
| Terraform attribute names | `snake_case` | `isolate_ports`, `vlan_aware` |
70-
| Go struct fields | PascalCase with `tfsdk` tag | `IsolatePorts types.Bool \`tfsdk:"isolate_ports"\`` |
71-
| Resource type names | `proxmox_virtual_environment_{domain}_{name}` | `proxmox_virtual_environment_sdn_vnet` |
72-
| Test function names | `TestAcc{Resource}{Scenario}` | `TestAccResourceSDNVNet` |
73-
| Constructor functions | `NewResource()`, `NewDataSource()` ||
66+
| Element | Convention | Example |
67+
|---------------------------|----------------------------------------------------------------------------|---------------------------------------------------------|
68+
| Package names | Lowercase, singular noun matching API domain | `zone`, `vnet`, `subnet`, multi-word: `hardwaremapping` |
69+
| Terraform attribute names | `snake_case` | `isolate_ports`, `vlan_aware` |
70+
| Go struct fields | PascalCase with `tfsdk` tag | `IsolatePorts types.Bool \`tfsdk:"isolate_ports"\`` |
71+
| Resource type names (new) | `proxmox_{domain}_{name}` ([ADR-007](007-resource-type-name-migration.md)) | `proxmox_sdn_vnet` |
72+
| Resource type names (old) | `proxmox_virtual_environment_{domain}_{name}` (legacy, pre-ADR-007) | `proxmox_virtual_environment_sdn_vnet` |
73+
| Test function names | `TestAcc{Resource}{Scenario}` | `TestAccResourceSDNVNet` |
74+
| Constructor functions | `NewResource()`, `NewDataSource()` ||
7475

7576
### Test Colocation
7677

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
# ADR-007: Resource Type Name Migration
2+
3+
## Status
4+
5+
Accepted
6+
7+
## Date
8+
9+
2026-03-13
10+
11+
## Context
12+
13+
All resources in this provider use the prefix `proxmox_virtual_environment_` (29 characters), making resource type names verbose and hard to scan. For example, `proxmox_virtual_environment_hagroup`, `proxmox_virtual_environment_network_linux_bridge`. Users and IDE tooling must skip past this boilerplate to reach the meaningful portion of the name. The community has requested shorter prefixes (see [#2133](https://github.com/bpg/terraform-provider-proxmox/issues/2133), [#1231](https://github.com/bpg/terraform-provider-proxmox/issues/1231)).
14+
15+
### Constraints Investigated
16+
17+
Three candidate prefixes were evaluated: `pve_`, `proxmox_`, and `proxmox_virtual_environment_` (status quo).
18+
19+
**Terraform's implied provider resolution** is the binding constraint. Terraform extracts the first word before `_` from a resource type name to determine which provider manages it:
20+
21+
- `proxmox_virtual_environment_hagroup` -> implied provider = `proxmox` (matches `bpg/proxmox`)
22+
- `proxmox_hagroup` -> implied provider = `proxmox` (matches `bpg/proxmox`)
23+
- `pve_hagroup` -> implied provider = `pve` (no match — would require a `pve` local name)
24+
25+
For `pve_*` resources to auto-resolve, users would need to declare `pve = { source = "bpg/proxmox" }` in `required_providers`. However, Terraform warns against (and has bugs with) declaring the same source under two local names since v1.2 ([terraform#31196](https://github.com/hashicorp/terraform/issues/31196), [terraform#31218](https://github.com/hashicorp/terraform/pull/31218)). This makes `pve_` impractical without a separate provider binary or registry entry.
26+
27+
**Plugin Framework and Mux** impose no prefix constraints — resource TypeNames can be any non-empty unique string. The prefix convention is advisory only. Both `proxmox_virtual_environment_*` and `proxmox_*` resources can coexist in the same provider binary.
28+
29+
### Summary of Options
30+
31+
| Prefix | Auto-resolves? | Single provider config? | Breaking change? |
32+
|---------------------------------------------|----------------|-----------------------------|------------------|
33+
| `proxmox_virtual_environment_` (status quo) | Yes | Yes | No |
34+
| `proxmox_` | Yes | Yes | Yes (v1.0) |
35+
| `pve_` | No | No (needs `pve` local name) | Yes + UX cost |
36+
37+
## Decision
38+
39+
Adopt `proxmox_` as the resource type name prefix, migrated in three phases.
40+
41+
### Phase 1: New Resources (immediate, pre-v1.0)
42+
43+
All new Framework resources use the `proxmox_` prefix by hardcoding the TypeName:
44+
45+
```go
46+
func (r *haRuleResource) Metadata(_ context.Context, _ resource.MetadataRequest, resp *resource.MetadataResponse) {
47+
resp.TypeName = "proxmox_harule"
48+
}
49+
```
50+
51+
The provider's `MetadataResponse.TypeName` remains `"proxmox_virtual_environment"` — it is not changed. Existing resources continue using `req.ProviderTypeName + "_suffix"` unchanged.
52+
53+
**No breaking changes in this phase.**
54+
55+
### Phase 2: Rename Framework Resources (pre-v1.0, transition)
56+
57+
For each existing **Framework** resource, register a second resource struct with the short name alongside the original. The original emits a deprecation warning.
58+
59+
This phase applies only to Framework resources (`fwprovider/`). SDK resources are handled separately in Phase 3.
60+
61+
```go
62+
// Short-name alias wrapping the original implementation
63+
type haGroupShort struct{ haGroupResource }
64+
65+
func (r *haGroupShort) Metadata(_ context.Context, _ resource.MetadataRequest, resp *resource.MetadataResponse) {
66+
resp.TypeName = "proxmox_hagroup"
67+
}
68+
69+
func (r *haGroupShort) MoveState(ctx context.Context) []resource.StateMover {
70+
return []resource.StateMover{{
71+
StateMover: func(ctx context.Context, req resource.MoveStateRequest, resp *resource.MoveStateResponse) {
72+
if req.SourceTypeName != "proxmox_virtual_environment_hagroup" {
73+
return
74+
}
75+
// Schema is identical — copy state as-is
76+
resp.TargetState.Raw = req.SourceRawState
77+
},
78+
}}
79+
}
80+
```
81+
82+
Users migrate at their own pace using Terraform's `moved` block (requires Terraform >= 1.8):
83+
84+
```hcl
85+
moved {
86+
from = proxmox_virtual_environment_hagroup.example
87+
to = proxmox_hagroup.example
88+
}
89+
```
90+
91+
**No breaking changes in this phase** — both names work simultaneously.
92+
93+
### Phase 3: Migrate SDK Resources to Framework (v1.0)
94+
95+
SDK resources (`proxmoxtf/`) are feature-frozen. As part of v1.0, each SDK resource is rewritten in the Framework provider with the new `proxmox_*` name directly. The old `proxmox_virtual_environment_*` SDK registrations are removed.
96+
97+
Additionally, any remaining long-name Framework resources from Phase 2 that still have dual registrations have their old names removed.
98+
99+
After v1.0, only `proxmox_*` names remain across the entire provider.
100+
101+
**This is a breaking change**, requiring the v1.0 major version bump.
102+
103+
### Scope
104+
105+
This ADR covers **resource type name prefix migration only**. It does not cover SDK-to-Framework schema migration, which is a separate concern with its own state transformation requirements. SDK resources being rewritten in the Framework may have different schemas; those migrations require dedicated `MoveState` implementations that handle attribute mapping, not just prefix renaming.
106+
107+
### Naming Convention Update
108+
109+
This ADR supersedes the resource type name convention in [ADR-003](003-resource-file-organization.md):
110+
111+
| Element | Old Convention | New Convention |
112+
|---------------------|------------------------------------------------|---------------------------|
113+
| Resource type names | `proxmox_virtual_environment_{domain}_{name}` | `proxmox_{domain}_{name}` |
114+
115+
New resources **must** use the `proxmox_` prefix. Existing resources retain their current names until Phase 2.
116+
117+
## Consequences
118+
119+
### Positive
120+
121+
- Resource names are 20+ characters shorter (e.g., `proxmox_hagroup` vs `proxmox_virtual_environment_hagroup`)
122+
- Better IDE autocomplete and Terraform registry browsing
123+
- Both old and new names auto-resolve to the `proxmox` provider — no user configuration changes needed
124+
- `moved` block support provides a smooth migration path
125+
- No separate provider binary or registry entry required
126+
127+
### Negative
128+
129+
- Dual registration in Phase 2 increases the number of registered resources temporarily
130+
- Phase 3 (v1.0) is a breaking change requiring user migration
131+
- `MoveState` / cross-type `moved` blocks require Terraform >= 1.8; older versions need manual `terraform state mv`
132+
- Provider TypeName stays as `proxmox_virtual_environment` which is inconsistent with the new resource prefix — acceptable since it's an internal detail not visible to users
133+
134+
### Migration Risk
135+
136+
For Framework resource renames (Phase 2), the state migration is low-risk: schemas are identical between old and new names, so `MoveState` simply copies the raw state. No attribute transformation is needed.
137+
138+
SDK-to-Framework migrations (Phase 3) carry higher risk due to potential schema differences and are scoped separately from this ADR.
139+
140+
## References
141+
142+
- [#2133: Reduce "proxmox_virtual_environment_" prefix](https://github.com/bpg/terraform-provider-proxmox/issues/2133)
143+
- [#1231: Related discussion on prefix naming](https://github.com/bpg/terraform-provider-proxmox/issues/1231)
144+
- [ADR-003: Resource File Organization](003-resource-file-organization.md) — naming conventions (superseded for type names)
145+
- [Terraform Plugin Framework: State Move](https://developer.hashicorp.com/terraform/plugin/framework/resources/state-move)
146+
- [Terraform: Moved Block](https://developer.hashicorp.com/terraform/language/modules/develop/refactoring)
147+
- [Terraform: Provider Requirements](https://developer.hashicorp.com/terraform/language/providers/requirements) — implied provider resolution
148+
- [terraform#31196](https://github.com/hashicorp/terraform/issues/31196) — duplicate source in required_providers bug

docs/adr/README.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ This directory contains Architecture Decision Records (ADRs) for terraform-provi
44

55
## ADRs
66

7-
| ADR | Title | Summary |
8-
|------------------------------------------|----------------------------|--------------------------------------------------------------------------------------|
9-
| [001](001-use-plugin-framework.md) | Use Plugin Framework | All new resources use Terraform Plugin Framework, not SDKv2 |
10-
| [002](002-api-client-structure.md) | API Client Structure | Layered domain clients in `proxmox/` with `ExpandPath()` pattern |
11-
| [003](003-resource-file-organization.md) | Resource File Organization | Domain hierarchy, 3-file pattern, naming conventions |
12-
| [004](004-schema-design-conventions.md) | Schema Design Conventions | Attribute types, validators, model-API conversion, `CheckDelete` |
13-
| [005](005-error-handling.md) | Error Handling | `"Unable to [Action] [Resource]"` format, 3-layer error architecture, retry policies |
14-
| [006](006-testing-requirements.md) | Testing Requirements | Acceptance tests required, table-driven structure, test helpers |
7+
| ADR | Title | Summary |
8+
|--------------------------------------------|------------------------------|--------------------------------------------------------------------------------------|
9+
| [001](001-use-plugin-framework.md) | Use Plugin Framework | All new resources use Terraform Plugin Framework, not SDKv2 |
10+
| [002](002-api-client-structure.md) | API Client Structure | Layered domain clients in `proxmox/` with `ExpandPath()` pattern |
11+
| [003](003-resource-file-organization.md) | Resource File Organization | Domain hierarchy, 3-file pattern, naming conventions |
12+
| [004](004-schema-design-conventions.md) | Schema Design Conventions | Attribute types, validators, model-API conversion, `CheckDelete` |
13+
| [005](005-error-handling.md) | Error Handling | `"Unable to [Action] [Resource]"` format, 3-layer error architecture, retry policies |
14+
| [006](006-testing-requirements.md) | Testing Requirements | Acceptance tests required, table-driven structure, test helpers |
15+
| [007](007-resource-type-name-migration.md) | Resource Type Name Migration | Migrate from `proxmox_virtual_environment_` to `proxmox_` prefix in 3 phases |
1516

1617
## Reading Order for New Resource Implementation
1718

0 commit comments

Comments
 (0)