Skip to content

aws_lambda_permission not recreated when aws_lambda_function package_type forces replacement #46632

@Varahasai5S0

Description

@Varahasai5S0

Terraform and AWS Provider Version

## Terraform Version

Terraform v1.5.7


## AWS Provider Version

hashicorp/aws v6.33.0

Affected Resource(s) or Data Source(s)

  • aws_lambda_function
  • aws_lambda_permission

Expected Behavior

When changing package_type from "Zip" to "Image", both aws_lambda_function and aws_lambda_permission should be planned for replacement in a single apply:

Plan: 2 to add, 0 to change, 2 to destroy

# aws_lambda_function.test must be replaced
# aws_lambda_permission.allow_api must be replaced

Actual Behavior

Only aws_lambda_function is planned for replacement. The aws_lambda_permission is not included in the plan:

Plan: 1 to add, 0 to change, 1 to destroy

# aws_lambda_function.test must be replaced
# aws_lambda_permission.allow_api - NO CHANGE PLANNED

After the first apply:

  • Lambda function is successfully replaced
  • Permission is missing from the function (verified with aws lambda get-policy)
  • Terraform state still shows the permission as existing (state drift)

A second apply is required to recreate the permission:

Plan: 1 to add, 0 to change, 0 to destroy

# aws_lambda_permission.allow_api will be created

Sample Terraform Configuration

Terraform Configuration

provider "aws" {
  region = "us-east-1"
}

resource "aws_iam_role" "lambda_role" {
  name = "test_lambda_role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Action = "sts:AssumeRole"
      Effect = "Allow"
      Principal = {
        Service = "lambda.amazonaws.com"
      }
    }]
  })
}

resource "aws_lambda_function" "test" {
  filename      = "lambda.zip"
  function_name = "test_function"
  role          = aws_iam_role.lambda_role.arn
  handler       = "index.handler"
  runtime       = "python3.9"
  package_type  = "Zip"

  source_code_hash = filebase64sha256("lambda.zip")
}

resource "aws_lambda_permission" "allow_api" {
  statement_id  = "AllowExecutionFromAPI"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.test.function_name
  principal     = "apigateway.amazonaws.com"
}

Steps to Reproduce

  1. Create initial infrastructure with package_type = "Zip"
terraform init
terraform apply -auto-approve
  1. Verify permission exists:
aws lambda get-policy --function-name test_function --region us-east-1
# Returns policy with AllowExecutionFromAPI statement
  1. Change package_type to "Image" and update configuration accordingly:
resource "aws_lambda_function" "test" {
  image_uri     = "ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/repo:tag"
  function_name = "test_function"
  role          = aws_iam_role.lambda_role.arn
  package_type  = "Image"
}
  1. Run terraform plan:
terraform plan
# Shows only function replacement, not permission
  1. Apply changes:
terraform apply -auto-approve
  1. Verify permission is missing:
aws lambda get-policy --function-name test_function --region us-east-1
# Returns: ResourceNotFoundException - The resource you requested does not exist
  1. Run second apply to fix:
terraform apply -auto-approve
# Now shows permission needs to be created

Important Facts and References

Assumption:

When a Lambda function is destroyed and recreated (replacement), AWS automatically deletes all associated resource-based policies (permissions). However, Terraform does not detect this cascading deletion when only package_type changes.

The issue occurs because:

  1. package_type change forces Lambda function replacement (destroy then create)
  2. AWS deletes all permissions when the function is destroyed
  3. Terraform doesn't recognize that dependent aws_lambda_permission resources need recreation
  4. The permission remains in Terraform state but doesn't exist in AWS (state drift)
  5. Second apply detects the drift during refresh and recreates the permission

Confirm how we can resolve this issue?

Would you like to implement a fix?

No

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugAddresses a defect in current functionality.needs-triageWaiting for first response or review from a maintainer.service/iamIssues and PRs that pertain to the iam service.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