sureshanaparti opened a new issue, #333: URL: https://github.com/apache/cloudstack-terraform-provider/issues/333
## Summary The provider is already a muxed provider serving both `terraform-plugin-sdk/v2` and `terraform-plugin-framework` behind a single protocol-v6 endpoint, but only 3 of 95 resource types have been migrated to the framework. This issue tracks migrating the remaining 63 resources and 29 data sources. ## Current state `main.go` combines two provider servers via `tf6muxserver`: - `providerserver.NewProtocol6(cloudstack.New())` — framework provider, defined in `cloudstack/provider_v6.go` - `cloudstack.Provider().GRPCProvider` — SDKv2 provider, wrapped by `tf5to6server.UpgradeServer()` to bridge protocol 5 → 6 Split of resource types by SDK: | | Resources | Data sources | |---|---|---| | SDKv2 (`cloudstack/provider.go`) | 63 | 29 | | Framework (`CloudstackProvider.Resources()`) | 3 | 0 | Already on the framework: `cloudstack_service_offering_constrained`, `cloudstack_service_offering_fixed`, `cloudstack_service_offering_unconstrained`. 100 of the ~109 Go files under `cloudstack/` still import `terraform-plugin-sdk/v2`; 9 import the framework. Relevant dependencies in `go.mod` — both SDKs and the mux are already present, so no dependency work is needed: | Module | Version | |---|---| | `terraform-plugin-framework` | v1.12.0 | | `terraform-plugin-framework-validators` | v0.12.0 | | `terraform-plugin-mux` | v0.16.0 | | `terraform-plugin-go` | v0.24.0 | | `terraform-plugin-sdk/v2` | v2.33.0 | | `terraform-plugin-testing` | v1.7.0 | | Go | 1.23.0 | ## Motivation Per [HashiCorp's framework benefits page](https://developer.hashicorp.com/terraform/plugin/framework-benefits), HashiCorp has stopped most feature development on SDKv2 and recommends the framework for new development and for migrating existing providers. Staying on SDKv2 for the bulk of the provider costs us: - **Null vs unknown vs zero.** SDKv2 conflates "unset", `""`, `0` and `false`, so optional attributes cannot distinguish "user did not set this" from "user set the zero value". - **No provider-defined functions.** - **No ephemeral resources / write-only attributes**, the modern mechanism for handling short-lived secrets (API keys, VM passwords, Kubernetes cluster configs) without persisting them in state. - **No list operations** for discovering unmanaged resources. - Two schema idioms in one repo, so every new contribution has to pick a side. ## Scope Port each remaining SDKv2 resource and data source to the framework: remove it from `ResourcesMap`/`DataSourcesMap` and register it in `CloudstackProvider.Resources()`/`DataSources()`. Once the lists below are complete, `terraform-plugin-sdk/v2`, `cloudstack/provider.go` and the `tf5to6server` bridge in `main.go` can be removed. No user-facing HCL change is expected or intended: attribute names, block shapes and semantics must be preserved, and upgrading from the last SDKv2 release should produce an empty plan for every resource type. The in-tree reference pattern is `cloudstack/service_offering_*.go` together with `cloudstack/provider_v6.go`. ## Notes for implementers - A resource type may be served by exactly **one** server in the mux. Registering a type with the framework while it remains in `ResourcesMap` makes the mux server fail at startup with a duplicate-type error, so both changes belong in the same commit. - Every SDKv2 `ForceNew: true` must be reproduced as a `RequiresReplace()` plan modifier on the same attribute. There are 296 across 59 files. - `ConflictsWith` (16 uses), `ValidateFunc` (11), `CustomizeDiff` (13) and `DiffSuppressFunc` (1) become framework validators and plan modifiers. - `ImportState` must be written explicitly for the 45 files that currently have an `Importer`. - There are no `StateUpgraders`, `MigrateState`, `Timeouts` blocks, partial state or `resource.Retry` uses anywhere in the SDKv2 surface. - 35 `schema.TypeSet` and 22 `schema.TypeList` uses need a deliberate choice between nested blocks and nested attributes; turning a block into an attribute is a config-breaking change. - The `cloudstack-go` call sites port verbatim — `NewCreate*Params` / `Set*` are identical on both sides. Only the surrounding plumbing changes. - Acceptance tests largely survive unchanged; `terraform-plugin-testing` is already a dependency and is protocol-agnostic. ## Resources (63) - [ ] `cloudstack_account` - [ ] `cloudstack_affinity_group` - [ ] `cloudstack_attach_volume` - [ ] `cloudstack_autoscale_policy` - [ ] `cloudstack_autoscale_vm_group` - [ ] `cloudstack_autoscale_vm_profile` - [ ] `cloudstack_cluster` - [ ] `cloudstack_cni_configuration` - [ ] `cloudstack_condition` - [ ] `cloudstack_configuration` - [ ] `cloudstack_counter` - [ ] `cloudstack_disk` - [ ] `cloudstack_disk_offering` - [ ] `cloudstack_domain` - [ ] `cloudstack_egress_firewall` - [ ] `cloudstack_firewall` - [ ] `cloudstack_host` - [ ] `cloudstack_instance` - [ ] `cloudstack_ipaddress` - [ ] `cloudstack_kubernetes_cluster` - [ ] `cloudstack_kubernetes_version` - [ ] `cloudstack_limits` - [ ] `cloudstack_loadbalancer` - [ ] `cloudstack_loadbalancer_rule` - [ ] `cloudstack_network` - [ ] `cloudstack_network_acl` - [ ] `cloudstack_network_acl_rule` - [ ] `cloudstack_network_acl_ruleset` - [ ] `cloudstack_network_offering` - [ ] `cloudstack_network_service_provider` - [ ] `cloudstack_network_service_provider_state` - [ ] `cloudstack_nic` - [ ] `cloudstack_physical_network` - [ ] `cloudstack_pod` - [ ] `cloudstack_port_forward` - [ ] `cloudstack_private_gateway` - [ ] `cloudstack_project` - [ ] `cloudstack_quota_tariff` - [ ] `cloudstack_role` - [ ] `cloudstack_role_permission` - [ ] `cloudstack_secondary_ipaddress` - [ ] `cloudstack_secondary_storage` - [ ] `cloudstack_security_group` - [ ] `cloudstack_security_group_rule` - [ ] `cloudstack_service_offering` - [ ] `cloudstack_snapshot_policy` - [ ] `cloudstack_ssh_keypair` - [ ] `cloudstack_static_nat` - [ ] `cloudstack_static_route` - [ ] `cloudstack_storage_network_ip_range` - [ ] `cloudstack_storage_pool` - [ ] `cloudstack_template` - [ ] `cloudstack_traffic_type` - [ ] `cloudstack_user` - [ ] `cloudstack_user_data` - [ ] `cloudstack_vlan_ip_range` - [ ] `cloudstack_volume` - [ ] `cloudstack_vpc` - [ ] `cloudstack_vpc_offering` - [ ] `cloudstack_vpn_connection` - [ ] `cloudstack_vpn_customer_gateway` - [ ] `cloudstack_vpn_gateway` - [ ] `cloudstack_zone` ## Data sources (29) - [ ] `cloudstack_autoscale_policy` - [ ] `cloudstack_autoscale_vm_group` - [ ] `cloudstack_autoscale_vm_profile` - [ ] `cloudstack_cluster` - [ ] `cloudstack_condition` - [ ] `cloudstack_counter` - [ ] `cloudstack_domain` - [ ] `cloudstack_instance` - [ ] `cloudstack_ipaddress` - [ ] `cloudstack_kubernetes_cluster_config` - [ ] `cloudstack_limits` - [ ] `cloudstack_network_offering` - [ ] `cloudstack_physical_network` - [ ] `cloudstack_pod` - [ ] `cloudstack_project` - [ ] `cloudstack_quota` - [ ] `cloudstack_quota_enabled` - [ ] `cloudstack_quota_tariff` - [ ] `cloudstack_role` - [ ] `cloudstack_service_offering` - [ ] `cloudstack_ssh_keypair` - [ ] `cloudstack_template` - [ ] `cloudstack_user` - [ ] `cloudstack_user_data` - [ ] `cloudstack_volume` - [ ] `cloudstack_vpc` - [ ] `cloudstack_vpc_offering` - [ ] `cloudstack_vpn_connection` - [ ] `cloudstack_zone` ## Teardown once the above is complete - [ ] Remove `terraform-plugin-sdk/v2` from `go.mod` - [ ] Remove the `tf5to6server` bridge from `main.go` - [ ] Delete `cloudstack/provider.go` and the SDKv2 test helpers ## Related findings - `cloudstack_service_offering` (SDKv2) coexists with the three framework `cloudstack_service_offering_*` resources, giving two ways to create a service offering. Needs a decision on whether the older one is deprecated. ## References - [Terraform Plugin Framework benefits](https://developer.hashicorp.com/terraform/plugin/framework-benefits) - [Migrate from SDKv2 to the plugin framework](https://developer.hashicorp.com/terraform/plugin/framework/migrating) - [Migrating providers](https://developer.hashicorp.com/terraform/plugin/framework/migrating/providers) - [terraform-plugin-mux](https://github.com/hashicorp/terraform-plugin-mux) - In-tree reference pattern: `cloudstack/service_offering_*.go`, `cloudstack/provider_v6.go`, `main.go` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
