From 276f86c5212edbaa2b42339b43b531339badfd5b Mon Sep 17 00:00:00 2001 From: magodo Date: Tue, 11 Jan 2022 15:09:09 +0800 Subject: [PATCH] Importer function to normalize resource id Normalize the ID using the importer function to conform to what is defined in the ID formatter. This is to mitigate cases like users import resource ID with lowercase 'g' for the resource group. In this case, the current validation in the importer raise no error, which results into the incorrect cased ID leak into terraform state. This will cause the other referencing resource get unexpected plan diff (see #14854). This commit adds the helper function for both untyped and typed sdk. The users are expected to pass in a wrapper function around the parse function generated via the resource id tool. While this wrapper might be eliminated once we have generic in Go. --- internal/sdk/wrapper_helpers.go | 15 +++++++++++++++ internal/tf/pluginsdk/imports.go | 19 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/internal/sdk/wrapper_helpers.go b/internal/sdk/wrapper_helpers.go index b82f8a03e972..ba5161cd89f7 100644 --- a/internal/sdk/wrapper_helpers.go +++ b/internal/sdk/wrapper_helpers.go @@ -1,10 +1,12 @@ package sdk import ( + "context" "fmt" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/resourceid" ) // combineSchema combines the arguments (user-configurable) and attributes (read-only) schema fields @@ -55,3 +57,16 @@ func runArgs(d *schema.ResourceData, meta interface{}, logger Logger) ResourceMe return metaData } + +// NormalizeIdImporter is a helper function which returns a ResourceRunFunc. +// This function is intended to be used as the CustomImporter for a ResourceWithCustomImporter. +func NormalizeIdImporter(parser func(string) (resourceid.Formatter, error)) ResourceRunFunc { + return func(ctx context.Context, metadata ResourceMetaData) error { + id, err := parser(metadata.ResourceData.Id()) + if err != nil { + return err + } + metadata.SetID(id) + return nil + } +} diff --git a/internal/tf/pluginsdk/imports.go b/internal/tf/pluginsdk/imports.go index d08463e532aa..2981642da2f6 100644 --- a/internal/tf/pluginsdk/imports.go +++ b/internal/tf/pluginsdk/imports.go @@ -5,6 +5,7 @@ import ( "fmt" "log" + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -47,3 +48,21 @@ func ImporterValidatingResourceIdThen(validateFunc IDValidationFunc, thenFunc Im }, } } + +type IDParseFunc func(string) (resourceids.Id, error) + +func ImporterValidatingThenNormalizeId(parser IDParseFunc) *schema.ResourceImporter { + return &schema.ResourceImporter{ + StateContext: func(ctx context.Context, d *ResourceData, meta interface{}) ([]*ResourceData, error) { + log.Printf("[DEBUG] Importing Resource - parsing %q", d.Id()) + + id, err := parser(d.Id()) + if err != nil { + return []*ResourceData{d}, fmt.Errorf("parsing Resource ID %q: %+v", d.Id(), err) + } + + d.SetId(id.ID()) + return []*ResourceData{d}, nil + }, + } +}