Skip to content
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

doc: add aws sdk migration guide #36104

Merged
merged 7 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
257 changes: 257 additions & 0 deletions docs/aws-go-sdk-migrations.md
jar-b marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
# AWS SDK For Go Migration Guide

AWS has [announced](https://aws.amazon.com/blogs/developer/announcing-end-of-support-for-aws-sdk-for-go-v1-on-july-31-2025/) that the V1 of the SDK for Go will enter maintenance mode on July 31, 2024 and reach end-of-life July 31, 2025.
jar-b marked this conversation as resolved.
Show resolved Hide resolved
While the AWS Terraform provider already [requires all net-new services](./aws-go-sdk-versions.md) to use AWS SDK V2 service clients, there remains a substantial number of existing services utilizing V1.

Over time maintainers will be migrating impacted services to adopt AWS SDK for Go V2.
For community members interested in contributoring to this effort, this guide documents the common patterns required to migrate a service.

## Pre-Requisites

### Re-generate Service Client

When fully replacing the client, [`names/data/names_data.csv`](https://github.com/hashicorp/terraform-provider-aws/blob/main/names/data/names_data.csv) should be updated to remove the v1 indicator and add v2 (ie. delete the `1` in the `ClientSDKV1` column and add a `2` in the `ClientSDKV2` column).
Once complete, re-generate the client.

```console
go generate ./internal/conns/...
```

### Add an `EndpointID` Constant

When a service is first migrated, a `{ServiceName}EndpointID` constant must be added to [`names/names.go`](https://github.com/hashicorp/terraform-provider-aws/blob/main/names/names.go) manually.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is no longer the case: acctest.ErrorCheck should take the corresponding names.<Service>ServiceID, which is generated. It may still be needed in some cases, such as acctest.PreCheckPartitionHasService

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the clarification. I'll fix the syntax in the acceptance testing ErrorCheck section below.

Given skaff outputs acceptance tests that use the acctest.PreCheckPartitionHasService PreCheck, and most existing services use it, I think this section may be worth keeping.

Be sure to preseve alphabetical order.

The AWS SDK for Go V1 previously exposed these as constants, but V2 does not.
This constant is used in acceptance testing pre-checks.

## Imports

In each go source file with a V1 SDK import, the library should be replaced with V2:

```go
// Remove
github.com/aws-sdk-go/service/<service>
```

```go
// Add
github.com/aws-sdk-go-v2/service/<service>
awstypes github.com/aws-sdk-go-v2/service/<service>/types
```

If the `aws` package is used, this should also be upgraded.

```
// Remove
github.com/aws-sdk-go/aws
```

```
// Add
github.com/aws-sdk-go-v2/aws
```

## Client

Once the generated client is updated the following adjustments can be made.

### Initialization From `meta`

This is typically one of the first lines in each CRUD method.

```go
// Remove
conn := meta.(*conns.AWSClient).<service>Conn(ctx)
```

```go
// Add
conn := meta.(*conns.AWSClient).<service>Client(ctx)
```

### Passing Client References

Once initialized, the client may be passed into other functions, such as finders.

```go
// Remove
<service>.<Service>
```

```go
// Add
<service>.Client
// ie. ssoadmin.SSOAdmin becomes ssoadmin.Client
```

### Generated Tagging Functions

The generated tagging functions should be updated to use the new client by passing `-AWSSDKVersion=2`.
The following line should be updated in `generate.go`:

```go
//go:generate go run ../../generate/tags/main.go <existing flags> -AWSSDKVersion=2
```

Once updated, re-generate with:

```console
go generate ./internal/service/<service>/...
```

### `WithContext` Methods

All operations using the `WithContext` methods can be replaced, as the suffix is removed in V2 and context is passed everywhere by default.

```go
// Remove
conn.<Action>WithContext
```

```go
// Add
conn.<Action
// ie. conn.CreateApplicationWithContext becomes conn.CreateApplication
```

## Errors

Typically error types have moved into the services `types` package.
There are multiple variants which can be migrated.

```go
// Remove
if tfawserr.ErrCodeEquals(err, <service>.ErrCode<error>) {
```

```go
// Add
if errs.IsA[*awstypes.<error>](err) {
```

For example,

```go
if tfawserr.ErrCodeEquals(err, ssoadmin.ErrCodeResourceNotFoundException) {
```

becomes:

```go
if errs.IsA[*awstypes.ResourceNotFoundException](err) {
```

The `ErrCodeContains` equivalent can also be migrated.

## AWS Helpers

These are simple 1-to-1 renames.

```go
// Remove
aws.StringValue
```

```go
// Add
aws.ToString
```

Similar variants for `Int32`, `Int64`, `Float32`, `Float64`, and `Bool` should also be changed.

## AWS Types

In general, the types for objects, enums, and errors move from the service package itself into the nested `types` package for each service.
This requires replacing the package prefix in several places.
As a starting point, any type reference which isn’t an Input/Output struct can likely be switched.

```go
// Remove
<service>.StatusInProgress
```

```go
// Add
awstypes.StatusInProgress
```

Individual services vary in which types are moved into the dedicated subpackage, so a programatic replacement of all occurrences may require some manual adjustment afterward.

### Enum Types

Enums are now represented with custom types, rather than as strings.
Because of this type change it may be necessary to convert from or to string values depending on the direction in which data is being exchanged.

#### Input Structs

Input structs will now require the value to be wrapped in the enum type.

```go
// Remove
input.Thing = aws.String(v.(string))
```

```go
// Add
input.Thing = awstypes.Thing(v.(string))
```

#### Acceptance Test Attribute Checks

Acceptance tests where enums are passed to configuration functions or used for attribute checks will need to be converted from the enum type back into a string.

```go
// Remove
resource.TestCheckResourceAttr(resourceName, "thing", <service>.Thing),
```

```go
// Add
resource.TestCheckResourceAttr(resourceName, "thing", string(awstypes.Thing)),
```

#### Validation Functions

Validation functions which previously used the `StringInSlice` helper can now use a generic equivalent that works with custom string types.

```go
// Remove
ValidateFunc: validation.StringInSlice(<service>.Thing_Values(), false),
```

```go
// Add
ValidateDiagFunc: enum.Validate[awstypes.Thing](),
```

## Pagination

V2 of the AWS SDK introduces new [paginator](https://aws.github.io/aws-sdk-go-v2/docs/making-requests/#using-paginators) helpers.
Any `List*Pages` methods called with V1 of the SDK will need to replace the pagination function argument with the syntax documented in the AWS SDK for Go V2 documentation.

## Acceptance Testing `ErrorCheck`

In V1, this check relies on the endpoint values included in the SDK. These are not included in the V2 SDK, and therefore are managed in the names package instead.

```go
// Remove
ErrorCheck: acctest.ErrorCheck(t, <service>.EndpointsID),
```

```go
// Add
ErrorCheck: acctest.ErrorCheck(t, names.<service>EndpointID),
```

For example,

```
ErrorCheck: acctest.ErrorCheck(t, ssoadmin.EndpointsID),
```

becomes:

```go
ErrorCheck: acctest.ErrorCheck(t, names.SSOAdminEndpointID),
```
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ nav:
- Design Decision Log: design-decision-log.md
- Dependency Updates: dependency-updates.md
- AWS SDK for Go Versions: aws-go-sdk-versions.md
- AWS SDK for Go Migrations: aws-go-sdk-migrations.md
- Terraform Plugin Development Packages: terraform-plugin-development-packages.md
- AWS Go SDK Base: aws-go-sdk-base.md
- Error Handling: error-handling.md
Expand Down
Loading