From a8406815443ab2476e20c81661c9040583d5a755 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 18 Aug 2023 15:03:34 -0400 Subject: [PATCH 1/4] r/aws_lambda_layer_version: Restore 'ForceNew' on 'source_code_hash'. --- internal/service/lambda/layer_version.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/service/lambda/layer_version.go b/internal/service/lambda/layer_version.go index 94cf43419c6..437daab5607 100644 --- a/internal/service/lambda/layer_version.go +++ b/internal/service/lambda/layer_version.go @@ -127,6 +127,7 @@ func ResourceLayerVersion() *schema.Resource { Type: schema.TypeString, Optional: true, Computed: true, + ForceNew: true, }, "source_code_size": { Type: schema.TypeInt, From 1c9439f69c1f4f28553fcf89587ed750c53aeee5 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 18 Aug 2023 15:07:17 -0400 Subject: [PATCH 2/4] Add CHANGELOG entry. --- .changelog/#####.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/#####.txt diff --git a/.changelog/#####.txt b/.changelog/#####.txt new file mode 100644 index 00000000000..bbbee8e6eb9 --- /dev/null +++ b/.changelog/#####.txt @@ -0,0 +1,3 @@ +```release-note:bug +resource/aws_lambda_layer_version: Change `source_code_hash` back to [ForceNew](https://developer.hashicorp.com/terraform/plugin/sdkv2/schemas/schema-behaviors#forcenew). This fixes `doesn't support update` errors +``` \ No newline at end of file From e2473305329ea372ffe88132094d6bbfe067ae11 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 18 Aug 2023 15:32:41 -0400 Subject: [PATCH 3/4] r/aws_lambda_layer_version: Add and use 'FindLayerVersionByTwoPartKey'. --- internal/service/lambda/layer_version.go | 115 +++++++++--------- internal/service/lambda/layer_version_test.go | 74 +++++------ 2 files changed, 88 insertions(+), 101 deletions(-) diff --git a/internal/service/lambda/layer_version.go b/internal/service/lambda/layer_version.go index 437daab5607..ad5743f6adc 100644 --- a/internal/service/lambda/layer_version.go +++ b/internal/service/lambda/layer_version.go @@ -15,11 +15,13 @@ import ( "github.com/aws/aws-sdk-go/service/lambda" "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" "github.com/hashicorp/terraform-provider-aws/internal/flex" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) const mutexLayerKey = `aws_lambda_layer_version` @@ -201,6 +203,7 @@ func resourceLayerVersionPublish(ctx context.Context, d *schema.ResourceData, me } d.SetId(aws.StringValue(result.LayerVersionArn)) + return append(diags, resourceLayerVersionRead(ctx, d, meta)...) } @@ -208,96 +211,92 @@ func resourceLayerVersionRead(ctx context.Context, d *schema.ResourceData, meta var diags diag.Diagnostics conn := meta.(*conns.AWSClient).LambdaConn(ctx) - layerName, version, err := LayerVersionParseID(d.Id()) + layerName, versionNumber, err := LayerVersionParseID(d.Id()) if err != nil { - return sdkdiag.AppendErrorf(diags, "parsing lambda layer ID: %s", err) + return sdkdiag.AppendFromErr(diags, err) } - layerVersion, err := conn.GetLayerVersionWithContext(ctx, &lambda.GetLayerVersionInput{ - LayerName: aws.String(layerName), - VersionNumber: aws.Int64(version), - }) + output, err := FindLayerVersionByTwoPartKey(ctx, conn, layerName, versionNumber) - if tfawserr.ErrCodeEquals(err, lambda.ErrCodeResourceNotFoundException) { - log.Printf("[WARN] Lambda Layer Version (%s) not found, removing from state", d.Id()) + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] Lambda Layer Version %s not found, removing from state", d.Id()) d.SetId("") - return diags + return nil } if err != nil { - return sdkdiag.AppendErrorf(diags, "reading Lambda Layer version (%s): %s", d.Id(), err) - } - - if err := d.Set("layer_name", layerName); err != nil { - return sdkdiag.AppendErrorf(diags, "setting lambda layer name: %s", err) - } - if err := d.Set("version", strconv.FormatInt(version, 10)); err != nil { - return sdkdiag.AppendErrorf(diags, "setting lambda layer version: %s", err) - } - if err := d.Set("arn", layerVersion.LayerVersionArn); err != nil { - return sdkdiag.AppendErrorf(diags, "setting lambda layer version arn: %s", err) - } - if err := d.Set("layer_arn", layerVersion.LayerArn); err != nil { - return sdkdiag.AppendErrorf(diags, "setting lambda layer arn: %s", err) - } - if err := d.Set("description", layerVersion.Description); err != nil { - return sdkdiag.AppendErrorf(diags, "setting lambda layer description: %s", err) - } - if err := d.Set("license_info", layerVersion.LicenseInfo); err != nil { - return sdkdiag.AppendErrorf(diags, "setting lambda layer license info: %s", err) - } - if err := d.Set("created_date", layerVersion.CreatedDate); err != nil { - return sdkdiag.AppendErrorf(diags, "setting lambda layer created date: %s", err) - } - if err := d.Set("source_code_hash", layerVersion.Content.CodeSha256); err != nil { - return sdkdiag.AppendErrorf(diags, "setting lambda layer source code hash: %s", err) - } - if err := d.Set("signing_profile_version_arn", layerVersion.Content.SigningProfileVersionArn); err != nil { - return sdkdiag.AppendErrorf(diags, "setting lambda layer signing profile arn: %s", err) - } - if err := d.Set("signing_job_arn", layerVersion.Content.SigningJobArn); err != nil { - return sdkdiag.AppendErrorf(diags, "setting lambda layer signing job arn: %s", err) - } - if err := d.Set("source_code_size", layerVersion.Content.CodeSize); err != nil { - return sdkdiag.AppendErrorf(diags, "setting lambda layer source code size: %s", err) - } - if err := d.Set("compatible_runtimes", flex.FlattenStringList(layerVersion.CompatibleRuntimes)); err != nil { - return sdkdiag.AppendErrorf(diags, "setting lambda layer compatible runtimes: %s", err) + return diag.Errorf("reading Lambda Layer Version (%s): %s", d.Id(), err) } - if err := d.Set("compatible_architectures", flex.FlattenStringList(layerVersion.CompatibleArchitectures)); err != nil { - return sdkdiag.AppendErrorf(diags, "setting lambda layer compatible architectures: %s", err) - } + d.Set("arn", output.LayerVersionArn) + d.Set("compatible_architectures", aws.StringValueSlice(output.CompatibleArchitectures)) + d.Set("compatible_runtimes", aws.StringValueSlice(output.CompatibleRuntimes)) + d.Set("created_date", output.CreatedDate) + d.Set("description", output.Description) + d.Set("layer_arn", output.LayerArn) + d.Set("layer_name", layerName) + d.Set("license_info", output.LicenseInfo) + d.Set("signing_job_arn", output.Content.SigningJobArn) + d.Set("signing_profile_version_arn", output.Content.SigningProfileVersionArn) + d.Set("source_code_hash", output.Content.CodeSha256) + d.Set("source_code_size", output.Content.CodeSize) + d.Set("version", strconv.FormatInt(versionNumber, 10)) return diags } func resourceLayerVersionDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - if v, ok := d.GetOk("skip_destroy"); ok && v.(bool) { + conn := meta.(*conns.AWSClient).LambdaConn(ctx) + + if d.Get("skip_destroy").(bool) { log.Printf("[DEBUG] Retaining Lambda Layer Version %q", d.Id()) return diags } - conn := meta.(*conns.AWSClient).LambdaConn(ctx) - - version, err := strconv.ParseInt(d.Get("version").(string), 10, 64) + layerName, versionNumber, err := LayerVersionParseID(d.Id()) if err != nil { - return sdkdiag.AppendErrorf(diags, "parsing lambda layer version: %s", err) + return sdkdiag.AppendFromErr(diags, err) } _, err = conn.DeleteLayerVersionWithContext(ctx, &lambda.DeleteLayerVersionInput{ - LayerName: aws.String(d.Get("layer_name").(string)), - VersionNumber: aws.Int64(version), + LayerName: aws.String(layerName), + VersionNumber: aws.Int64(versionNumber), }) + if err != nil { return sdkdiag.AppendErrorf(diags, "deleting Lambda Layer Version (%s): %s", d.Id(), err) } - log.Printf("[DEBUG] Lambda layer %q deleted", d.Get("arn").(string)) return diags } +func FindLayerVersionByTwoPartKey(ctx context.Context, conn *lambda.Lambda, layerName string, versionNumber int64) (*lambda.GetLayerVersionOutput, error) { + input := &lambda.GetLayerVersionInput{ + LayerName: aws.String(layerName), + VersionNumber: aws.Int64(versionNumber), + } + + output, err := conn.GetLayerVersionWithContext(ctx, input) + + if tfawserr.ErrCodeEquals(err, lambda.ErrCodeResourceNotFoundException) { + return nil, &retry.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + if err != nil { + return nil, err + } + + if output == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + return output, nil +} + func LayerVersionParseID(id string) (layerName string, version int64, err error) { arn, err := arn2.Parse(id) if err != nil { diff --git a/internal/service/lambda/layer_version_test.go b/internal/service/lambda/layer_version_test.go index df06cda191e..89183d7dcd9 100644 --- a/internal/service/lambda/layer_version_test.go +++ b/internal/service/lambda/layer_version_test.go @@ -6,18 +6,16 @@ package lambda_test import ( "context" "fmt" - "strconv" "testing" - "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/lambda" - "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/hashicorp/terraform-provider-aws/internal/acctest" "github.com/hashicorp/terraform-provider-aws/internal/conns" tflambda "github.com/hashicorp/terraform-provider-aws/internal/service/lambda" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) func TestAccLambdaLayerVersion_basic(t *testing.T) { @@ -34,7 +32,7 @@ func TestAccLambdaLayerVersion_basic(t *testing.T) { { Config: testAccLayerVersionConfig_basic(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckLayerVersionExists(ctx, resourceName, rName), + testAccCheckLayerVersionExists(ctx, resourceName), acctest.CheckResourceAttrRegionalARN(resourceName, "arn", "lambda", fmt.Sprintf("layer:%s:1", rName)), resource.TestCheckResourceAttr(resourceName, "compatible_runtimes.#", "0"), resource.TestCheckResourceAttr(resourceName, "description", ""), @@ -71,7 +69,7 @@ func TestAccLambdaLayerVersion_update(t *testing.T) { { Config: testAccLayerVersionConfig_createBeforeDestroy(rName, "test-fixtures/lambdatest.zip"), Check: resource.ComposeTestCheckFunc( - testAccCheckLayerVersionExists(ctx, resourceName, rName), + testAccCheckLayerVersionExists(ctx, resourceName), acctest.CheckResourceAttrRegionalARN(resourceName, "arn", "lambda", fmt.Sprintf("layer:%s:1", rName)), ), }, @@ -84,7 +82,7 @@ func TestAccLambdaLayerVersion_update(t *testing.T) { { Config: testAccLayerVersionConfig_createBeforeDestroy(rName, "test-fixtures/lambdatest_modified.zip"), Check: resource.ComposeTestCheckFunc( - testAccCheckLayerVersionExists(ctx, resourceName, rName), + testAccCheckLayerVersionExists(ctx, resourceName), acctest.CheckResourceAttrRegionalARN(resourceName, "arn", "lambda", fmt.Sprintf("layer:%s:2", rName)), ), }, @@ -106,21 +104,21 @@ func TestAccLambdaLayerVersion_sourceCodeHash(t *testing.T) { { Config: testAccLayerVersionConfig_sourceCodeHash(rName, "test-fixtures/lambdatest.zip"), Check: resource.ComposeTestCheckFunc( - testAccCheckLayerVersionExists(ctx, resourceName, rName), + testAccCheckLayerVersionExists(ctx, resourceName), acctest.CheckResourceAttrRegionalARN(resourceName, "arn", "lambda", fmt.Sprintf("layer:%s:1", rName)), ), }, { Config: testAccLayerVersionConfig_sourceCodeHash(rName, "test-fixtures/lambdatest.zip"), Check: resource.ComposeTestCheckFunc( - testAccCheckLayerVersionExists(ctx, resourceName, rName), + testAccCheckLayerVersionExists(ctx, resourceName), acctest.CheckResourceAttrRegionalARN(resourceName, "arn", "lambda", fmt.Sprintf("layer:%s:1", rName)), ), }, { Config: testAccLayerVersionConfig_sourceCodeHash(rName, "test-fixtures/lambdatest_modified.zip"), Check: resource.ComposeTestCheckFunc( - testAccCheckLayerVersionExists(ctx, resourceName, rName), + testAccCheckLayerVersionExists(ctx, resourceName), acctest.CheckResourceAttrRegionalARN(resourceName, "arn", "lambda", fmt.Sprintf("layer:%s:2", rName)), ), }, @@ -141,7 +139,7 @@ func TestAccLambdaLayerVersion_s3(t *testing.T) { Steps: []resource.TestStep{ { Config: testAccLayerVersionConfig_s3(rName), - Check: testAccCheckLayerVersionExists(ctx, resourceName, rName), + Check: testAccCheckLayerVersionExists(ctx, resourceName), }, { @@ -168,7 +166,7 @@ func TestAccLambdaLayerVersion_compatibleRuntimes(t *testing.T) { { Config: testAccLayerVersionConfig_compatibleRuntimes(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckLayerVersionExists(ctx, resourceName, rName), + testAccCheckLayerVersionExists(ctx, resourceName), resource.TestCheckResourceAttr(resourceName, "compatible_runtimes.#", "2"), ), }, @@ -197,14 +195,14 @@ func TestAccLambdaLayerVersion_compatibleArchitectures(t *testing.T) { { Config: testAccLayerVersionConfig_compatibleArchitecturesNone(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckLayerVersionExists(ctx, resourceName, rName), + testAccCheckLayerVersionExists(ctx, resourceName), resource.TestCheckResourceAttr(resourceName, "compatible_architectures.#", "0"), ), }, { Config: testAccLayerVersionConfig_compatibleArchitecturesX86(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckLayerVersionExists(ctx, resourceName, rName), + testAccCheckLayerVersionExists(ctx, resourceName), resource.TestCheckResourceAttr(resourceName, "compatible_architectures.#", "1"), resource.TestCheckTypeSetElemAttr(resourceName, "compatible_architectures.*", lambda.ArchitectureX8664), ), @@ -212,14 +210,14 @@ func TestAccLambdaLayerVersion_compatibleArchitectures(t *testing.T) { { Config: testAccLayerVersionConfig_compatibleArchitecturesArm(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckLayerVersionExists(ctx, resourceName, rName), + testAccCheckLayerVersionExists(ctx, resourceName), resource.TestCheckResourceAttr(resourceName, "compatible_architectures.#", "1"), ), }, { Config: testAccLayerVersionConfig_compatibleArchitecturesX86Arm(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckLayerVersionExists(ctx, resourceName, rName), + testAccCheckLayerVersionExists(ctx, resourceName), resource.TestCheckResourceAttr(resourceName, "compatible_architectures.#", "2"), ), }, @@ -249,7 +247,7 @@ func TestAccLambdaLayerVersion_description(t *testing.T) { { Config: testAccLayerVersionConfig_description(rName, testDescription), Check: resource.ComposeTestCheckFunc( - testAccCheckLayerVersionExists(ctx, resourceName, rName), + testAccCheckLayerVersionExists(ctx, resourceName), resource.TestCheckResourceAttr(resourceName, "description", testDescription), ), }, @@ -279,7 +277,7 @@ func TestAccLambdaLayerVersion_licenseInfo(t *testing.T) { { Config: testAccLayerVersionConfig_licenseInfo(rName, testLicenseInfo), Check: resource.ComposeTestCheckFunc( - testAccCheckLayerVersionExists(ctx, resourceName, rName), + testAccCheckLayerVersionExists(ctx, resourceName), resource.TestCheckResourceAttr(resourceName, "license_info", testLicenseInfo), ), }, @@ -303,12 +301,12 @@ func TestAccLambdaLayerVersion_skipDestroy(t *testing.T) { PreCheck: func() { acctest.PreCheck(ctx, t) }, ErrorCheck: acctest.ErrorCheck(t, lambda.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, - CheckDestroy: nil, // this purposely leaves dangling resources, since skip_destroy = true + CheckDestroy: acctest.CheckDestroyNoop, // this purposely leaves dangling resources, since skip_destroy = true Steps: []resource.TestStep{ { Config: testAccLayerVersionConfig_skipDestroy(rName, "nodejs14.x"), Check: resource.ComposeTestCheckFunc( - testAccCheckLayerVersionExists(ctx, resourceName, rName), + testAccCheckLayerVersionExists(ctx, resourceName), acctest.CheckResourceAttrRegionalARN(resourceName, "arn", "lambda", fmt.Sprintf("layer:%s:1", rName)), resource.TestCheckResourceAttr(resourceName, "compatible_runtimes.#", "1"), resource.TestCheckResourceAttr(resourceName, "skip_destroy", "true"), @@ -317,7 +315,7 @@ func TestAccLambdaLayerVersion_skipDestroy(t *testing.T) { { Config: testAccLayerVersionConfig_skipDestroy(rName, "nodejs16.x"), Check: resource.ComposeTestCheckFunc( - testAccCheckLayerVersionExists(ctx, resourceName, rName), + testAccCheckLayerVersionExists(ctx, resourceName), acctest.CheckResourceAttrRegionalARN(resourceName, "arn", "lambda", fmt.Sprintf("layer:%s:2", rName)), resource.TestCheckResourceAttr(resourceName, "compatible_runtimes.#", "1"), resource.TestCheckResourceAttr(resourceName, "skip_destroy", "true"), @@ -336,54 +334,44 @@ func testAccCheckLayerVersionDestroy(ctx context.Context) resource.TestCheckFunc continue } - layerName, version, err := tflambda.LayerVersionParseID(rs.Primary.ID) + layerName, versionNumber, err := tflambda.LayerVersionParseID(rs.Primary.ID) if err != nil { return err } - _, err = conn.GetLayerVersionWithContext(ctx, &lambda.GetLayerVersionInput{ - LayerName: aws.String(layerName), - VersionNumber: aws.Int64(version), - }) - if tfawserr.ErrCodeEquals(err, lambda.ErrCodeResourceNotFoundException) { + _, err = tflambda.FindLayerVersionByTwoPartKey(ctx, conn, layerName, versionNumber) + + if tfresource.NotFound(err) { continue } + if err != nil { return err } - return fmt.Errorf("Lambda Layer Version (%s) still exists", rs.Primary.ID) + return fmt.Errorf("Lambda Layer Version %s still exists", rs.Primary.ID) } return nil } } -func testAccCheckLayerVersionExists(ctx context.Context, res, layerName string) resource.TestCheckFunc { +func testAccCheckLayerVersionExists(ctx context.Context, n string) resource.TestCheckFunc { return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[res] + rs, ok := s.RootModule().Resources[n] if !ok { - return fmt.Errorf("Lambda Layer version not found: %s", res) - } - - if rs.Primary.ID == "" { - return fmt.Errorf("Lambda Layer ID not set") + return fmt.Errorf("Not found: %s", n) } - if rs.Primary.Attributes["version"] == "" { - return fmt.Errorf("Lambda Layer Version not set") - } - - version, err := strconv.Atoi(rs.Primary.Attributes["version"]) + layerName, versionNumber, err := tflambda.LayerVersionParseID(rs.Primary.ID) if err != nil { return err } conn := acctest.Provider.Meta().(*conns.AWSClient).LambdaConn(ctx) - _, err = conn.GetLayerVersionWithContext(ctx, &lambda.GetLayerVersionInput{ - LayerName: aws.String(layerName), - VersionNumber: aws.Int64(int64(version)), - }) + + _, err = tflambda.FindLayerVersionByTwoPartKey(ctx, conn, layerName, versionNumber) + return err } } From 3729fab8f5f1da0fd23e81f0d5fb21e6fb2b4d3c Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 18 Aug 2023 15:35:39 -0400 Subject: [PATCH 4/4] Correct CHANGELOG entry file name. --- .changelog/{#####.txt => 33097.txt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .changelog/{#####.txt => 33097.txt} (100%) diff --git a/.changelog/#####.txt b/.changelog/33097.txt similarity index 100% rename from .changelog/#####.txt rename to .changelog/33097.txt