Skip to content

Adding a New List Resource#

List Resources in the Terraform AWS Provider allow users to retrieve and manage collections of AWS resources.

Each List Resource should be submitted for review individually. Pull requests containing multiple list resources or other resources are more difficult to review, and maintainers will typically request that they be split into separate submissions.

The List Resource Reference provides more detail on adding List Resources.

Prerequisites#

List Resources are dependent on Resource Identity being implemented on the target resource. Ensure that the resource identity has been created and merged first. Refer to Adding Resource Identity Support for detailed instructions.

Steps to Add a List Resource#

Naming of a new List Resource should be identical to the target resource. For example, if adding a new list resource for aws_batch_job_definition, the list resource should be named aws_batch_job_definition.

Always use the skaff provider scaffolding tool to generate new list resource and test templates using your chosen name. Existing resources can be implemented using either Terraform Plugin SDKv2 or Terraform Plugin Framework. The implementation type can be identified by inspecting the tags in the resource file.

skaff will generate the following files:

  • internal/service/<service-name>/<resource-name>_list.go - List Resource implementation
  • internal/service/<service-name>/<resource-name>_list_test.go - List Resource acceptance tests
  • website/docs/list-resources/<service-name>_<resource-name>.html.markdown - List Resource documentation
  • internal/service/<service-name>/testdata/<Resource-Name>/list_basic/main.tf - Basic List Resource acceptance test configuration
  • internal/service/<service-name>/testdata/<Resource-Name>/list_basic/query.tfquery.hcl - Query for using list resource

SDK resources#

SDKv2 target resource will have the tag @SDKResource() in the resource file. For these resources use the following, replacing <resource name> with the name of the resource being added, eg JobDefinition.

skaff list --name <resource name>

Framework resources#

Framework target resource will have the tag @FrameworkResource() in the resource file. For these resources use the following, replacing <resource-name> with the name of the resource being added, eg JobDefinition.

skaff list --framework --name <resource-name>

Fill in the List handler#

Use the AWS API documentation to resolve the appropriate types to be able to list the resource. This is typically done using Describe or List API calls.

Plugin SDK#

The annotation @SDKListResource("<resource_name>") is required to register the List Resource with the provider. The value of <resource_name> must match the name of the associated resource type.

In the iterator loop body, the resource data rd must always be populated with the id value, using rd.SetId(<value>). Any additional attributes needed for the Resource Identity must be set using rd.Set(<attribute-name>, <attribute-value>).

If the list request parameter IncludeResource is set, the resource data should be populated. This should be done using a function named resource<Resource Name>Flatten. Both the List Resource and the resource's Read operation should use this flatten function. If the function does not exist, refactor the resource's Read operation so that the body of the function that sets values on the resource data is moved to the flattening function.

Plugin Framework#

The annotation @FrameworkListResource("<resource_name>") is required to register the List Resource with the provider. The value of <resource_name> must match the name of the associated resource type.

When adding a List Resource for an existing resource type, extract the portion of the existing resource type's Read operation that flattens the API response into the resource data model into a new method flatten. For many resource types, this will simply call flex.Flatten(...).

Both the List Resource and the resource type's Read operation should call the flatten function.

Adding custom query parameters#

Sometimes a list resource will have custom query parameters that can be used to filter the results returned by the AWS API. If this is the case, these parameters should be added by implementing the ListResourceConfigSchema method on the resource. A simple example can be found on the aws_s3_object list resource.

Implement acceptance tests#

Acceptance tests are mostly generated by skaff but will need some modifications to function correctly. A functioning Terraform configuration is necessary to run the acceptance tests. The generated test configuration will need to be updated to include any required parameters for the resource.

At a minimum, a List Resource should have the following acceptance tests:

  • A basic test that validates that multiple resources can be queried
  • An includeResource test that validates that resource data is populated when IncludeResource is set to true. This includes tags, for resource types that support tagging.

List Resources for regional resources, which is most resource types, must also have:

  • A regionOverride test that validates that the region attribute on the list block overrides the default region of the provider.

In general, the configuration should be as simple as possible, avoiding optional attributes. One exception is if a resource type has an optional name attribute or the combination of name and name_prefix. In that case, name should be specified if the name value is used in the Resource Identity.

If a resource type has attribute settings that could affect listing behavior, additional tests to validate that behavior should be added.

For more information on acceptance tests for List Resource, see the Acceptance Testing section of the List Resource Reference.

Example test file#

resource "aws_batch_job_definition" "test" {
  count = var.resource_count

  name = "${var.rName}-${count.index}"

  type = "container"
  container_properties = jsonencode({
    image  = "busybox"
    vcpus  = 1
    memory = 128
  })
}

variable "rName" {
  description = "Name for resource"
  type        = string
  nullable    = false
}

variable "resource_count" {
  description = "The number of resources to create"
  type        = number
  nullable    = false
}

Compilation Checks#

Once code changes are made, do some basic verification to ensure the provider and tests still compile.

To verify the provider compiles:

make fmt
make build

To verify tests compile:

go test -c ./internal/service/<service>

Register List Resource to the provider#

To register the new list resource:

go generate ./internal/service/<service>

Run Acceptance Tests#

Run the acceptance tests for the new list resource to ensure everything is functioning as expected. Replace <service-name> and <resource-name> with the appropriate service and resource names.

  make testacc PKG=<service-name> TESTARGS='-run=TestAcc<service-name><resource-name>_List_'

Troubleshooting#

Prerequisites Issues#

  • Resource Identity Missing: List resources require the target resource to have resource identity implemented first. This is a hard blocker - the list resource cannot be created without it.

Common Implementation Issues#

  • Incorrect AWS API Types: The skaff generator may use incorrect response types. Check AWS API documentation for the correct type (e.g., awstypes.Batch vs awstypes.BatchDefinition)
  • Resource Identifier: Use the same identifier as the target resource (often name, not ARN)

Test Configuration Issues#

  • Minimal Generated Config: Generated test configurations are basic and need substantial updates with all required resource dependencies.
  • PreCheck Functions: Remove custom precheck functions unless they exist - use standard acctest.PreCheck(ctx, t).
  • ARN Validation: ARNs have multiple forms and may cause the test check to fail. Find the correct format for the <resource-name> and update the validation.