-
Notifications
You must be signed in to change notification settings - Fork 94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding docs for migrating from SDKv2 to the Framework #461
Changes from 25 commits
fe9d1f2
7e6158f
45718ce
92724f4
2cf4cf6
3fe19bc
77793a8
0b5c8c3
0b9f120
e0eb531
f5c4be6
0e3d07b
d781d32
d654477
9314e01
474c8bb
653c65c
a86abfb
84fd690
017d416
1ae0d44
1afd243
7a07a06
3566d84
be4cb9e
64b35fc
f07b3e2
d14ee0d
73879d7
62e9ec0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
@@ -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 | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you get a chance, you can try running
Suggested change
And further down with additional newlines after code fences. 👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Have installed and run I'm ignoring the In terms of the remaining notifications, I'm interested to hear feedback from @robin-norwood and @laurapacilio as I thought this was intentional but happy to fix however suits: markdownlint --disable MD013 -- ./website/docs/plugin/framework/migrating/*
./website/docs/plugin/framework/migrating/data-sources.mdx:107 MD024/no-duplicate-heading/no-duplicate-header Multiple headings with the same content [Context: "### SDKv2"]
./website/docs/plugin/framework/migrating/data-sources.mdx:140 MD024/no-duplicate-heading/no-duplicate-header Multiple headings with the same content [Context: "### Framework"]
./website/docs/plugin/framework/migrating/provider.mdx:111 MD024/no-duplicate-heading/no-duplicate-header Multiple headings with the same content [Context: "### SDKv2"]
./website/docs/plugin/framework/migrating/provider.mdx:138 MD024/no-duplicate-heading/no-duplicate-header Multiple headings with the same content [Context: "### Framework"]
./website/docs/plugin/framework/migrating/provider.mdx:208 MD036/no-emphasis-as-heading/no-emphasis-as-header Emphasis used instead of a heading [Context: "SDKv2"]
./website/docs/plugin/framework/migrating/provider.mdx:233 MD036/no-emphasis-as-heading/no-emphasis-as-header Emphasis used instead of a heading [Context: "Framework"]
./website/docs/plugin/framework/migrating/provider.mdx:278 MD024/no-duplicate-heading/no-duplicate-header Multiple headings with the same content [Context: "### SDKv2"]
./website/docs/plugin/framework/migrating/provider.mdx:293 MD024/no-duplicate-heading/no-duplicate-header Multiple headings with the same content [Context: "### Framework"]
./website/docs/plugin/framework/migrating/provider.mdx:313 MD024/no-duplicate-heading/no-duplicate-header Multiple headings with the same content [Context: "### Migration Notes"]
./website/docs/plugin/framework/migrating/provider.mdx:321 MD024/no-duplicate-heading/no-duplicate-header Multiple headings with the same content [Context: "### Example"]
./website/docs/plugin/framework/migrating/provider.mdx:335 MD036/no-emphasis-as-heading/no-emphasis-as-header Emphasis used instead of a heading [Context: "SDKv2"]
./website/docs/plugin/framework/migrating/provider.mdx:358 MD036/no-emphasis-as-heading/no-emphasis-as-header Emphasis used instead of a heading [Context: "Framework"]
./website/docs/plugin/framework/migrating/testing.mdx:109 MD024/no-duplicate-heading/no-duplicate-header Multiple headings with the same content [Context: "### Example"]
./website/docs/plugin/framework/migrating/testing.mdx:119 MD036/no-emphasis-as-heading/no-emphasis-as-header Emphasis used instead of a heading [Context: "SDKv2"]
./website/docs/plugin/framework/migrating/testing.mdx:146 MD024/no-duplicate-heading/no-duplicate-header Multiple headings with the same content [Context: "### Framework"] There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Forgive me - is the problem that we have duplicate headings? My opinion is that they are needed here, but let me know if you disagree! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The 2 things that are being flagged by the linter are:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Following the removal of
|
||||||||
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) | ||||||||
and the `data_source_http.go` file in | ||||||||
bendbennett marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
[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, | ||||||||
}, | ||||||||
/* ... */ | ||||||||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
--- | ||
page_title: 'Computed Blocks: Migrating from SDKv2 to the Framework' | ||
description: >- | ||
Migrate computed blocks from SDKv2 to attribute validators in the plugin Framework. | ||
--- | ||
|
||
# Computed Blocks | ||
|
||
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). Refer to [Schemas - Blocks](/plugin/framework/FIXME) in the | ||
Framework documentation for details. | ||
bendbennett marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
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 `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. | ||
bendbennett marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```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`. | ||
bendbennett marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```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, | ||
/* ... */ | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that we have a Schema section, should these pages be moved under there as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that makes sense given that each of these pages relates to how the schema is set-up.
@laurapacilio @robin-norwood are you happy if I go ahead and move these pages as @bflad suggests?