From 8042c257b234adb79f996b355efd28d9fd32e381 Mon Sep 17 00:00:00 2001 From: Paul Tyng Date: Tue, 13 Oct 2020 13:45:36 -0400 Subject: [PATCH] Relax validation of ID attribute Fixes #607 --- helper/schema/resource.go | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/helper/schema/resource.go b/helper/schema/resource.go index f295cab7eef..f41964a5890 100644 --- a/helper/schema/resource.go +++ b/helper/schema/resource.go @@ -26,7 +26,6 @@ var ReservedResourceFields = []string{ "connection", "count", "depends_on", - "id", "lifecycle", "provider", "provisioner", @@ -649,6 +648,14 @@ func (r *Resource) InternalValidate(topSchemaMap schemaMap, writable bool) error } } + if f, ok := tsm["id"]; ok { + // if there is an explicit ID, validate it... + err := validateResourceID(f) + if err != nil { + return err + } + } + for k, f := range tsm { if isReservedResourceFieldName(k, f) { return fmt.Errorf("%s is a reserved field name", k) @@ -717,18 +724,30 @@ func isReservedDataSourceFieldName(name string) bool { return false } -func isReservedResourceFieldName(name string, s *Schema) bool { - // Allow phasing out "id" - // See https://github.com/terraform-providers/terraform-provider-aws/pull/1626#issuecomment-328881415 - if name == "id" && s.Deprecated != "" { - return false +func validateResourceID(s *Schema) error { + if s.Type != TypeString { + return fmt.Errorf(`the "id" attribute must be of TypeString`) + } + + if s.Required { + return fmt.Errorf(`the "id" attribute cannot be marked Required`) } + // ID should at least be computed. If unspecified it will be set to Computed and Optional, + // but Optional is unnecessary if undesired. + if s.Computed != true { + return fmt.Errorf(`the "id" attribute must be marked Computed`) + } + return nil +} + +func isReservedResourceFieldName(name string, s *Schema) bool { for _, reservedName := range ReservedResourceFields { if name == reservedName { return true } } + return false }