Terraform has been a great tool for me to maintain infrastructure as a code (IaC). In fact, 90% of our current environment infrastructure is provisioned via Terraform.
Lately, I've stumbled upon a challenging case: How to zip AWS Lambda function on the fly without using external script?
Well, apparently there's a little trick that does this job: archive_file data source:
data "archive_file" "lambda_zip" {
type = "zip"
source_dir = "source"
output_path = "lambda.zip"
}
resource "aws_lambda_function" "func" {
filename = "lambda.zip"
source_code_hash = "${data.archive_file.lambda_zip.output_base64sha256}"
function_name = "my_lambda"
role = "${aws_iam_role.lambda.arn}"
description = "Function desc"
handler = "index.handler"
runtime = "nodejs4.3"
}
The archive_file data source generates a zip archive from the contents of the source directory. Terraform then uses the output_base64sha256 attribute to detect changes in the source code -- if any file in the source directory changes, Terraform will automatically re-zip and update the Lambda function.
This approach has several advantages:
- No external scripts needed -- everything stays within Terraform's declarative configuration.
- Automatic change detection -- the
source_code_hashensures Lambda is updated whenever the source code changes. - Simple and clean -- just two resource blocks and you're done.
The archive_file data source supports multiple modes:
source_dir-- zip an entire directorysource_file-- zip a single filesource_contentandsource_content_filename-- create a zip from inline content
This is particularly useful in CI/CD pipelines where you want Terraform to handle the entire deployment lifecycle, including packaging the Lambda function code, without relying on separate build steps or shell scripts.