Skip to content

Commit

Permalink
Merge pull request #33595 from hashicorp/d-framework-upgrade
Browse files Browse the repository at this point in the history
[Docs]: Policy update to recommended AWS SDK V2 and Plugin Framework
  • Loading branch information
jar-b authored Oct 20, 2023
2 parents 1310732 + 0e1434f commit daa8946
Show file tree
Hide file tree
Showing 25 changed files with 2,844 additions and 1,361 deletions.
47 changes: 37 additions & 10 deletions docs/add-a-new-datasource.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<!-- markdownlint-configure-file { "code-block-style": false } -->
# Adding a New Data Source

New data sources are required when AWS adds a new service, or adds new features within an existing service which would require a new data source to allow practitioners to query existing resources of that type for use in their configurations. Anything with a Describe or Get endpoint could make a data source, but some are more useful than others.
Expand Down Expand Up @@ -36,18 +37,44 @@ These will map the AWS API response to the data source schema. You will also nee

Data Sources use a self registration process that adds them to the provider using the `@SDKDataSource()` annotation in the datasource's comments. Run `make gen` to register the datasource. This will add an entry to the `service_package_gen.go` file located in the service package folder.

```
package something
=== "Terraform Plugin Framework (Preferred)"

import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
```go
package something

// @SDKDataSource("aws_something_example", name="Example")
func DataSourceExample() *schema.Resource {
return &schema.Resource{
// some configuration
}
}
```
import (
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-provider-aws/internal/framework"
)

// @FrameworkDataSource(name="Example")
func newResourceExample(_ context.Context) (datasource.ResourceWithConfigure, error) {
return &dataSourceExample{}, nil
}

type dataSourceExample struct {
framework.DataSourceWithConfigure
}

func (r *dataSourceExample) Metadata(_ context.Context, request datasource.MetadataRequest, response *datasource.MetadataResponse) {
response.TypeName = "aws_something_example"
}
```

=== "Terraform Plugin SDK V2"

```go
package something

import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"

// @SDKDataSource("aws_something_example", name="Example")
func DataSourceExample() *schema.Resource {
return &schema.Resource{
// some configuration
}
}
```

### Write Passing Acceptance Tests

Expand Down
49 changes: 38 additions & 11 deletions docs/add-a-new-resource.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<!-- markdownlint-configure-file { "code-block-style": false } -->
# Adding a New Resource

New resources are required when AWS adds a new service, or adds new features within an existing service which would require a new resource to manage in Terraform. Typically anything with a new set of CRUD API endpoints is a great candidate for a new resource.
Expand Down Expand Up @@ -36,20 +37,46 @@ These will map planned Terraform state to the AWS API call, or an AWS API respon

### Register Resource to the provider

Resources use a self registration process that adds them to the provider using the `@SDKResource()` annotation in the resource's comments. Run `make gen` to register the resource. This will add an entry to the `service_package_gen.go` file located in the service package folder.
Resources use a self registration process that adds them to the provider using the `@FrameworkResource()` or `@SDKResource()` annotation in the resource's comments. Run `make gen` to register the resource. This will add an entry to the `service_package_gen.go` file located in the service package folder.

```
package something
=== "Terraform Plugin Framework (Preferred)"

import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
```go
package something

// @SDKResource("aws_something_example", name="Example)
func ResourceExample() *schema.Resource {
return &schema.Resource{
// some configuration
}
}
```
import (
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-provider-aws/internal/framework"
)

// @FrameworkResource(name="Example")
func newResourceExample(_ context.Context) (resource.ResourceWithConfigure, error) {
return &resourceExample{}, nil
}

type resourceExample struct {
framework.ResourceWithConfigure
}

func (r *resourceExample) Metadata(_ context.Context, request resource.MetadataRequest, response *resource.MetadataResponse) {
response.TypeName = "aws_something_example"
}
```

=== "Terraform Plugin SDK V2"

```go
package something

import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"

// @SDKResource("aws_something_example", name="Example)
func ResourceExample() *schema.Resource {
return &schema.Resource{
// some configuration
}
}
```

### Write passing Acceptance Tests

Expand Down
35 changes: 20 additions & 15 deletions docs/add-a-new-service.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<!-- markdownlint-configure-file { "code-block-style": false } -->
# Adding a New AWS Service

AWS frequently launches new services, and Terraform support is frequently desired by the community shortly after launch. Depending on the API surface area of the new service, this could be a major undertaking. The following steps should be followed to prepare for adding the resources that allow for Terraform management of that service.
Expand Down Expand Up @@ -27,17 +28,25 @@ To add an AWS SDK for Go service client:
1. Otherwise, determine the service identifier using the rule described in [the Naming Guide](naming.md#service-identifier).

1. In `names/names_data.csv`, add a new line with all the requested information for the service following the guidance in the [`names` README](https://github.com/hashicorp/terraform-provider-aws/blob/main/names/README.md).
**_Be very careful when adding or changing data in `names_data.csv`!
The Provider and generators depend on the file being correct.
We strongly recommend using an editor with CSV support._**

!!! tip
Be very careful when adding or changing data in `names_data.csv`!
The Provider and generators depend on the file being correct.
We strongly recommend using an editor with CSV support.

To generate the client, run the following then submit the pull request:

```sh
make gen
make test
go mod tidy
```
```console
make gen
```

```console
make test
```

```console
go mod tidy
```

Once the service client has been added, implement the first [resource](./add-a-new-resource.md) or [data source](./add-a-new-datasource.md) in a separate PR.

Expand All @@ -51,8 +60,7 @@ If an AWS service must be created in a non-standard way, for example the service

1. Add a file `internal/<service>/service_package.go` that contains an API client factory function, for example:

<!-- markdownlint-disable code-block-style -->
=== "aws-go-sdk-v2"
=== "AWS Go SDK V2 (Preferred)"

```go
package route53domains
Expand Down Expand Up @@ -80,7 +88,7 @@ If an AWS service must be created in a non-standard way, for example the service
}
```

=== "aws-go-sdk"
=== "AWS Go SDK V1"

```go
package globalaccelerator
Expand All @@ -107,16 +115,14 @@ If an AWS service must be created in a non-standard way, for example the service
return globalaccelerator_sdkv1.New(sess.Copy(config)), nil
}
```
<!-- markdownlint-enable code-block-style -->

## Customizing a new Service Client

If an AWS service must be customized after creation, for example retry handling must be changed, then:

1. Add a file `internal/<service>/service_package.go` that contains an API client customization function, for example:

<!-- markdownlint-disable code-block-style -->
=== "aws-go-sdk"
=== "AWS Go SDK V1"

```go
package chime
Expand Down Expand Up @@ -145,4 +151,3 @@ If an AWS service must be customized after creation, for example retry handling
return conn, nil
}
```
<!-- markdownlint-enable code-block-style -->
12 changes: 6 additions & 6 deletions docs/add-import-support.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Adding Resource Import Support

Adding import support for Terraform resources will allow existing infrastructure to be managed within Terraform. This type of enhancement generally requires a small to moderate amount of code changes.
Adding import support for Terraform resources will allow existing infrastructure to be managed within Terraform. This type of enhancement generally requires a small to moderate amount of code changes. Comprehensive code examples and information about resource import support can be found in the [Terraform Plugin Framework documentation](https://developer.hashicorp.com/terraform/plugin/framework/resources/import).

Comprehensive code examples and information about resource import support can be found in the [Terraform Plugin SDK v2 documentation](https://www.terraform.io/plugin/sdkv2/resources/import).

- _Resource Code Implementation_: In the resource code (e.g., `internal/service/{service}/{thing}.go`), implementation of `Importer` `State` function. When possible, prefer using [`schema.ImportStatePassthroughContext`](https://www.terraform.io/plugin/sdkv2/resources/import#importer-state-function) as the `Importer` `State` function
- _Resource Acceptance Testing Implementation_: In the resource acceptance testing (e.g., `internal/service/{service}/{thing}_test.go`), implementation of `TestStep`s with `ImportState: true`
- _Resource Documentation Implementation_: In the resource documentation (e.g., `website/docs/r/service_thing.html.markdown`), addition of `Import` documentation section at the bottom of the page
- _Resource Code_: In the resource code (e.g., `internal/service/{service}/{thing}.go`),
- **Plugin Framework (Preferred)** Implement the `ImportState` method on the resource struct. When possible, prefer using the [`resource.ImportStatePassthroughID` function](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/resource#ImportStatePassthroughID).
- **Plugin SDK V2**: Implement an `Importer` `State` function. When possible, prefer using [`schema.ImportStatePassthroughContext`](https://www.terraform.io/plugin/sdkv2/resources/import#importer-state-function).
- _Resource Acceptance Tests_: In the resource acceptance tests (e.g., `internal/service/{service}/{thing}_test.go`), implement one or more tests containing a `TestStep` with `ImportState: true`.
- _Resource Documentation_: In the resource documentation (e.g., `website/docs/r/service_thing.html.markdown`), add an `Import` section at the bottom of the page.
16 changes: 7 additions & 9 deletions docs/aws-go-sdk-versions.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,19 @@ There are two versions of this API, both of which are considered Generally Avail
- [AWS SDKs and Tools maintenance policy](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html)
- [AWS SDKs and Tools version support matrix](https://docs.aws.amazon.com/sdkref/latest/guide/version-support-matrix.html)

While the vast majority of the provider is based on the [AWS SDK for Go v1](https://github.com/aws/aws-sdk-go),
the provider also allows the use of the [AWS SDK for Go v2](https://github.com/aws/aws-sdk-go-v2).
Each Terraform provider implementation for an AWS service relies on a service client, which in turn is constructed based on a specific SDK version.
While the vast majority of the provider is based on the [AWS SDK for Go v1](https://github.com/aws/aws-sdk-go), the provider also allows the use of the [AWS SDK for Go v2](https://github.com/aws/aws-sdk-go-v2).

## Which SDK Version should I use?

Each Terraform provider implementation for an AWS service relies on a service client which in turn is constructed based on a specific SDK version.
At present, we are slowly increasing our footprint on SDK v2, but are not actively migrating existing code to use v2.
The choice of SDK will be as follows:
At this time **all net-new services are required to use AWS Go SDK v2**.
Enhancements or bug fixes to existing AWS Go SDK v1 based services do not require migration.
You can determine the SDK version a given service uses by looking at the `import` section in the service's Go files.
Where applicable, the contributor guide has been updated to include examples with both AWS Go SDK v1 and v2.

For new services, you should use [AWS SDK for Go v2](https://github.com/aws/aws-sdk-go-v2).
We are beginning to migrate core services written with v1 onto v2, and adoption will continue to increase over time.
AWS has a [migration guide](https://aws.github.io/aws-sdk-go-v2/docs/migrating/) that details the differences between the versions of the SDK.

For existing services, use the version of the SDK that service currently uses.
You can determine this by looking at the `import` section in the service's Go files.

## What does the SDK handle?

The AWS SDKs handle calling the various web service interfaces for AWS services.
Expand Down
30 changes: 16 additions & 14 deletions docs/changelog-process.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
# Changelog Process

HashiCorp’s open-source projects have always maintained user-friendly, readable CHANGELOG.md that allow users to tell at a glance whether a release should have any effect on them, and to gauge the risk of an upgrade.
HashiCorp’s open-source projects have always maintained user-friendly, readable `CHANGELOG.md` that allow users to tell at a glance whether a release should have any effect on them, and to gauge the risk of an upgrade.

We use the [go-changelog](https://github.com/hashicorp/go-changelog) to generate and update the changelog from files created in the `.changelog/` directory. It is important that when you raise your Pull Request, there is a changelog entry which describes the changes your contribution makes. Not all changes require an entry in the changelog, guidance follows on what changes do.
We use [go-changelog](https://github.com/hashicorp/go-changelog) to generate the changelog from files created in the `.changelog/` directory.
It is important that when you raise your pull request, there is a changelog entry which describes the changes your contribution makes.
Not all changes require an entry in the changelog, guidance follows on what changes do.

## Changelog format

The changelog format requires an entry in the following format, where HEADER corresponds to the changelog category, and the entry is the changelog entry itself. The entry should be included in a file in the `.changelog` directory with the naming convention `{PR-NUMBER}.txt`. For example, to create a changelog entry for pull request 1234, there should be a file named `.changelog/1234.txt`.

``````markdown
``````
```release-note:{HEADER}
{ENTRY}
```
``````

If a pull request should contain multiple changelog entries, then multiple blocks can be added to the same changelog file. For example:

``````markdown
``````
```release-note:note
resource/aws_example_thing: The `broken` attribute has been deprecated. All configurations using `broken` should be updated to use the new `not_broken` attribute instead.
```
Expand All @@ -36,7 +38,7 @@ The CHANGELOG is intended to show operator-impacting changes to the codebase for

A new resource entry should only contain the name of the resource, and use the `release-note:new-resource` header.

``````markdown
``````
```release-note:new-resource
aws_secretsmanager_secret_policy
```
Expand All @@ -46,7 +48,7 @@ aws_secretsmanager_secret_policy

A new data source entry should only contain the name of the data source, and use the `release-note:new-data-source` header.

``````markdown
``````
```release-note:new-data-source
aws_workspaces_workspace
```
Expand All @@ -56,7 +58,7 @@ aws_workspaces_workspace

A new full length documentation entry gives the title of the documentation added, using the `release-note:new-guide` header.

``````markdown
``````
```release-note:new-guide
Custom Service Endpoint Configuration
```
Expand All @@ -66,7 +68,7 @@ Custom Service Endpoint Configuration

A new bug entry should use the `release-note:bug` header and have a prefix indicating the resource or data source it corresponds to, a colon, then followed by a brief summary. Use a `provider` prefix for provider level fixes.

``````markdown
``````
```release-note:bug
resource/aws_glue_classifier: Fix quote_symbol being optional
```
Expand All @@ -76,7 +78,7 @@ resource/aws_glue_classifier: Fix quote_symbol being optional

A new enhancement entry should use the `release-note:enhancement` header and have a prefix indicating the resource or data source it corresponds to, a colon, then followed by a brief summary. Use a `provider` prefix for provider level enhancements.

``````markdown
``````
```release-note:enhancement
resource/aws_eip: Add network_border_group argument
```
Expand All @@ -86,7 +88,7 @@ resource/aws_eip: Add network_border_group argument

A deprecation entry should use the `release-note:note` header and have a prefix indicating the resource or data source it corresponds to, a colon, then followed by a brief summary. Use a `provider` prefix for provider level changes.

``````markdown
``````
```release-note:note
resource/aws_dx_gateway_association: The vpn_gateway_id attribute is being deprecated in favor of the new associated_gateway_id attribute to support transit gateway associations
```
Expand All @@ -96,21 +98,21 @@ resource/aws_dx_gateway_association: The vpn_gateway_id attribute is being depre

A breaking-change entry should use the `release-note:breaking-change` header and have a prefix indicating the resource or data source it corresponds to, a colon, then followed by a brief summary. Use a `provider` prefix for provider level changes.

``````markdown
``````
```release-note:breaking-change
resource/aws_lambda_alias: Resource import no longer converts Lambda Function name to ARN
```
``````

#### Region validation support

``````markdown
``````
```release-note:note
provider: Region validation now automatically supports the new `XX-XXXXX-#` (Location) region. For AWS operations to work in the new region, the region must be explicitly enabled as outlined in the [AWS Documentation](https://docs.aws.amazon.com/general/latest/gr/rande-manage.html#rande-manage-enable). When the region is not enabled, the Terraform AWS Provider will return errors during credential validation (e.g., `error validating provider credentials: error calling sts:GetCallerIdentity: InvalidClientTokenId: The security token included in the request is invalid`) or AWS operations will throw their own errors (e.g., `data.aws_availability_zones.available: Error fetching Availability Zones: AuthFailure: AWS was not able to validate the provided access credentials`). [GH-####]
```
```release-note:enhancement
* provider: Support automatic region validation for `XX-XXXXX-#` [GH-####]
provider: Support automatic region validation for `XX-XXXXX-#` [GH-####]
```
``````

Expand All @@ -120,7 +122,7 @@ Dependency updates: If the update contains relevant bug fixes or enhancements th
Any changes which do not fit into the above categories but warrant highlighting.
Use resource/data source/provider prefixes where appropriate.

``````markdown
``````
```release-note:note
resource/aws_lambda_alias: Resource import no longer converts Lambda Function name to ARN
```
Expand Down
Loading

0 comments on commit daa8946

Please sign in to comment.