diff --git a/README.md b/README.md
index bf847486..fc110287 100644
--- a/README.md
+++ b/README.md
@@ -621,7 +621,7 @@ Q2: How to force recreate deployment package?
Q3: `null_resource.archive[0] must be replaced`
-> Answer: This probably mean that zip-archive has been deployed, but is currently absent locally, and it has to be recreated locally. When you run into this issue during CI/CD process (where workspace is clean) or from multiple workspaces, you can set environment variable `TF_RECREATE_MISSING_LAMBDA_PACKAGE=false` or pass `recreate_missing_package = false` as a parameter to the module and run `terraform apply`.
+> Answer: This probably mean that zip-archive has been deployed, but is currently absent locally, and it has to be recreated locally. When you run into this issue during CI/CD process (where workspace is clean) or from multiple workspaces, you can set environment variable `TF_RECREATE_MISSING_LAMBDA_PACKAGE=false` or pass `recreate_missing_package = false` as a parameter to the module and run `terraform apply`. Alternatively, you can pass `trigger_on_package_timestamp = false` as a parameter to ignore the file timestamp when deciding to create the archive or not.
Q4: What does this error mean - `"We currently do not support adding policies for $LATEST."` ?
@@ -651,6 +651,7 @@ Q4: What does this error mean - `"We currently do not support adding policies fo
- [Event Source Mapping](https://github.com/terraform-aws-modules/terraform-aws-lambda/tree/master/examples/event-source-mapping) - Create Lambda Function with event source mapping configuration (SQS, DynamoDB, Amazon MQ, and Kinesis).
- [Triggers](https://github.com/terraform-aws-modules/terraform-aws-lambda/tree/master/examples/triggers) - Create Lambda Function with some triggers (eg, Cloudwatch Events, EventBridge).
- [Code Signing](https://github.com/terraform-aws-modules/terraform-aws-lambda/tree/master/examples/code-signing) - Create Lambda Function with code signing configuration.
+- [Simple CI/CD](https://github.com/terraform-aws-modules/terraform-aws-lambda/tree/master/examples/simple-cicd) - Create Lambda Function as if it runs on CI/CD platform where `builds` directory is often absent.
# Examples by the users of this module
@@ -852,6 +853,7 @@ No modules.
| [timeout](#input\_timeout) | The amount of time your Lambda Function has to run in seconds. | `number` | `3` | no |
| [timeouts](#input\_timeouts) | Define maximum timeout for creating, updating, and deleting Lambda Function resources | `map(string)` | `{}` | no |
| [tracing\_mode](#input\_tracing\_mode) | Tracing mode of the Lambda Function. Valid value can be either PassThrough or Active. | `string` | `null` | no |
+| [trigger\_on\_package\_timestamp](#input\_trigger\_on\_package\_timestamp) | Whether to recreate the Lambda package if the timestamp changes | `bool` | `true` | no |
| [trusted\_entities](#input\_trusted\_entities) | List of additional trusted entities for assuming Lambda Function role (trust relationship) | `any` | `[]` | no |
| [use\_existing\_cloudwatch\_log\_group](#input\_use\_existing\_cloudwatch\_log\_group) | Whether to use an existing CloudWatch log group or create new | `bool` | `false` | no |
| [vpc\_security\_group\_ids](#input\_vpc\_security\_group\_ids) | List of security group ids when Lambda Function should run in the VPC. | `list(string)` | `null` | no |
diff --git a/examples/fixtures/python3.10-app1/index.py b/examples/fixtures/python3.10-app1/index.py
new file mode 100644
index 00000000..396c5054
--- /dev/null
+++ b/examples/fixtures/python3.10-app1/index.py
@@ -0,0 +1,4 @@
+def lambda_handler(event, context):
+ print("Hello from app1!")
+
+ return event
diff --git a/examples/simple-cicd/.gitignore b/examples/simple-cicd/.gitignore
new file mode 100644
index 00000000..a57582cc
--- /dev/null
+++ b/examples/simple-cicd/.gitignore
@@ -0,0 +1 @@
+/src
diff --git a/examples/simple-cicd/README.md b/examples/simple-cicd/README.md
new file mode 100644
index 00000000..05f93a51
--- /dev/null
+++ b/examples/simple-cicd/README.md
@@ -0,0 +1,53 @@
+# Simple CI/CD example
+
+Configuration in this directory creates AWS Lambda Function as it would run in a context of CICD executions, where the Terraform working directory is empty and there is no `builds` directory, that:
+
+- `terraform plan` doesn't trigger a diff if the source code of the lambda function didn't change.
+- `terraform plan` does trigger a diff if the source code of the lambda function has changed.
+- `terraform apply` works if the code has changed.
+
+## Usage
+
+To run this example you need to execute:
+
+```bash
+./test.sh
+```
+
+Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources.
+
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 1.0 |
+| [aws](#requirement\_aws) | >= 4.63 |
+| [random](#requirement\_random) | >= 2.0 |
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [random](#provider\_random) | >= 2.0 |
+
+## Modules
+
+| Name | Source | Version |
+|------|--------|---------|
+| [lambda\_function](#module\_lambda\_function) | ../../ | n/a |
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [random_pet.this](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource |
+
+## Inputs
+
+No inputs.
+
+## Outputs
+
+No outputs.
+
diff --git a/examples/simple-cicd/main.tf b/examples/simple-cicd/main.tf
new file mode 100644
index 00000000..66afc150
--- /dev/null
+++ b/examples/simple-cicd/main.tf
@@ -0,0 +1,26 @@
+provider "aws" {
+ region = "eu-west-1"
+ # region = "us-east-1"
+
+ # Make it faster by skipping something
+ skip_metadata_api_check = true
+ skip_region_validation = true
+ skip_credentials_validation = true
+}
+
+resource "random_pet" "this" {
+ length = 2
+}
+
+module "lambda_function" {
+ source = "../../"
+
+ function_name = "${random_pet.this.id}-lambda-simple"
+ handler = "index.lambda_handler"
+ runtime = "python3.10"
+
+ source_path = [
+ "${path.module}/src/python3.10-app1",
+ ]
+ trigger_on_package_timestamp = false
+}
diff --git a/examples/simple-cicd/outputs.tf b/examples/simple-cicd/outputs.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/examples/simple-cicd/test.sh b/examples/simple-cicd/test.sh
new file mode 100755
index 00000000..90ce9804
--- /dev/null
+++ b/examples/simple-cicd/test.sh
@@ -0,0 +1,126 @@
+#!/usr/bin/env bash
+# vim:ts=4:sw=4:noet
+
+set -eo pipefail
+
+trap ctrl_c INT
+
+ctrl_c() {
+ echo "** Trapped CTRL-C"
+ exit 1
+}
+
+failed=0
+
+:echo() {
+ local color=${2:-"33;1"}
+ echo -e "\e[${color}m$1\e[0m"
+}
+
+:note() {
+ :echo "$1" "35;1"
+}
+
+:case() {
+ if [ $? -ne 0 ]
+ then failed=1
+ fi
+
+ if [ "$failed" -eq 1 ]
+ then :echo "SKIPPED: $1"; return 1
+ else echo; :echo "CASE: $1"
+ fi
+}
+
+:check_diff() {
+ expected="$1"
+
+ set +e
+ terraform plan -detailed-exitcode
+ status=$?
+ set -e
+ # ${status} possible values:
+ # 0 - Succeeded, diff is empty (no changes)
+ # 1 - Errored
+ # 2 - Succeeded, there is a diff
+ if [ "${status}" -ne "${expected}" ]; then
+ case "${expected}" in
+ 0)
+ :echo "Error: we don't expect any diff here!"
+ return 1
+ ;;
+ 2)
+ echo "Error: we DO expect some diff here!"
+ return 1
+ ;;
+ esac
+ fi
+}
+
+terraform=$(which terraform)
+terraform() {
+ $terraform "$@" < <(yes yes)
+}
+
+:note "Preparing ..."
+rm -rf src
+mkdir -p src
+cp -r "../fixtures/python3.10-app1" src
+terraform init
+:echo "Destroy / Remove ZIP files"
+terraform destroy
+rm -rf builds 2>/dev/null || true
+
+#############################################################
+# Part 1: Check that CICD environment won't detect any diff #
+#############################################################
+
+:echo
+:note "Starting Part 1: Check that CICD environment won't detect any diff"
+
+:case "Apply / No diff" && {
+ terraform apply
+ :check_diff 0
+}
+
+:case "Remove 'builds' dir / No diff" && {
+ rm -rf builds
+ :check_diff 0
+}
+
+###############################################################################
+# Part 2: Check that CICD environment will detect diff if lambda code changes #
+###############################################################################
+
+:echo
+:note "Starting Part 2: Check that CICD environment will detect diff if lambda code changes"
+
+:note "Change the source code / Remove 'builds' dir"
+echo "" >> src/python3.10-app1/index.py
+rm -rf builds
+
+:case "Plan / Expect diff" && {
+ terraform plan
+ :check_diff 2
+}
+
+:case "Apply / No diff" && {
+ terraform apply
+ :check_diff 0
+}
+
+:note "Remove 'builds' dir"
+rm -rf builds
+
+:case "Plan / No diff" && {
+ terraform plan
+ :check_diff 0
+}
+
+#:case "Destroy / Remove ZIP files" && {
+# terraform plan -destroy
+# terraform destroy -auto-approve
+# rm builds/*.zip
+#}
+
+:note "All tests have passed successfully."
diff --git a/examples/simple-cicd/variables.tf b/examples/simple-cicd/variables.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/examples/simple-cicd/versions.tf b/examples/simple-cicd/versions.tf
new file mode 100644
index 00000000..5afa48b5
--- /dev/null
+++ b/examples/simple-cicd/versions.tf
@@ -0,0 +1,14 @@
+terraform {
+ required_version = ">= 1.0"
+
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = ">= 4.63"
+ }
+ random = {
+ source = "hashicorp/random"
+ version = ">= 2.0"
+ }
+ }
+}
diff --git a/package.tf b/package.tf
index b68dc89f..34322514 100644
--- a/package.tf
+++ b/package.tf
@@ -61,7 +61,7 @@ resource "null_resource" "archive" {
triggers = {
filename = data.external.archive_prepare[0].result.filename
- timestamp = data.external.archive_prepare[0].result.timestamp
+ timestamp = var.trigger_on_package_timestamp ? data.external.archive_prepare[0].result.timestamp : null
}
provisioner "local-exec" {
diff --git a/variables.tf b/variables.tf
index 61198bea..28a2b82e 100644
--- a/variables.tf
+++ b/variables.tf
@@ -761,3 +761,9 @@ variable "recreate_missing_package" {
type = bool
default = true
}
+
+variable "trigger_on_package_timestamp" {
+ description = "Whether to recreate the Lambda package if the timestamp changes"
+ type = bool
+ default = true
+}
diff --git a/wrappers/main.tf b/wrappers/main.tf
index 1ae65252..a5f8683c 100644
--- a/wrappers/main.tf
+++ b/wrappers/main.tf
@@ -119,6 +119,7 @@ module "wrapper" {
timeout = try(each.value.timeout, var.defaults.timeout, 3)
timeouts = try(each.value.timeouts, var.defaults.timeouts, {})
tracing_mode = try(each.value.tracing_mode, var.defaults.tracing_mode, null)
+ trigger_on_package_timestamp = try(each.value.trigger_on_package_timestamp, var.defaults.trigger_on_package_timestamp, true)
trusted_entities = try(each.value.trusted_entities, var.defaults.trusted_entities, [])
use_existing_cloudwatch_log_group = try(each.value.use_existing_cloudwatch_log_group, var.defaults.use_existing_cloudwatch_log_group, false)
vpc_security_group_ids = try(each.value.vpc_security_group_ids, var.defaults.vpc_security_group_ids, null)