hashicorp / hashicorp/terraform-plugin-sdk
Allow provider to define uniqueness of a resource
- 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
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