Skip to content

aws_lambda_function still updates non API properties on update errors #42695

Open
@vtstanescu

Description

@vtstanescu

Terraform and AWS Provider Version

OpenTofu v1.9.1
hashicorp/aws v5.98.0

Affected Resource(s) or Data Source(s)

  • aws_lambda_function

Expected Behavior

s3_bucket and s3_key are not updated

Actual Behavior

s3_bucket and s3_key are updated

Relevant Error/Panic Output

Error: updating Lambda Function (lambda-function) code: operation error Lambda: UpdateFunctionCode, https response error StatusCode: 403, RequestID: , api error AccessDeniedException: Your access has been denied by S3, please make sure your request credentials have permission to GetObject for binaries-bucket/lambda-package.zip. S3 Error Code: AccessDenied. S3 Error Message: User: arn:aws:sts::123456789012:assumed-role/devops-role/session-name is not authorized to perform: kms:Decrypt on resource: arn:aws:kms:eu-west-1:123456789012:key/mrk-00000000000000000000000000000000 because no identity-based policy allows the kms:Decrypt action

Sample Terraform Configuration

Any aws_lambda_function resource with s3_bucket and s3_key properties will do.

Steps to Reproduce

  1. Apply the configuration to create the function
  2. Amend the IAM role used to apply the configuration to remove some permission
    required to update the function code, like the kms:Decrypt action for S3
  3. Amend the configuration to change the s3_key
  4. Try applying the updated configuration
  5. Apply fails as your IAM role doesn't have kms:Decrypt required by s3:GetObject
    s3_key is still updated in the Terraform config
  6. Run terraform plan -> no changes required

Debug Logging

No response

GenAI / LLM Assisted Development

No response

Important Facts and References

Related to #25886, #28963

@ewbankkit I see you addressed this issue in the PR #28963.
Do you recall why the following code snippet was done this way (function.go#978)?

if err != nil {
	if errs.IsAErrorMessageContains[*awstypes.InvalidParameterValueException](err, "Error occurred while GetObject.") {
		// As s3_bucket, s3_key and s3_object_version aren't set in resourceFunctionRead(), don't ovewrite the last known good values.
		for _, key := range []string{names.AttrS3Bucket, "s3_key", "s3_object_version"} {
			old, _ := d.GetChange(key)
			d.Set(key, old)
		}
	}

	return sdkdiag.AppendErrorf(diags, "updating Lambda Function (%s) code: %s", d.Id(), err)
}

I think the setting of the old values for s3_bucket, s3_key, and s3_object_version should happen regardless of what the error was, but maybe you covered some scenarios I'm missing.

Would you like to implement a fix?

Yes

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugAddresses a defect in current functionality.service/lambdaIssues and PRs that pertain to the lambda service.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions