diff --git a/.changelog/22193.txt b/.changelog/22193.txt new file mode 100644 index 00000000000..7a970651f3e --- /dev/null +++ b/.changelog/22193.txt @@ -0,0 +1,7 @@ +```release-note:bug +resource/aws_transfer_access: Fix erroneous diffs in `policy` when no changes made or policies are equivalent +``` + +```release-note:bug +resource/aws_transfer_user: Fix erroneous diffs in `policy` when no changes made or policies are equivalent +``` \ No newline at end of file diff --git a/internal/service/transfer/access.go b/internal/service/transfer/access.go index 75a571578b9..42cbc4861d8 100644 --- a/internal/service/transfer/access.go +++ b/internal/service/transfer/access.go @@ -8,6 +8,7 @@ import ( "github.com/aws/aws-sdk-go/service/transfer" "github.com/hashicorp/aws-sdk-go-base/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/structure" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/tfresource" @@ -70,6 +71,10 @@ func ResourceAccess() *schema.Resource { Optional: true, ValidateFunc: verify.ValidIAMPolicyJSON, DiffSuppressFunc: verify.SuppressEquivalentPolicyDiffs, + StateFunc: func(v interface{}) string { + json, _ := structure.NormalizeJsonString(v) + return json + }, }, "posix_profile": { @@ -137,7 +142,13 @@ func resourceAccessCreate(d *schema.ResourceData, meta interface{}) error { } if v, ok := d.GetOk("policy"); ok { - input.Policy = aws.String(v.(string)) + policy, err := structure.NormalizeJsonString(v.(string)) + + if err != nil { + return fmt.Errorf("policy (%s) is invalid JSON: %w", v.(string), err) + } + + input.Policy = aws.String(policy) } if v, ok := d.GetOk("posix_profile"); ok { @@ -187,12 +198,21 @@ func resourceAccessRead(d *schema.ResourceData, meta interface{}) error { return fmt.Errorf("error setting home_directory_mappings: %w", err) } d.Set("home_directory_type", access.HomeDirectoryType) - d.Set("policy", access.Policy) + if err := d.Set("posix_profile", flattenTransferUserPosixUser(access.PosixProfile)); err != nil { return fmt.Errorf("error setting posix_profile: %w", err) } // Role is currently not returned via the API. // d.Set("role", access.Role) + + policyToSet, err := verify.PolicyToSet(d.Get("policy").(string), aws.StringValue(access.Policy)) + + if err != nil { + return err + } + + d.Set("policy", policyToSet) + d.Set("server_id", serverID) return nil @@ -225,7 +245,13 @@ func resourceAccessUpdate(d *schema.ResourceData, meta interface{}) error { } if d.HasChange("policy") { - input.Policy = aws.String(d.Get("policy").(string)) + policy, err := structure.NormalizeJsonString(d.Get("policy").(string)) + + if err != nil { + return fmt.Errorf("policy (%s) is invalid JSON: %w", d.Get("policy").(string), err) + } + + input.Policy = aws.String(policy) } if d.HasChange("posix_profile") { diff --git a/internal/service/transfer/user.go b/internal/service/transfer/user.go index 64fd9bcd7d3..f8ecb881ec7 100644 --- a/internal/service/transfer/user.go +++ b/internal/service/transfer/user.go @@ -8,6 +8,7 @@ import ( "github.com/aws/aws-sdk-go/service/transfer" "github.com/hashicorp/aws-sdk-go-base/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/structure" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/flex" @@ -71,6 +72,10 @@ func ResourceUser() *schema.Resource { Optional: true, ValidateFunc: verify.ValidIAMPolicyJSON, DiffSuppressFunc: verify.SuppressEquivalentPolicyDiffs, + StateFunc: func(v interface{}) string { + json, _ := structure.NormalizeJsonString(v) + return json + }, }, "posix_profile": { @@ -151,7 +156,13 @@ func resourceUserCreate(d *schema.ResourceData, meta interface{}) error { } if v, ok := d.GetOk("policy"); ok { - input.Policy = aws.String(v.(string)) + policy, err := structure.NormalizeJsonString(v.(string)) + + if err != nil { + return fmt.Errorf("policy (%s) is invalid JSON: %w", v.(string), err) + } + + input.Policy = aws.String(policy) } if v, ok := d.GetOk("posix_profile"); ok { @@ -203,7 +214,15 @@ func resourceUserRead(d *schema.ResourceData, meta interface{}) error { return fmt.Errorf("error setting home_directory_mappings: %w", err) } d.Set("home_directory_type", user.HomeDirectoryType) - d.Set("policy", user.Policy) + + policyToSet, err := verify.PolicyToSet(d.Get("policy").(string), aws.StringValue(user.Policy)) + + if err != nil { + return err + } + + d.Set("policy", policyToSet) + if err := d.Set("posix_profile", flattenTransferUserPosixUser(user.PosixProfile)); err != nil { return fmt.Errorf("error setting posix_profile: %w", err) } @@ -252,7 +271,13 @@ func resourceUserUpdate(d *schema.ResourceData, meta interface{}) error { } if d.HasChange("policy") { - input.Policy = aws.String(d.Get("policy").(string)) + policy, err := structure.NormalizeJsonString(d.Get("policy").(string)) + + if err != nil { + return fmt.Errorf("policy (%s) is invalid JSON: %w", d.Get("policy").(string), err) + } + + input.Policy = aws.String(policy) } if d.HasChange("posix_profile") {