Skip to content

Latest commit

 

History

History
34 lines (26 loc) · 5.89 KB

checklist-resource.md

File metadata and controls

34 lines (26 loc) · 5.89 KB

New Resource Checklist

Implementing a new resource is a good way to learn more about how Terraform interacts with upstream APIs. There are plenty of examples to draw from in the existing resources, but you still get to implement something completely new.

  • Plugin Framework: All new resources should go into the internal/provider folder and utilize the Terraform Plugin Framework when developing a new resource or data source. New resources should also go in a folder that corresponds to the product name (e.g. vaultsecrets).
  • Minimal LOC: It can be inefficient for both the reviewer and author to go through long feedback cycles on a big PR with many resources. We therefore encourage you to only submit 1 resource at a time.
  • Acceptance Tests: New resources should include acceptance tests covering their behavior. See Writing Acceptance Tests below for a detailed guide on how to approach these.
  • Documentation: Each resource gets a page in the Terraform Registry documentation. For a new resource, you'll want to add an example and field descriptions. A guide is required if the new feature requires multiple dependent resources to use.
  • Well-formed Code: Do your best to follow existing conventions you see in the codebase, and ensure your code is formatted with go fmt. The PR reviewers can help out on this front, and may provide comments with suggestions on how to improve the code.

Schema

  • Uses Globally Unique ID: The id field needs to be globally unique. Since many of the HCP services use IDs that are only unique within a particular project, you may need to create an id for Terraform using the linkURL() helper function. This function will produce an id of the following format: /project/<project_id>/<resource_type>/<resource_id>. If the service uses ID for a resource ID that is not globally unique, the resource ID should be specified in the Terraform schema as <resource_type>_id.
  • Validates Fields Where Possible: All fields that can be validated client-side should include a ValidateFunc or ValidateDiagFunc. These validations should favor validators provided by this project, or Terraform helper/validation package functions.
  • Supports Optional Project ID Input: If the resource has multi-project support, there should be an optional input field for project_id in the schema. If the user does not provide a project_id for the resource, client.Config.ProjectID should be used to retrieve the implied project ID from the provider. The user may provide a project_id to the provider, otherwise the provider uses the authentication scope to determine the oldest accessible project. This prevents the user from needing to locate and provide their project ID for single-project organizations.

CRUD Operations

  • Uses Context-Aware CRUD Functions: The context-aware CRUD functions (eg. CreateContext, ReadContext, etc.) should be used over their deprecated counterparts (eg. Create, Read, etc.).
  • Uses Context For API Calls: The context.Context that is passed into the CRUD functions should be passed into all API calls, most often by setting the Context field of a *Params object. This allows the API calls to be cancelled properly by Terraform.
  • Uses DRY API Calls: API calls that are needed in more than one resource should be encapsulated in a wrapper function located in internal/clients/. This prevents verbose request blocks from being duplicated across the codebase. Wrapper functions can also be implemented for single-use API requests, but are not required.
  • Handles Existing Resource Prior To Create: Before calling the API creation function, there should be a check to ensure that the resource does not already exist. If it does exist, the user should see a helpful log message that they may need to import the resource.
  • Implements Immediate Resource ID Set During Create: Immediately after calling the API creation function, the resource ID should be set with d.SetId() before other API operations or returning.
  • Refreshes Attributes During Read: All attributes available in the API should have d.Set() called to set their values in the Terraform state during the Read function.
  • Handles Removed Resource During Read: If a resource is removed outside of Terraform (e.g. via different tool, API, or web UI), d.SetId("") and return nil can be used in the resource Read function to trigger resource recreation. When this occurs, a warning log message should be printed beforehand.
  • Handles Failed State During Read: If a resource fails during an operation and ends up in a failed state, d.SetId("") and return nil can be used in the resource Read function to trigger resource recreation. When this occurs, a warning log message should be printed beforehand.
  • Handles Nonexistent Resource Prior To Delete: Before calling the API deletion function, there should be a check to ensure that the resource exists. If it does not exist, the user should see a helpful log message that no action was taken.

Documentation

  • Includes Descriptions For Resource And Fields: The resource and all fields in the schema should include a Description, which will be used when generating the docs.
  • Includes Example: The resource should include an example in examples/resources/<resource>/resource.tf, which will be used when generating the docs.
  • Includes Generated Docs: The docs should be regenerated using go generate, which will update files in the docs/ directory.