[Bug]: r/aws_lambda_invocation: Upgrade to v5.1.0
causes new invocation #40954
Closed
Description
Terraform Core Version
1.10.4
AWS Provider Version
5.83.0
Affected Resource(s)
aws_lambda_invocation
Expected Behavior
When updating an existing configuration from a provider version below v5.1.0
, the upgrade process should not trigger a new invocation.
Actual Behavior
A new invocation is made after upgrading to a version >v5.1.0, even when the default lifecycle_scope
of CREATE_ONLY
is added.
Terraform Configuration Files
main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
# start with this version
version = "4.20.0"
# upgrade to anything after v5.1.0
# version = "5.83.0"
}
}
}
provider "aws" {}
### Lambda function setup
data "aws_partition" "current" {}
data "aws_iam_policy_document" "test" {
statement {
effect = "Allow"
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["lambda.${data.aws_partition.current.dns_suffix}"]
}
}
}
resource "aws_iam_role" "test" {
name = "jb-test-lambda-invocation"
assume_role_policy = data.aws_iam_policy_document.test.json
}
resource "aws_iam_role_policy_attachment" "test" {
policy_arn = "arn:${data.aws_partition.current.partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
role = aws_iam_role.test.name
}
resource "aws_lambda_function" "test" {
depends_on = [aws_iam_role_policy_attachment.test]
filename = "lambda_function.zip"
function_name = "jb-test"
role = aws_iam_role.test.arn
handler = "lambda_function.lambda_handler"
runtime = "python3.9"
environment {
variables = {
TEST_DATA = "value3"
}
}
}
### End Lambda function setup
resource "aws_lambda_invocation" "example" {
function_name = aws_lambda_function.test.function_name
input = jsonencode({
key1 = "value1"
key2 = "value2"
})
}
output "result_entry" {
value = jsondecode(aws_lambda_invocation.example.result)
}
lambda_function.py
import json
import random
def lambda_handler(event, context):
#Generate a random number
random_number = random.randint(1,1000000)
return {
'statusCode': 200,
'body': json.dumps({'random_number': random_number})
}
Steps to Reproduce
- Provision the configuration above.
- Switch
main.tf
to the latest version of the AWS Terraform provider. - Run
terraform init -upgrade
. - Run
terraform apply
. The plan will display new arguments with default values being added to theaws_lambda_invocation
resource. The apply itself will trigger a new invocation of the lambda function, despite the defaultlifecycle_scope
ofCREATE_ONLY
.
Debug Output
Output after the initial apply (v4.20.0
):
Apply complete! Resources: 4 added, 0 changed, 0 destroyed.
Outputs:
result_entry = {
"body" = "{\"random_number\": 770797}"
"statusCode" = 200
}
First apply after upgrading to v5.83.0
(note the output initially indicates the result has not changed):
terraform apply -auto-approve
data.aws_partition.current: Reading...
data.aws_partition.current: Read complete after 0s [id=aws]
data.aws_iam_policy_document.test: Reading...
data.aws_iam_policy_document.test: Read complete after 0s [id=2690255455]
aws_iam_role.test: Refreshing state... [id=jb-test-lambda-invocation]
aws_iam_role_policy_attachment.test: Refreshing state... [id=jb-test-lambda-invocation-20250115194909810400000001]
aws_lambda_function.test: Refreshing state... [id=jb-test]
aws_lambda_invocation.example: Refreshing state... [id=jb-test_$LATEST_ff45cc3835165307ef414c23ca2c6f67]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
~ update in-place
Terraform will perform the following actions:
# aws_lambda_invocation.example will be updated in-place
~ resource "aws_lambda_invocation" "example" {
id = "jb-test_$LATEST_ff45cc3835165307ef414c23ca2c6f67"
+ lifecycle_scope = "CREATE_ONLY"
+ terraform_key = "tf"
# (4 unchanged attributes hidden)
}
Plan: 0 to add, 1 to change, 0 to destroy.
aws_lambda_invocation.example: Modifying... [id=jb-test_$LATEST_ff45cc3835165307ef414c23ca2c6f67]
aws_lambda_invocation.example: Modifications complete after 0s [id=jb-test_$LATEST_ff45cc3835165307ef414c23ca2c6f67]
Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
Outputs:
result_entry = {
"body" = "{\"random_number\": 770797}"
"statusCode" = 200
}
All subsequent plans show the result has changed, implying the upgrade invoked the function when it should not have.
terraform plan
data.aws_partition.current: Reading...
data.aws_partition.current: Read complete after 0s [id=aws]
data.aws_iam_policy_document.test: Reading...
data.aws_iam_policy_document.test: Read complete after 0s [id=2690255455]
aws_iam_role.test: Refreshing state... [id=jb-test-lambda-invocation]
aws_iam_role_policy_attachment.test: Refreshing state... [id=jb-test-lambda-invocation-20250115194909810400000001]
aws_lambda_function.test: Refreshing state... [id=jb-test]
aws_lambda_invocation.example: Refreshing state... [id=jb-test_$LATEST_ff45cc3835165307ef414c23ca2c6f67]
Changes to Outputs:
~ result_entry = {
~ body = jsonencode(
~ {
~ random_number = 770797 -> 15568
}
)
# (1 unchanged attribute hidden)
}
You can apply this plan to save these new output values to the Terraform state, without changing any real infrastructure.
References
Would you like to implement a fix?
Yes