Skip to content

Commit

Permalink
Adding docs for migrating from SDKv2 to the Framework (#461)
Browse files Browse the repository at this point in the history
* Adding docs for migrating from SDKv2 to the Framework (#459)

* Apply suggestions from code review

Co-authored-by: Robin Norwood <robin.norwood@gmail.com>

* Further fixes following review (#459)

* Apply suggestions from code review

Co-authored-by: Brian Flad <bflad417@gmail.com>

* Linting (#459)

* Using /* ... */ to indicate code has been truncated and removing statement in the text to same effect. (#459)

* Removing text and link as nothing to link to at present (#459)

* Adding an example of migrating schema.TypeList to types.ListType (#459)

* Adding example of migrating from schema.ImportStatePassthroughContext to resource.ImportStatePassthroughID (#459)

* Removing extra blank line (#459)

* Reword to clarify reference to practitioner-configurable blocks (#459)

* Replacing ellipsis with in-line comment (#459)

* Adding example of schema for using nested attributes when migrating computed blocks to framework using protocol version 6 (#459)

* Adding schema examples for common type migrations (#459)

* Apply suggestions from code review

Co-authored-by: Brian Flad <bflad417@gmail.com>

* Updating links to tagged version of random provider (#459)

* Updating layout for data sources and providers (#459)

* Removing ellipsis and replacing with comment (#459)

* Formatting code examples (#459)

* Updating computed-blocks example to use ListNestedAttributes (#459)

* Restructuring resources and updating state upgrade example (#459)

* Formatting headers (#459)

* Apply suggestions from code review

Co-authored-by: Brian Flad <bflad417@gmail.com>
Co-authored-by: Laura Pacilio <83350965+laurapacilio@users.noreply.github.com>

* Restructuring top-level Schemas page, adding example for config headers (#459)

* Apply suggestions from code review

Co-authored-by: Robin Norwood <robin.norwood@gmail.com>
Co-authored-by: Laura Pacilio <83350965+laurapacilio@users.noreply.github.com>
Co-authored-by: Brian Flad <bflad417@gmail.com>

* Replacing link using "Provider Schema" with "Providers" (#459)

* Fixing formatting and wording (#459)

* Fixing formatting and wording (#459)

Co-authored-by: Robin Norwood <robin.norwood@gmail.com>
Co-authored-by: Brian Flad <bflad417@gmail.com>
Co-authored-by: Laura Pacilio <83350965+laurapacilio@users.noreply.github.com>
  • Loading branch information
4 people committed Sep 9, 2022
1 parent beffdc6 commit 8ce2dcd
Show file tree
Hide file tree
Showing 20 changed files with 3,329 additions and 1 deletion.
111 changes: 110 additions & 1 deletion website/data/plugin-framework-nav-data.json
Expand Up @@ -21,7 +21,10 @@
{
"title": "Resources",
"routes": [
{ "title": "Overview", "path": "resources" },
{
"title": "Overview",
"path": "resources"
},
{
"title": "Import",
"path": "resources/import"
Expand Down Expand Up @@ -83,5 +86,111 @@
{
"title": "Debugging",
"path": "debugging"
},
{
"title": "Migrating from SDK",
"routes": [
{
"title": "Overview",
"path": "migrating"
},
{
"title": "Testing",
"path": "migrating/testing"
},
{
"title": "Schema",
"routes": [
{
"title": "Overview",
"path": "migrating/schema"
}
]
},
{
"title": "Providers",
"routes": [
{
"title": "Overview",
"path": "migrating/providers"
}
]
},
{
"title": "Resources",
"routes": [
{
"title": "Overview",
"path": "migrating/resources"
},
{
"title": "CRUD Functions",
"path": "migrating/resources/crud"
},
{
"title": "Import",
"path": "migrating/resources/import"
},
{
"title": "Plan Modification",
"path": "migrating/resources/plan-modification"
},
{
"title": "State Upgraders",
"path": "migrating/resources/state-upgrade"
}
]
},
{
"title": "Data Sources",
"routes": [
{
"title": "Overview",
"path": "migrating/data-sources"
}
]
},
{
"title": "Attributes & Blocks",
"routes": [
{
"title": "Attribute Schema",
"path": "migrating/attributes-blocks/attribute-schema"
},
{
"title": "Attribute Types",
"path": "migrating/attributes-blocks/types"
},
{
"title": "Attribute Fields",
"path": "migrating/attributes-blocks/fields"
},
{
"title": "Default Values",
"path": "migrating/attributes-blocks/default-values"
},
{
"title": "Force New",
"path": "migrating/attributes-blocks/force-new"
},
{
"title": "Validators - Predefined",
"path": "migrating/attributes-blocks/validators-predefined"
},
{
"title": "Validators - Custom",
"path": "migrating/attributes-blocks/validators-custom"
},
{
"title": "Blocks",
"path": "migrating/attributes-blocks/blocks"
},
{
"title": "Blocks with Computed Fields",
"path": "migrating/attributes-blocks/blocks-computed"
}
]
}
]
}
]
@@ -0,0 +1,126 @@
---
page_title: 'Attribute Schema: Migrating from SDKv2 to the Framework'
description: >-
Migrate attributes from SDKv2 to the plugin Framework
---

# Attribute Schema

Attributes define how users can configure values for your Terraform provider, resources, and data sources. Refer to
[Schemas - Attributes](/plugin/framework/schemas#attributes) in the Framework documentation for details.

This page explains how to migrate an attribute from SDKv2 to the plugin Framework.

## SDKv2
In SDKv2, attributes are defined by the `Schema` field in the provider, resource, or data source schema. The `Schema`
field maps each attribute name (string) to the attribute's `schema.Schema` struct. Both resources and data sources are
defined using the `schema.Resource` struct.

The following code shows a basic implementation of attribute schema for a provider in SDKv2.

```go
func ProviderExample() *schema.Provider {
return &schema.Provider{
Schema: map[string]*schema.Schema{
/* ... */
},
```
In SDKv2, resource and data source attributes are defined the same way on their respective types.
```go
func resourceExample() *schema.Resource {
return &schema.Resource{
Schema: map[string]*schema.Schema{
/* ... */
```
## Framework
In the Framework, you define attributes by setting the `Attributes` field on your provider, resource, or data type's
schema, as returned by the `GetSchema` function. The `tfsdk.Schema` type returned by `GetSchema` includes an
`Attributes` field that maps each attribute name (string) to the attribute's `tfsdk.Attribute` struct.
The following code shows how to define an attribute for a resource with the Framework.
```go
func (d *resourceTypeExample) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) {
return tfsdk.Schema{
Attributes: map[string]tfsdk.Attribute{
"example": {
/* ... */
```
The Framework defines the `tfsdk.Attribute` struct as follows.
```go
type Attribute struct {
Type attr.Type
Attributes NestedAttributes
Description string
MarkdownDescription string
Required bool
Optional bool
Computed bool
Sensitive bool
DeprecationMessage string
Validators []AttributeValidator
PlanModifiers AttributePlanModifiers
}
```
## Migration Notes
Remember the following differences between SDKv2 and the Framework when completing the migration.
- In SDKv2, attributes are defined by a map from attribute names to `schema.Schema` structs in the `Schema` field of
your resource's schema. In the Framework, attributes are defined by a map from attribute names to `tfsdk.Attribute`
structs in your resource's schema, which is returned by the `GetSchema` function.
- There are several differences between the implementation of attributes in SDKv2 and the Framework. Refer to the other
pages in the Attributes & Blocks section of this migration guide for more details.
## Example
The following examples show how to migrate portions of the
[http](https://github.com/hashicorp/terraform-provider-http) provider.
For a complete example, clone the
`terraform-provider-http` repository and compare the `data_source.go` file in
[v2.2.0](https://github.com/hashicorp/terraform-provider-http/blob/v2.2.0/internal/provider/data_source.go)
with the `data_source_http.go` file in
[v3.0.1](https://github.com/hashicorp/terraform-provider-http/blob/v3.0.1/internal/provider/data_source_http.go).
### SDKv2
The following example from the `data_source.go` file shows the implementation of the `url` attribute for the `http`
data source.
```go
func dataSource() *schema.Resource {
return &schema.Resource{
/* ... */
Schema: map[string]*schema.Schema{
"url": {
Description: "The URL for the request. Supported schemes are `http` and `https`.",
Type: schema.TypeString,
Required: true,
},
```
### Framework
The following shows the same section of provider code after the migration.
This code implements the `url` attribute for the `http` data source with the Framework.
```go
func (d *httpDataSourceType) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) {
return tfsdk.Schema{
/* ... */
Attributes: map[string]tfsdk.Attribute{
"url": {
Description: "The URL for the request. Supported schemes are `http` and `https`.",
Type: types.StringType,
Required: true,
},
/* ... */
```
@@ -0,0 +1,122 @@
---
page_title: 'Computed Blocks: Migrating from SDKv2 to the Framework'
description: >-
Migrate blocks with computed fields from SDKv2 to attribute validators in the plugin Framework.
---

# Blocks with Computed Fields

Some providers, resources, and data sources include repeatable nested blocks in their attributes. Some blocks contain
fields with `Computed: true`, which means that the provider code can define the value or that it could come from the
output of terraform apply (e.g., the ID of an EC2 instance).

This page explains how to migrate computed-only blocks from SDKv2 to the Framework. Refer to
[Blocks](/plugin/framework/migrating/attributes-blocks/blocks) if you are looking for information about migrating blocks
that are practitioner configurable.

## SDKv2

In SDKv2, blocks are defined by an attribute whose type is either `TypeList` or `TypeSet`, and whose `Elem` field is set to a
`schema.Resource` that contains a map of the block's attribute names to corresponding `schemaSchema` structs.

```go
map[string]*schema.Schema{
"example": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"nested_example": {
Type: schema.TypeString,
Computed: true,
/* ... */
```
## Framework
In the Framework, when working with protocol version 5, computed blocks are implemented using an attribute with a `Type`
of `types.ListType` which has an `ElemType` of `types.ObjectType`.
```go
map[string]tfsdk.Attribute{
"example": {
Computed: true,
Type: types.ListType{
ElemType: types.ObjectType{
AttrTypes: map[string]attr.Type{
"nested_example": types.StringType,
/* ... */

```
In the Framework, when working with protocol version 6, we recommend that you define computed blocks using nested
attributes. This example shows usage of `ListNestedAttributes` as this provides configuration references with list index
syntax as is the case when using `schema.TypeList` in SDKv2. `SingleNestedAttributes` is a good choice for single
underlying objects which results in a breaking change but also allows dropping `[0]` in configuration references.
```go
map[string]tfsdk.Attribute{
"example": {
Computed: true,
Attributes: tfsdk.ListNestedAttributes(map[string]tfsdk.Attribute{
"nested_example": {
Computed: true,
Type: types.StringType,
/* ... */

```
## Migration Notes
- When using protocol version 5 specify `ElemType` as `types.ObjectType` when migrating blocks that are computed from SDKv2 to Framework.
- When using protocol version 6, use [nested attributes](https://www.terraform.io/plugin/framework/schemas#attributes-1) when migrating blocks that are computed from SDKv2 to Framework.
## Example
The following examples show how to migrate portions of the [tls](https://github.com/hashicorp/terraform-provider-tls)
provider.
For a complete example, clone the
`terraform-provider-tls` repository and compare the `data_source_certificate.go` file in
[v3.4.0](https://github.com/hashicorp/terraform-provider-tls/blob/v3.4.0/internal/provider/data_source_certificate.go)
with
[v4.0.1](https://github.com/hashicorp/terraform-provider-tls/blob/v4.0.1/internal/provider/data_source_certificate.go).
### SDKv2
The following example from the `data_source_certificate.go` file shows the implementation of the `certificates` nested
block on the `certificate` data source's schema.
```go
Schema: map[string]*schema.Schema{
"certificates": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"signature_algorithm": {
Type: schema.TypeString,
Computed: true,
/* ... */
},
```
### Framework
The following shows the same section of provider code after the migration.
This code defines the `certificates` block as an attribute on the `certificate` data source's schema, where the
`types.ObjectType` is being used to define the nested block.
```go
map[string]tfsdk.Attribute{
"certificates": {
Type: types.ListType{
ElemType: types.ObjectType{
AttrTypes: map[string]attr.Type{
"signature_algorithm": types.StringType,
},
},
Computed: true,
/* ... */
```

0 comments on commit 8ce2dcd

Please sign in to comment.