hashicorp / hashicorp/terraform-plugin-sdk

Allow provider to define uniqueness of a resource

Open
#224 7 comments 30 reactions 0 assignees View on GitHub
enhancement upstream-protocol upstream-terraform
Dominant language
Go
Stars
485
Forks
244
Avg merge
19h 57m
Merged PRs (30d)
4

Description

## Problem Statement

### ID field
Each resource today has an ability to set an ID.

This was and to some extent still is treated as a "meta-field" which is special-cased throughout Terraform and SDK, e.g. it has its own getter/setter (`ResourceData.GetId()`, `ResourceData.SetId()`), existence of ID was (in Terraform `<0.12`) internally used as indicator whether a resource exists or not and it is currently the easiest way to import resources (via their ID) and `id` is always available in CRUD but must not be overridden in the schema.

ID is however assigned when the resource has either started the process of creation or finished creating (in CRUD). Terraform currently has no way of constructing unique identifier beforehand and therefore no way of predicting whether it will collide with any other unique identifier (it doesn't even attempt to do so for that reason).

### Example

DNS is a globally shared namespace and it's possible that in some DNS providers you are able to create duplicate domains for valid reasons (e.g. migration), but often times this is not possible. Route53 will return error for one of the following zones - depending on which one is scheduled for creation 1st while Terraform parallelises requests.

```hcl
resource "aws_route53_zone" "primary" {
name = "example.com"
}

resource "aws_route53_zone" "secondary" {
name = "example.com"
}
```

## Proposal

Implementation is likely to be subject to RFC & further discussion.

The schema could allow marking certain fields as "identifier", then core would be able to query provider for such enhanced schema and combined with values from the config it should be able to tell if there are any duplicate resources.

### (hypothetical) Example

```go
func resourceAwsRoute53Zone() *schema.Resource {
return &schema.Resource{
// ...
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
IsIdentifier: true,
},
```
then assuming the HCL config from above
```
$ terraform plan

Error: 2 duplicate resources found.

on main.tf line 2, in resource "aws_route53_zone" "primary":
1: resource "aws_route53_zone" "primary" {
2: name = "example.com"
```

Better and more detailed diagnostic messages are subject to our ability to either display & highlight multiple fields which can make up the identifier or be able to identify the most important one in case there's more than one.

## References

- https://github.com/hashicorp/terraform/issues/22094
- https://github.com/terraform-providers/terraform-provider-aws/issues/367
- https://github.com/terraform-providers/terraform-provider-aws/issues/501
- https://github.com/terraform-providers/terraform-provider-aws/issues/539
- https://github.com/terraform-providers/terraform-provider-aws/issues/3209
- https://github.com/terraform-providers/terraform-provider-aws/issues/3737
- https://github.com/terraform-providers/terraform-provider-aws/issues/6212
- https://github.com/terraform-providers/terraform-provider-aws/issues/6245
- https://github.com/terraform-providers/terraform-provider-aws/issues/9223 (where an operator may have accidentally added a duplicate resource)

Contributor guide

Open the contributing guide

Research direction

No implementation files or tests are named. Start by reading the proposed schema.Resource and Schema entry points, then review the RFC and linked issue discussions to understand the unresolved design; done requires an agreed provider/core identifier design rather than only the hypothetical IsIdentifier field.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
backend-api-design, developer-experience
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.