Framework and SDKv2 Feature Comparison
We recommend using the plugin framework to develop your provider because it offers significant benefits in comparison to SDKv2. We designed the framework with feedback from thousands of existing providers, so the framework significantly improves upon the functionality available in SDKv2.
This page is a continuation of the Framework Benefits page, which describes the higher level coding improvements over SDKv2. The following features are only available in the framework.
Expanded Access to Configuration, Plan, and State Data
Providers receive up to three sources of schema-based data during Terraform operation requests: configuration, plan, and prior state. The SDKv2 combines this data into a single schema.ResourceData
type, which you implement differently depending on the operation. Certain ResourceData
methods are only valid during certain operations and trying to get data from an explicit source is problematic in many cases.
In the following SDKv2 example, the code comments highlight issues with the single data type:
The framework alleviates these issues by exposing configuration, plan, and state data as separate attributes on request and response types that only expose the data available to the given operation.
In the following framework example, the code comments show the available data that matches each operation.
Schema Data Models
In the SDKv2, you must fetch configuration, plan, and state data separately for each attribute or type. In the framework, you can fetch all of the configuration, plan, and state data at once. This approach lets you declare a single data model for a schema, which guarantees correctness and consistency across operations.
In the following SDKv2 example, you must fetch the data for each attribute unless you save the schema as a variable and reference it in the operation logic.
Some SDKv2 providers opted to type assert during these calls, which had the potential to cause Go runtime panics if they did not also check the assertion boolean.
The Fully Exposed Value States section goes into other issues and quirks with attempting to handle SDKv2 data.
Data with the framework can be modeled as a custom type and the operation of getting or setting the data will return framework-defined errors, if necessary.
In the following framework example, a provider-defined type receives all schema-based data.
With Required
attributes, you can replace the framework types in the schema data model with standard Go types (e.g. bool
) to further simplify data handling, if desired.
Fully Exposed Value States
Terraform supports three states for any value: null (missing), unknown ("known after apply"), and known. The SDKv2 does not expose or fully support null and unknown value states to providers. Instead, the Get()
method on these value states returns Go type zero-values such as ""
for schema.TypeString
, 0
for schema.TypeInt
, and false
for schema.TypeBool
. Other methods, such as GetOk()
and GetOkExists()
, have slightly different functionality for each type and operation, especially for collection types.
In the following SDKv2 example, the code comments explain issues with the single data type.
The framework type system fully exposes null, unknown, and known value states. You can reliably query each value with the IsNull()
or IsUnknown()
methods.
In the following framework example, you can determine the correct value state.
Unrestricted Type System
The framework type system exposes the majority of Terraform types and values. It is also extensible because it lets you define new types that are specific to your provider.
Custom Attribute Types
You can implement custom types for your provider that expose data with convenient Go types, methods, and built-in validation.
The following framework example uses a custom timetypes.RFC3339Type
attribute type instead of types.StringType
. The timetypes.RFC3339Type
attribute type is associated with a timetypes.RFC3339
value type. The attribute type automatically validates whether the string can be parsed as an RFC3339 timestamp and the value type exposes a Time() time.Time
method for easier usage over a regular string value.
The following framework example uses the custom timetypes.RFC3339
value type to expose the time.Time
value.
Complex Map Types
The framework type system does not have any restrictions for using complex types as the value for a map type. SDKv2 restricted map values to string, number, and boolean types.
This framework example declares a map type with a list of string values.
If you need to declare additional schema behaviors for the map values, you can use map nesting mode in Protocol Version 6 Nested Attributes, which is also only available in the framework.
Object Type
The framework type system supports the Terraform object type, which you can use to declare attribute name to value mappings without additional schema behaviors. These differ from maps by requiring specific names and their values to always exist. SDKv2 did not directly expose this type.
The following framework example declares an object type with two attributes.
If you need to declare additional schema behaviors for the object values, you can use the single nesting mode in Protocol Version 6 Nested Attributes, which is also only available in the framework.
Protocol Version 6 Nested Attributes
Protocol version 6 is the latest version of the protocol between Terraform and providers. Only the framework supports version 6.
Version 6 lets you declare schemas with nested attributes in addition to blocks. Nested attributes support schema behaviors and practitioners using your provider can configure them with expressions instead of with dynamic blocks. Nested attributes support includes four nesting modes:
- List: Ordered collection of nested attributes
- Map: Collection of string keys to nested attributes.
- Set: Unordered collection of nested attributes.
- Single: Single object of nested attributes that is useful for replacing list blocks with a single element.
In the following configuration example, a schema uses a list block that is difficult to dynamically configure.
In the following configuration example, a schema uses list nested attributes to simplify the configuration.
The following framework example shows the schema definition for the list nested attributes.
Unrestricted Validation Capabilities
The framework exposes many more configuration validation integration points than SDKv2. It is also extensible with provider-defined types that implement validation in the type itself.
Collection Type Validation
Attribute validation in the framework is not restricted by type.
This framework example validates all list values against a set of acceptable values.
This framework example checks whether map keys are between 3 and 50 characters in length using validators available in terraform-plugin-framework-validators
.
Type-Based Validation
Attribute validation supports attribute types that declare their own validation, in addition to any validators on the attribute itself.
In the following framework example, the custom type ensures that the string is a valid RFC3339 string, and the attribute can declare additional validation.
Declarative Schema Validation
The framework supports schema-level validation with reusable and declarative validators. In certain cases, such as when you would use SDKv2 AtLeastOneOf
, this approach can reduce overlapping validation errors and make logic easier to understand.
In the following SDKv2 example, multiple attributes can raise multiple errors.
In the following framework example, the validation logic raises a single error when the resource configuration does not include at least one of the specified attributes.
Imperative Schema Validation
The framework supports schema-level validation with custom logic in addition to the declarative validators. This support lets you fully customize the validation to implement complex validation logic.
In the following framework example, the resource implements custom validation logic.
Path Expressions
The framework includes a schema path implementation that lets you target attributes of any type or nesting level. This feature lets you build paths without knowing the special string syntax of the SDKv2, instead using Go ecosystem features such as suggestions from editor integrations.
In the following framework example, the path is absolute to the first element of a list.
Additionally, the framework supports expressions on top of these paths, which enables logic such as matching all indices in a list, relative paths, and parent paths.
The following framework example validates whether the two attributes within the same list element conflict with each other.
Import Warning Diagnostics
The framework supports diagnostics through all Terraform operations. The SDKv2 does not support diagnostics with some operations, such as import.
The following framework example returns a warning to practitioners when they import the resource.
Destroy Plan Diagnostics
With the framework, Terraform version 1.3 and later supports calling the provider when Terraform is planning to destroy a resource. SDKv2 does not support this functionality.
In this framework example, the resource will raise a warning when planned for destruction to give practitioner more information:
Resource Private State Management
Each provider can maintain resource private state data in Terraform state. Terraform never accesses resource private state or includes the information in plans, but providers can use this private data for advanced use cases. For example, a provider could use resource private state to store API ETag values that are not beneficial for practitioners. SDKv2 does not support this functionality.
Refer to the Manage Private State documentation for more information.