docs/add-a-new-resource.md
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.
Each resource should be submitted for review in isolation. Pull requests containing multiple resources are harder to review and the maintainers will normally ask for them to be broken apart.
If this is the first resource for a new service, please ensure the Service Client for the new service has been added and merged. See Adding a new Service for details.
For new resources use a branch named f-{resource name} for example: f-ec2-vpc. See Raising a Pull Request for more details.
See the Naming Guide for details on how to name the new resource and the resource file. Not following the naming standards will cause extra delay as maintainers request that you make changes.
Use the skaff provider scaffolding tool to generate new resource and test templates using your chosen name. Doing so will ensure that any boilerplate code, structural best practices and repetitive naming are done for you and always represent our most current standards.
In the internal/service/<service>/<resource>.go file you will see a Schema property which exists as a map of Schema objects. This relates the AWS API data model with the Terraform resource itself. For each property you want to make available in Terraform, you will need to add it as an attribute, choose the correct data type and supply the correct Schema Behaviors to ensure Terraform knows how to correctly handle the value.
Typically you will add arguments to represent the values that are under control by Terraform, and attributes to supply read-only values as references for Terraform. These are distinguished by Schema Behavior.
Attribute names are to be specified in snake_case as opposed to the AWS API which is CamelCase.
These will map the planned Terraform state to the AWS API call, or an AWS API response to an applied Terraform state. You will also need to handle different response types (including errors correctly). For complex attributes, you will need to implement Flattener or Expander functions. The Data Handling and Conversion Guide covers everything you need to know for mapping AWS API responses to Terraform State and vice-versa. The Error Handling Guide covers everything you need to know about handling AWS API responses consistently.
This will identify which of the resource type's attributes make up the resource's globally-unique identity. The Resource Identity Reference provides more detail on enabling Resource Identity on a resource type.
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.
=== "Terraform Plugin Framework (Preferred)"
```go
package something
import (
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-provider-aws/internal/framework"
)
// @FrameworkResource("aws_something_example", name="Example")
func newExampleResource(_ context.Context) (resource.ResourceWithConfigure, error) {
return &resourceExample{}, nil
}
type exampleResource struct {
framework.ResourceWithModel[exampleResourceModel]
}
type exampleResourceModel struct {
// Fields corresponding to attributes in the Schema.
}
```
=== "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
}
}
```
To adequately test the resource we will need to write a complete set of Acceptance Tests. You will need an AWS account for this which allows the creation of that resource. See Writing Acceptance Tests for a detailed guide on how to approach these.
You will need at a minimum:
Add a file covering the use of the new resource in website/docs/r/<service>_<name>.md. Add more examples if it is complex or relies on resources in another service. This documentation will appear on the Terraform Registry when the resource is made available in a provider release. Link to AWS Documentation where appropriate, particularly for values which are likely to change.
A List Resource is a side-car type that adds a Listing operation to a resource type's Create, Read, Update, and Delete operations. It is easiest to add after the main CRUD functionality of the resource type is implemented, but should still be part of creating a new resource type.
See the instructions in the guide Adding a New List Resource. Full details on implementing a List Resource can be found in the List Resource Reference.
Format your code and check linters to detect various issues.
make fmt
make tools # install linters and dependencies
make lint # run provider linters
make docs-lint # run documentation linters
In general, pull requests are triaged within a few days of creation and are prioritized based on community reactions. Please view our Prioritization Guide for full details of the process.